From bcea62090b8bd48c741d8a33c327119fb1c679db Mon Sep 17 00:00:00 2001 From: andyksaw Date: Sat, 28 Feb 2026 17:52:53 +1100 Subject: [PATCH 1/4] Update role endpoints --- .../com/projectcitybuild/pcbridge/http/pcb/models/Group.kt | 6 +++--- .../projectcitybuild/pcbridge/http/pcb/models/PlayerData.kt | 2 +- .../pcbridge/http/pcb/requests/PCBRequest.kt | 4 ++-- .../pcbridge/paper/features/groups/domain/RolesFilter.kt | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/Group.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/Group.kt index aa71e7506..48c6faeeb 100644 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/Group.kt +++ b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/Group.kt @@ -5,7 +5,7 @@ import kotlinx.serialization.Serializable @Serializable data class Group( - @SerializedName("group_id") + @SerializedName("id") val id: Int, @SerializedName("name") @@ -20,8 +20,8 @@ data class Group( @SerializedName("minecraft_display_name") val displayName: String?, - @SerializedName("group_type") - val groupType: String?, + @SerializedName("role_type") + val roleType: String?, @SerializedName("display_priority") val displayPriority: Int?, diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/PlayerData.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/PlayerData.kt index a401ac8ac..f9b09d867 100644 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/PlayerData.kt +++ b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/PlayerData.kt @@ -21,5 +21,5 @@ data class PlayerData( val elevation: HttpOpElevation? = null, ) { val isStaff: Boolean - get() = groups.firstOrNull { it.groupType?.lowercase() == "staff" } != null + get() = groups.firstOrNull { it.roleType?.lowercase() == "staff" } != null } diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/requests/PCBRequest.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/requests/PCBRequest.kt index 0f9dc3afd..4f4139667 100644 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/requests/PCBRequest.kt +++ b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/requests/PCBRequest.kt @@ -48,14 +48,14 @@ internal interface PCBRequest { @Body players: PlayersStatsRequest, ) - @POST("v3/server/op/grant") + @POST("v3/server/pim/op/grant") @FormUrlEncoded suspend fun opGrant( @Field(value = "uuid") uuid: String, @Field(value = "reason") reason: String, ): HttpOpElevation - @POST("v3/server/op/revoke") + @POST("v3/server/pim/op/revoke") @FormUrlEncoded suspend fun opRevoke( @Field(value = "uuid") uuid: String, diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/RolesFilter.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/RolesFilter.kt index b4011caef..11537add3 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/RolesFilter.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/RolesFilter.kt @@ -15,7 +15,7 @@ class RolesFilter { } val mapping = mutableMapOf() for (group in groups) { - val rawRoleType = group.groupType + val rawRoleType = group.roleType val displayPriority = group.displayPriority if (rawRoleType == null || displayPriority == null) continue From b48c8d848366fff506edf09a8872049287389e2e Mon Sep 17 00:00:00 2001 From: andyksaw Date: Sat, 28 Feb 2026 18:00:15 +1100 Subject: [PATCH 2/4] Update naming --- .../pcbridge/http/pcb/models/PlayerData.kt | 6 +++--- .../pcbridge/http/pcb/models/{Group.kt => Role.kt} | 2 +- .../paper/architecture/state/data/PlayerSession.kt | 6 +++--- .../features/groups/domain/ChatGroupFormatter.kt | 6 +++--- .../paper/features/groups/domain/RolesFilter.kt | 10 +++++----- .../domain/repositories/ChatGroupRepository.kt | 3 +-- .../hooks/listener/ChatGroupInvalidateListener.kt | 2 +- .../groups/hooks/listener/RoleStateChangeListener.kt | 12 ++++++------ .../hooks/placeholders/TabGroupListPlaceholder.kt | 5 ++--- .../hooks/placeholders/TabGroupsPlaceholder.kt | 2 +- 10 files changed, 26 insertions(+), 28 deletions(-) rename pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/{Group.kt => Role.kt} (97%) diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/PlayerData.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/PlayerData.kt index f9b09d867..bc851b5e8 100644 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/PlayerData.kt +++ b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/PlayerData.kt @@ -11,8 +11,8 @@ data class PlayerData( @SerializedName("player") val player: Player? = null, - @SerializedName("groups") - val groups: List = emptyList(), + @SerializedName("roles") + val roles: List = emptyList(), @SerializedName("badges") val badges: List = emptyList(), @@ -21,5 +21,5 @@ data class PlayerData( val elevation: HttpOpElevation? = null, ) { val isStaff: Boolean - get() = groups.firstOrNull { it.roleType?.lowercase() == "staff" } != null + get() = roles.firstOrNull { it.roleType?.lowercase() == "staff" } != null } diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/Group.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/Role.kt similarity index 97% rename from pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/Group.kt rename to pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/Role.kt index 48c6faeeb..a6dc2f9ed 100644 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/Group.kt +++ b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/pcb/models/Role.kt @@ -4,7 +4,7 @@ import com.google.gson.annotations.SerializedName import kotlinx.serialization.Serializable @Serializable -data class Group( +data class Role( @SerializedName("id") val id: Int, diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/architecture/state/data/PlayerSession.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/architecture/state/data/PlayerSession.kt index d60f52c70..3c3eb5500 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/architecture/state/data/PlayerSession.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/architecture/state/data/PlayerSession.kt @@ -2,7 +2,7 @@ package com.projectcitybuild.pcbridge.paper.architecture.state.data import com.projectcitybuild.pcbridge.http.pcb.models.Account import com.projectcitybuild.pcbridge.http.pcb.models.Badge -import com.projectcitybuild.pcbridge.http.pcb.models.Group +import com.projectcitybuild.pcbridge.http.pcb.models.Role import com.projectcitybuild.pcbridge.http.pcb.models.Player import com.projectcitybuild.pcbridge.http.pcb.models.PlayerData import com.projectcitybuild.pcbridge.paper.core.libs.datetime.services.LocalizedTime @@ -35,7 +35,7 @@ data class PlayerSession( else PlayerSyncedState.Valid( account = data.account, player = data.player, - groups = data.groups, + roles = data.roles, badges = data.badges, opElevation = data.elevation?.toDomain(), ), @@ -49,7 +49,7 @@ sealed class PlayerSyncedState { data class Valid( val account: Account? = null, val player: Player? = null, - val groups: List = emptyList(), + val roles: List = emptyList(), val badges: List = emptyList(), val opElevation: OpElevation? = null, ): PlayerSyncedState() diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/ChatGroupFormatter.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/ChatGroupFormatter.kt index 99c32d9c0..5b203cbba 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/ChatGroupFormatter.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/ChatGroupFormatter.kt @@ -1,6 +1,6 @@ package com.projectcitybuild.pcbridge.paper.features.groups.domain -import com.projectcitybuild.pcbridge.http.pcb.models.Group +import com.projectcitybuild.pcbridge.http.pcb.models.Role import com.projectcitybuild.pcbridge.paper.features.groups.domain.data.RoleType import net.kyori.adventure.text.Component import net.kyori.adventure.text.event.HoverEvent @@ -9,7 +9,7 @@ import net.kyori.adventure.text.minimessage.MiniMessage class ChatGroupFormatter( private val rolesFilter: RolesFilter, ) { - fun format(groups: Set): Component? { + fun format(groups: Set): Component? { val roles = rolesFilter.filter(groups) if (roles.isEmpty()) { return null @@ -24,7 +24,7 @@ class ChatGroupFormatter( } } -private fun Group.component() = MiniMessage.miniMessage() +private fun Role.component() = MiniMessage.miniMessage() .deserialize(displayName ?: name) .also { if (hoverText.isNullOrEmpty()) { diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/RolesFilter.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/RolesFilter.kt index 11537add3..73b352242 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/RolesFilter.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/RolesFilter.kt @@ -1,6 +1,6 @@ package com.projectcitybuild.pcbridge.paper.features.groups.domain -import com.projectcitybuild.pcbridge.http.pcb.models.Group +import com.projectcitybuild.pcbridge.http.pcb.models.Role import com.projectcitybuild.pcbridge.paper.core.libs.observability.logging.logSync import com.projectcitybuild.pcbridge.paper.features.groups.domain.data.RoleType @@ -9,12 +9,12 @@ class RolesFilter { * Sorts the given collection of roles into a Map, where only * the highest display priority of a RoleType is present */ - fun filter(groups: Set): Map { - if (groups.isEmpty()) { + fun filter(roles: Set): Map { + if (roles.isEmpty()) { return emptyMap() } - val mapping = mutableMapOf() - for (group in groups) { + val mapping = mutableMapOf() + for (group in roles) { val rawRoleType = group.roleType val displayPriority = group.displayPriority diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/repositories/ChatGroupRepository.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/repositories/ChatGroupRepository.kt index 6ad4998cf..ea23c724d 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/repositories/ChatGroupRepository.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/repositories/ChatGroupRepository.kt @@ -1,7 +1,6 @@ package com.projectcitybuild.pcbridge.paper.features.groups.domain.repositories import com.projectcitybuild.pcbridge.paper.core.libs.store.SessionStore -import com.projectcitybuild.pcbridge.paper.core.libs.store.Store import com.projectcitybuild.pcbridge.paper.features.groups.domain.ChatGroupFormatter import io.github.reactivecircus.cache4k.Cache import kotlinx.coroutines.Dispatchers @@ -19,7 +18,7 @@ class ChatGroupRepository( suspend fun getGroupsComponent(playerUUID: UUID): CachedComponent { return groupCache.get(playerUUID) { val playerSession = session.state.players[playerUUID] - val groups = playerSession?.syncedValue?.groups + val groups = playerSession?.syncedValue?.roles ?: emptyList() withContext(Dispatchers.IO) { diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/listener/ChatGroupInvalidateListener.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/listener/ChatGroupInvalidateListener.kt index a87ad5f69..f640c4b1e 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/listener/ChatGroupInvalidateListener.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/listener/ChatGroupInvalidateListener.kt @@ -23,7 +23,7 @@ class ChatGroupInvalidateListener( fun onPlayerStateUpdated( event: PlayerStateUpdatedEvent, ) = event.scopedSync(groupsTracer, this::class.java) { - if (event.prevState?.syncedValue?.groups == event.state.syncedValue?.groups) { + if (event.prevState?.syncedValue?.roles == event.state.syncedValue?.roles) { return@scopedSync } logSync.info { "Invalidating chat group cache for ${event.playerUUID}" } diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/listener/RoleStateChangeListener.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/listener/RoleStateChangeListener.kt index 9f41fbfd1..2db93afa1 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/listener/RoleStateChangeListener.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/listener/RoleStateChangeListener.kt @@ -1,6 +1,6 @@ package com.projectcitybuild.pcbridge.paper.features.groups.hooks.listener -import com.projectcitybuild.pcbridge.http.pcb.models.Group +import com.projectcitybuild.pcbridge.http.pcb.models.Role import com.projectcitybuild.pcbridge.paper.architecture.listeners.scopedSync import com.projectcitybuild.pcbridge.paper.architecture.permissions.Permissions import com.projectcitybuild.pcbridge.paper.architecture.state.events.PlayerStateCreatedEvent @@ -19,7 +19,7 @@ class RoleStateChangeListener( ) = event.scopedSync(groupsTracer, this::class.java) { val synced = event.state.syncedValue if (synced != null) { - update(event.playerUUID, groups = synced.groups) + update(event.playerUUID, roles = synced.roles) } } @@ -27,14 +27,14 @@ class RoleStateChangeListener( fun onPlayerStateUpdated( event: PlayerStateUpdatedEvent, ) = event.scopedSync(groupsTracer, this::class.java) { - if (event.prevState?.syncedValue?.groups == event.state.syncedValue?.groups) { + if (event.prevState?.syncedValue?.roles == event.state.syncedValue?.roles) { return@scopedSync } - update(event.playerUUID, groups = event.state.syncedValue!!.groups) + update(event.playerUUID, roles = event.state.syncedValue!!.roles) } - private fun update(playerUUID: UUID, groups: List) { - val groupSet = groups.mapNotNull { it.minecraftName }.toSet() + private fun update(playerUUID: UUID, roles: List) { + val groupSet = roles.mapNotNull { it.minecraftName }.toSet() permissions.provider.setUserRoles(playerUUID, groupSet) } } diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/placeholders/TabGroupListPlaceholder.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/placeholders/TabGroupListPlaceholder.kt index a37d210da..e3f3eb5f4 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/placeholders/TabGroupListPlaceholder.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/placeholders/TabGroupListPlaceholder.kt @@ -1,7 +1,6 @@ package com.projectcitybuild.pcbridge.paper.features.groups.hooks.placeholders import com.projectcitybuild.pcbridge.paper.architecture.state.events.PlayerStateCreatedEvent -import com.projectcitybuild.pcbridge.paper.core.libs.store.Store import com.projectcitybuild.pcbridge.paper.architecture.state.events.PlayerStateUpdatedEvent import com.projectcitybuild.pcbridge.paper.architecture.tablist.TabRenderer import com.projectcitybuild.pcbridge.paper.architecture.tablist.UpdatableTabPlaceholder @@ -25,7 +24,7 @@ class TabGroupListPlaceholder( override suspend fun value(player: Player): Component { val playerState = session.state.players[player.uniqueId] val roles = rolesFilter.filter( - playerState?.syncedValue?.groups?.toSet() ?: emptySet() + playerState?.syncedValue?.roles?.toSet() ?: emptySet() ) val roleNames = roles.values.mapNotNull { it.minecraftName } @@ -44,7 +43,7 @@ class TabGroupListPlaceholder( @EventHandler suspend fun onPlayerStateUpdated(event: PlayerStateUpdatedEvent) { - if (event.prevState?.syncedValue?.groups == event.state.syncedValue?.groups) { + if (event.prevState?.syncedValue?.roles == event.state.syncedValue?.roles) { return } log.debug { "PlayerStateUpdatedEvent: updating tab group list for player" } diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/placeholders/TabGroupsPlaceholder.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/placeholders/TabGroupsPlaceholder.kt index 31250fffa..c56479c32 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/placeholders/TabGroupsPlaceholder.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/placeholders/TabGroupsPlaceholder.kt @@ -32,7 +32,7 @@ class TabGroupsPlaceholder( @EventHandler suspend fun onPlayerStateUpdated(event: PlayerStateUpdatedEvent) { - if (event.prevState?.syncedValue?.groups == event.state.syncedValue?.groups) { + if (event.prevState?.syncedValue?.roles == event.state.syncedValue?.roles) { return } log.debug { "PlayerStateUpdatedEvent: updating tab groups for player" } From a02f4487253590f26efc48cf547bb62dd909343a Mon Sep 17 00:00:00 2001 From: andyksaw Date: Sat, 28 Feb 2026 18:08:03 +1100 Subject: [PATCH 3/4] Update naming --- .../pcbridge/paper/Container.kt | 4 +- .../pcbridge/paper/PluginLifecycle.kt | 18 ++--- .../paper/features/groups/GroupsModule.kt | 73 ------------------- .../paper/features/groups/GroupsTracer.kt | 5 -- .../features/groups/domain/data/RoleType.kt | 8 -- .../repositories/ChatGroupRepository.kt | 33 --------- .../hooks/commands/homes/HomeLimitCommand.kt | 2 +- .../hooks/commands/roles/RolesDebugCommand.kt | 12 +-- .../paper/features/roles/RolesModule.kt | 73 +++++++++++++++++++ .../paper/features/roles/RolesTracer.kt | 5 ++ .../domain/ChatRoleFormatter.kt} | 10 +-- .../{groups => roles}/domain/RolesFilter.kt | 12 +-- .../features/roles/domain/data/RoleType.kt | 8 ++ .../domain/repositories/ChatRoleRepository.kt | 33 +++++++++ .../hooks/decorators/ChatRoleDecorator.kt} | 14 ++-- .../listener/ChatRoleInvalidateListener.kt} | 20 ++--- .../hooks/listener/RoleStateChangeListener.kt | 12 +-- .../placeholders/TabRoleListPlaceholder.kt} | 10 +-- .../placeholders/TabRolesPlaceholder.kt} | 14 ++-- 19 files changed, 183 insertions(+), 183 deletions(-) delete mode 100644 pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/GroupsModule.kt delete mode 100644 pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/GroupsTracer.kt delete mode 100644 pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/data/RoleType.kt delete mode 100644 pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/repositories/ChatGroupRepository.kt create mode 100644 pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/RolesModule.kt create mode 100644 pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/RolesTracer.kt rename pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/{groups/domain/ChatGroupFormatter.kt => roles/domain/ChatRoleFormatter.kt} (77%) rename pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/{groups => roles}/domain/RolesFilter.kt (75%) create mode 100644 pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/domain/data/RoleType.kt create mode 100644 pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/domain/repositories/ChatRoleRepository.kt rename pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/{groups/hooks/decorators/ChatGroupDecorator.kt => roles/hooks/decorators/ChatRoleDecorator.kt} (53%) rename pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/{groups/hooks/listener/ChatGroupInvalidateListener.kt => roles/hooks/listener/ChatRoleInvalidateListener.kt} (53%) rename pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/{groups => roles}/hooks/listener/RoleStateChangeListener.kt (74%) rename pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/{groups/hooks/placeholders/TabGroupListPlaceholder.kt => roles/hooks/placeholders/TabRoleListPlaceholder.kt} (84%) rename pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/{groups/hooks/placeholders/TabGroupsPlaceholder.kt => roles/hooks/placeholders/TabRolesPlaceholder.kt} (72%) diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/Container.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/Container.kt index f119d61d9..bd31f50e2 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/Container.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/Container.kt @@ -60,7 +60,7 @@ import com.projectcitybuild.pcbridge.paper.features.builds.buildsModule import com.projectcitybuild.pcbridge.paper.features.chatbadge.chatBadgeModule import com.projectcitybuild.pcbridge.paper.features.chatformatting.chatFormattingModule import com.projectcitybuild.pcbridge.paper.features.config.configModule -import com.projectcitybuild.pcbridge.paper.features.groups.groupsModule +import com.projectcitybuild.pcbridge.paper.features.roles.rolesModule import com.projectcitybuild.pcbridge.paper.features.homes.homesModule import com.projectcitybuild.pcbridge.paper.features.joinmessages.joinMessagesModule import com.projectcitybuild.pcbridge.paper.features.maintenance.maintenanceModule @@ -113,7 +113,7 @@ private val featureModules = listOf( chatBadgeModule, chatFormattingModule, configModule, - groupsModule, + rolesModule, homesModule, joinMessagesModule, maintenanceModule, diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/PluginLifecycle.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/PluginLifecycle.kt index f81e8eb15..4b7619f16 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/PluginLifecycle.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/PluginLifecycle.kt @@ -45,11 +45,11 @@ import com.projectcitybuild.pcbridge.paper.features.chatformatting.hooks.listene import com.projectcitybuild.pcbridge.paper.features.chatformatting.hooks.decorators.ChatUrlDecorator import com.projectcitybuild.pcbridge.paper.features.config.hooks.commands.ConfigCommand import com.projectcitybuild.pcbridge.paper.features.config.hooks.listeners.ConfigWebhookListener -import com.projectcitybuild.pcbridge.paper.features.groups.hooks.decorators.ChatGroupDecorator -import com.projectcitybuild.pcbridge.paper.features.groups.hooks.listener.ChatGroupInvalidateListener -import com.projectcitybuild.pcbridge.paper.features.groups.hooks.listener.RoleStateChangeListener -import com.projectcitybuild.pcbridge.paper.features.groups.hooks.placeholders.TabGroupListPlaceholder -import com.projectcitybuild.pcbridge.paper.features.groups.hooks.placeholders.TabGroupsPlaceholder +import com.projectcitybuild.pcbridge.paper.features.roles.hooks.decorators.ChatRoleDecorator +import com.projectcitybuild.pcbridge.paper.features.roles.hooks.listener.ChatRoleInvalidateListener +import com.projectcitybuild.pcbridge.paper.features.roles.hooks.listener.RoleStateChangeListener +import com.projectcitybuild.pcbridge.paper.features.roles.hooks.placeholders.TabRoleListPlaceholder +import com.projectcitybuild.pcbridge.paper.features.roles.hooks.placeholders.TabRolesPlaceholder import com.projectcitybuild.pcbridge.paper.features.homes.hooks.commands.HomeCommand import com.projectcitybuild.pcbridge.paper.features.homes.hooks.commands.HomesCommand import com.projectcitybuild.pcbridge.paper.features.homes.hooks.listeners.HomeRenameDialogListener @@ -203,7 +203,7 @@ class PluginLifecycle : KoinComponent { get(), get(), get(), - get(), + get(), get(), get(), get(), @@ -233,7 +233,7 @@ class PluginLifecycle : KoinComponent { private fun registerDecorators() { get().apply{ senders( - get(), + get(), get(), ) messages( @@ -252,13 +252,13 @@ class PluginLifecycle : KoinComponent { get(), get(), get(), - get(), + get(), ) players( get(), get(), get(), - get(), + get(), ) } } diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/GroupsModule.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/GroupsModule.kt deleted file mode 100644 index ee7a1150b..000000000 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/GroupsModule.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.projectcitybuild.pcbridge.paper.features.groups - -import com.projectcitybuild.pcbridge.paper.features.groups.hooks.decorators.ChatGroupDecorator -import com.projectcitybuild.pcbridge.paper.features.groups.domain.ChatGroupFormatter -import com.projectcitybuild.pcbridge.paper.features.groups.domain.RolesFilter -import com.projectcitybuild.pcbridge.paper.features.groups.hooks.listener.ChatGroupInvalidateListener -import com.projectcitybuild.pcbridge.paper.features.groups.hooks.listener.RoleStateChangeListener -import com.projectcitybuild.pcbridge.paper.features.groups.hooks.placeholders.TabGroupListPlaceholder -import com.projectcitybuild.pcbridge.paper.features.groups.hooks.placeholders.TabGroupsPlaceholder -import com.projectcitybuild.pcbridge.paper.features.groups.domain.repositories.ChatGroupRepository -import io.github.reactivecircus.cache4k.Cache -import org.koin.core.qualifier.named -import org.koin.dsl.module -import java.util.UUID - -val groupsModule = module { - factory { - ChatGroupInvalidateListener( - chatGroupRepository = get(), - ) - } - - factory { - RoleStateChangeListener( - permissions = get(), - ) - } - - factory { - ChatGroupDecorator( - chatGroupRepository = get(), - ) - } - - factory { - TabGroupListPlaceholder( - rolesFilter = get(), - session = get(), - server = get(), - tabRenderer = get(), - ) - } - - factory { - TabGroupsPlaceholder( - chatGroupRepository = get(), - server = get(), - tabRenderer = get(), - ) - } - - factory { - ChatGroupRepository( - chatGroupFormatter = get(), - session = get(), - groupCache = get(named("group_cache")), - ) - } - - single(named("group_cache")) { - Cache.Builder().build() - } - - factory { - ChatGroupFormatter( - rolesFilter = get(), - ) - } - - factory { - RolesFilter() - } -} \ No newline at end of file diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/GroupsTracer.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/GroupsTracer.kt deleted file mode 100644 index e97bdce6f..000000000 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/GroupsTracer.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.projectcitybuild.pcbridge.paper.features.groups - -import com.projectcitybuild.pcbridge.paper.core.libs.observability.tracing.TracerFactory - -val groupsTracer = TracerFactory.make("features.groups") \ No newline at end of file diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/data/RoleType.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/data/RoleType.kt deleted file mode 100644 index cc6051087..000000000 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/data/RoleType.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.projectcitybuild.pcbridge.paper.features.groups.domain.data - -enum class RoleType { - TRUST, - BUILD, - STAFF, - DONOR, -} \ No newline at end of file diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/repositories/ChatGroupRepository.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/repositories/ChatGroupRepository.kt deleted file mode 100644 index ea23c724d..000000000 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/repositories/ChatGroupRepository.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.projectcitybuild.pcbridge.paper.features.groups.domain.repositories - -import com.projectcitybuild.pcbridge.paper.core.libs.store.SessionStore -import com.projectcitybuild.pcbridge.paper.features.groups.domain.ChatGroupFormatter -import io.github.reactivecircus.cache4k.Cache -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import net.kyori.adventure.text.Component -import java.util.UUID - -class ChatGroupRepository( - private val session: SessionStore, - private val chatGroupFormatter: ChatGroupFormatter, - private val groupCache: Cache, -) { - data class CachedComponent(val value: Component?) - - suspend fun getGroupsComponent(playerUUID: UUID): CachedComponent { - return groupCache.get(playerUUID) { - val playerSession = session.state.players[playerUUID] - val groups = playerSession?.syncedValue?.roles - ?: emptyList() - - withContext(Dispatchers.IO) { - CachedComponent(chatGroupFormatter.format(groups.toSet())) - } - } - } - - fun invalidate(playerUUID: UUID) { - groupCache.invalidate(playerUUID) - } -} diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/homes/hooks/commands/homes/HomeLimitCommand.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/homes/hooks/commands/homes/HomeLimitCommand.kt index 27668fecf..d95e27636 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/homes/hooks/commands/homes/HomeLimitCommand.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/homes/hooks/commands/homes/HomeLimitCommand.kt @@ -41,7 +41,7 @@ class HomeLimitCommand( .joinToString() context.source.sender.sendRichMessage("---") - context.source.sender.sendRichMessage("The following groups grant you homes: $sources") + context.source.sender.sendRichMessage("The following roles grant you homes: $sources") } } } \ No newline at end of file diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/pim/hooks/commands/roles/RolesDebugCommand.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/pim/hooks/commands/roles/RolesDebugCommand.kt index 25db6955c..b50fdb663 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/pim/hooks/commands/roles/RolesDebugCommand.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/pim/hooks/commands/roles/RolesDebugCommand.kt @@ -22,7 +22,7 @@ class RolesDebugCommand( return Commands.literal("debug") .requiresPermission(PermissionNode.PIM_ROLES) .then( - Commands.argument("groups", StringArgumentType.greedyString()) + Commands.argument("roles", StringArgumentType.greedyString()) .executesSuspending(plugin, ::execute) ) .build() @@ -31,14 +31,14 @@ class RolesDebugCommand( private suspend fun execute(context: PaperCommandContext) = context.scoped(syncTracer) { val player = context.source.requirePlayer() - val groupsArg = context.getArgument("groups", String::class.java) - val groups = groupsArg.split(" ").toSet() - check(groups.isNotEmpty()) { "No groups specified" } + val rolesArg = context.getArgument("roles", String::class.java) + val roles = rolesArg.split(" ").toSet() + check(roles.isNotEmpty()) { "No roles specified" } - permissions.provider.setUserRoles(player.uniqueId, groups) + permissions.provider.setUserRoles(player.uniqueId, roles) player.sendRichMessage( - "Your groups have been set to ${groups.joinToString(",")}\n" + + "Your roles have been set to ${roles.joinToString(",")}\n" + "Use /sync or reconnect to revert this" ) } diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/RolesModule.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/RolesModule.kt new file mode 100644 index 000000000..d9623f673 --- /dev/null +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/RolesModule.kt @@ -0,0 +1,73 @@ +package com.projectcitybuild.pcbridge.paper.features.roles + +import com.projectcitybuild.pcbridge.paper.features.roles.hooks.decorators.ChatRoleDecorator +import com.projectcitybuild.pcbridge.paper.features.roles.domain.ChatRoleFormatter +import com.projectcitybuild.pcbridge.paper.features.roles.domain.RolesFilter +import com.projectcitybuild.pcbridge.paper.features.roles.hooks.listener.ChatRoleInvalidateListener +import com.projectcitybuild.pcbridge.paper.features.roles.hooks.listener.RoleStateChangeListener +import com.projectcitybuild.pcbridge.paper.features.roles.hooks.placeholders.TabRoleListPlaceholder +import com.projectcitybuild.pcbridge.paper.features.roles.hooks.placeholders.TabRolesPlaceholder +import com.projectcitybuild.pcbridge.paper.features.roles.domain.repositories.ChatRoleRepository +import io.github.reactivecircus.cache4k.Cache +import org.koin.core.qualifier.named +import org.koin.dsl.module +import java.util.UUID + +val rolesModule = module { + factory { + ChatRoleInvalidateListener( + chatRoleRepository = get(), + ) + } + + factory { + RoleStateChangeListener( + permissions = get(), + ) + } + + factory { + ChatRoleDecorator( + chatRoleRepository = get(), + ) + } + + factory { + TabRoleListPlaceholder( + rolesFilter = get(), + session = get(), + server = get(), + tabRenderer = get(), + ) + } + + factory { + TabRolesPlaceholder( + chatRoleRepository = get(), + server = get(), + tabRenderer = get(), + ) + } + + factory { + ChatRoleRepository( + chatRoleFormatter = get(), + session = get(), + roleCache = get(named("role_cache")), + ) + } + + single(named("role_cache")) { + Cache.Builder().build() + } + + factory { + ChatRoleFormatter( + rolesFilter = get(), + ) + } + + factory { + RolesFilter() + } +} \ No newline at end of file diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/RolesTracer.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/RolesTracer.kt new file mode 100644 index 000000000..9c2513e17 --- /dev/null +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/RolesTracer.kt @@ -0,0 +1,5 @@ +package com.projectcitybuild.pcbridge.paper.features.roles + +import com.projectcitybuild.pcbridge.paper.core.libs.observability.tracing.TracerFactory + +val rolesTracer = TracerFactory.make("features.roles") \ No newline at end of file diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/ChatGroupFormatter.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/domain/ChatRoleFormatter.kt similarity index 77% rename from pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/ChatGroupFormatter.kt rename to pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/domain/ChatRoleFormatter.kt index 5b203cbba..db885d3ff 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/ChatGroupFormatter.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/domain/ChatRoleFormatter.kt @@ -1,16 +1,16 @@ -package com.projectcitybuild.pcbridge.paper.features.groups.domain +package com.projectcitybuild.pcbridge.paper.features.roles.domain import com.projectcitybuild.pcbridge.http.pcb.models.Role -import com.projectcitybuild.pcbridge.paper.features.groups.domain.data.RoleType +import com.projectcitybuild.pcbridge.paper.features.roles.domain.data.RoleType import net.kyori.adventure.text.Component import net.kyori.adventure.text.event.HoverEvent import net.kyori.adventure.text.minimessage.MiniMessage -class ChatGroupFormatter( +class ChatRoleFormatter( private val rolesFilter: RolesFilter, ) { - fun format(groups: Set): Component? { - val roles = rolesFilter.filter(groups) + fun format(roleSet: Set): Component? { + val roles = rolesFilter.filter(roleSet) if (roles.isEmpty()) { return null } diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/RolesFilter.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/domain/RolesFilter.kt similarity index 75% rename from pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/RolesFilter.kt rename to pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/domain/RolesFilter.kt index 73b352242..f38b42e59 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/domain/RolesFilter.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/domain/RolesFilter.kt @@ -1,8 +1,8 @@ -package com.projectcitybuild.pcbridge.paper.features.groups.domain +package com.projectcitybuild.pcbridge.paper.features.roles.domain import com.projectcitybuild.pcbridge.http.pcb.models.Role import com.projectcitybuild.pcbridge.paper.core.libs.observability.logging.logSync -import com.projectcitybuild.pcbridge.paper.features.groups.domain.data.RoleType +import com.projectcitybuild.pcbridge.paper.features.roles.domain.data.RoleType class RolesFilter { /** @@ -14,9 +14,9 @@ class RolesFilter { return emptyMap() } val mapping = mutableMapOf() - for (group in roles) { - val rawRoleType = group.roleType - val displayPriority = group.displayPriority + for (role in roles) { + val rawRoleType = role.roleType + val displayPriority = role.displayPriority if (rawRoleType == null || displayPriority == null) continue @@ -27,7 +27,7 @@ class RolesFilter { } val existing = mapping[roleType] if (existing == null || existing.displayPriority!! < displayPriority) { - mapping[roleType] = group + mapping[roleType] = role } } return mapping diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/domain/data/RoleType.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/domain/data/RoleType.kt new file mode 100644 index 000000000..efa5dde0f --- /dev/null +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/domain/data/RoleType.kt @@ -0,0 +1,8 @@ +package com.projectcitybuild.pcbridge.paper.features.roles.domain.data + +enum class RoleType { + TRUST, + BUILD, + STAFF, + DONOR, +} \ No newline at end of file diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/domain/repositories/ChatRoleRepository.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/domain/repositories/ChatRoleRepository.kt new file mode 100644 index 000000000..aa35e8e05 --- /dev/null +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/domain/repositories/ChatRoleRepository.kt @@ -0,0 +1,33 @@ +package com.projectcitybuild.pcbridge.paper.features.roles.domain.repositories + +import com.projectcitybuild.pcbridge.paper.core.libs.store.SessionStore +import com.projectcitybuild.pcbridge.paper.features.roles.domain.ChatRoleFormatter +import io.github.reactivecircus.cache4k.Cache +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import net.kyori.adventure.text.Component +import java.util.UUID + +class ChatRoleRepository( + private val session: SessionStore, + private val chatRoleFormatter: ChatRoleFormatter, + private val roleCache: Cache, +) { + data class CachedComponent(val value: Component?) + + suspend fun getRolesComponent(playerUUID: UUID): CachedComponent { + return roleCache.get(playerUUID) { + val playerSession = session.state.players[playerUUID] + val roles = playerSession?.syncedValue?.roles + ?: emptyList() + + withContext(Dispatchers.IO) { + CachedComponent(chatRoleFormatter.format(roles.toSet())) + } + } + } + + fun invalidate(playerUUID: UUID) { + roleCache.invalidate(playerUUID) + } +} diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/decorators/ChatGroupDecorator.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/hooks/decorators/ChatRoleDecorator.kt similarity index 53% rename from pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/decorators/ChatGroupDecorator.kt rename to pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/hooks/decorators/ChatRoleDecorator.kt index 54546e129..d3fca7e07 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/decorators/ChatGroupDecorator.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/hooks/decorators/ChatRoleDecorator.kt @@ -1,23 +1,23 @@ -package com.projectcitybuild.pcbridge.paper.features.groups.hooks.decorators +package com.projectcitybuild.pcbridge.paper.features.roles.hooks.decorators import com.projectcitybuild.pcbridge.paper.architecture.chat.decorators.ChatSender import com.projectcitybuild.pcbridge.paper.architecture.chat.decorators.ChatSenderDecorator -import com.projectcitybuild.pcbridge.paper.features.groups.domain.repositories.ChatGroupRepository +import com.projectcitybuild.pcbridge.paper.features.roles.domain.repositories.ChatRoleRepository import net.kyori.adventure.text.Component -class ChatGroupDecorator( - private val chatGroupRepository: ChatGroupRepository, +class ChatRoleDecorator( + private val chatRoleRepository: ChatRoleRepository, ): ChatSenderDecorator { override suspend fun decorate(prev: ChatSender): ChatSender { val uuid = prev.sender.uniqueId - val cached = chatGroupRepository.getGroupsComponent(uuid) + val cached = chatRoleRepository.getRolesComponent(uuid) - val groups = cached.value + val roles = cached.value ?: return prev return prev.copy( sourceDisplayName = Component.text() - .append(groups, Component.space(), prev.sourceDisplayName) + .append(roles, Component.space(), prev.sourceDisplayName) .build(), ) } diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/listener/ChatGroupInvalidateListener.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/hooks/listener/ChatRoleInvalidateListener.kt similarity index 53% rename from pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/listener/ChatGroupInvalidateListener.kt rename to pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/hooks/listener/ChatRoleInvalidateListener.kt index f640c4b1e..9acb44b97 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/listener/ChatGroupInvalidateListener.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/hooks/listener/ChatRoleInvalidateListener.kt @@ -1,32 +1,32 @@ -package com.projectcitybuild.pcbridge.paper.features.groups.hooks.listener +package com.projectcitybuild.pcbridge.paper.features.roles.hooks.listener import com.projectcitybuild.pcbridge.paper.architecture.listeners.scopedSync import com.projectcitybuild.pcbridge.paper.architecture.state.events.PlayerStateCreatedEvent import com.projectcitybuild.pcbridge.paper.architecture.state.events.PlayerStateUpdatedEvent import com.projectcitybuild.pcbridge.paper.core.libs.observability.logging.logSync -import com.projectcitybuild.pcbridge.paper.features.groups.domain.repositories.ChatGroupRepository -import com.projectcitybuild.pcbridge.paper.features.groups.groupsTracer +import com.projectcitybuild.pcbridge.paper.features.roles.domain.repositories.ChatRoleRepository +import com.projectcitybuild.pcbridge.paper.features.roles.rolesTracer import org.bukkit.event.EventHandler import org.bukkit.event.Listener -class ChatGroupInvalidateListener( - private val chatGroupRepository: ChatGroupRepository, +class ChatRoleInvalidateListener( + private val chatRoleRepository: ChatRoleRepository, ) : Listener { @EventHandler fun onPlayerStateCreated( event: PlayerStateCreatedEvent, - ) = event.scopedSync(groupsTracer, this::class.java) { - chatGroupRepository.invalidate(event.playerUUID) + ) = event.scopedSync(rolesTracer, this::class.java) { + chatRoleRepository.invalidate(event.playerUUID) } @EventHandler fun onPlayerStateUpdated( event: PlayerStateUpdatedEvent, - ) = event.scopedSync(groupsTracer, this::class.java) { + ) = event.scopedSync(rolesTracer, this::class.java) { if (event.prevState?.syncedValue?.roles == event.state.syncedValue?.roles) { return@scopedSync } - logSync.info { "Invalidating chat group cache for ${event.playerUUID}" } - chatGroupRepository.invalidate(event.playerUUID) + logSync.info { "Invalidating chat role cache for ${event.playerUUID}" } + chatRoleRepository.invalidate(event.playerUUID) } } diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/listener/RoleStateChangeListener.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/hooks/listener/RoleStateChangeListener.kt similarity index 74% rename from pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/listener/RoleStateChangeListener.kt rename to pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/hooks/listener/RoleStateChangeListener.kt index 2db93afa1..edfb1e92e 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/listener/RoleStateChangeListener.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/hooks/listener/RoleStateChangeListener.kt @@ -1,11 +1,11 @@ -package com.projectcitybuild.pcbridge.paper.features.groups.hooks.listener +package com.projectcitybuild.pcbridge.paper.features.roles.hooks.listener import com.projectcitybuild.pcbridge.http.pcb.models.Role import com.projectcitybuild.pcbridge.paper.architecture.listeners.scopedSync import com.projectcitybuild.pcbridge.paper.architecture.permissions.Permissions import com.projectcitybuild.pcbridge.paper.architecture.state.events.PlayerStateCreatedEvent import com.projectcitybuild.pcbridge.paper.architecture.state.events.PlayerStateUpdatedEvent -import com.projectcitybuild.pcbridge.paper.features.groups.groupsTracer +import com.projectcitybuild.pcbridge.paper.features.roles.rolesTracer import org.bukkit.event.EventHandler import org.bukkit.event.Listener import java.util.UUID @@ -16,7 +16,7 @@ class RoleStateChangeListener( @EventHandler fun onPlayerStateCreated( event: PlayerStateCreatedEvent, - ) = event.scopedSync(groupsTracer, this::class.java) { + ) = event.scopedSync(rolesTracer, this::class.java) { val synced = event.state.syncedValue if (synced != null) { update(event.playerUUID, roles = synced.roles) @@ -26,7 +26,7 @@ class RoleStateChangeListener( @EventHandler fun onPlayerStateUpdated( event: PlayerStateUpdatedEvent, - ) = event.scopedSync(groupsTracer, this::class.java) { + ) = event.scopedSync(rolesTracer, this::class.java) { if (event.prevState?.syncedValue?.roles == event.state.syncedValue?.roles) { return@scopedSync } @@ -34,7 +34,7 @@ class RoleStateChangeListener( } private fun update(playerUUID: UUID, roles: List) { - val groupSet = roles.mapNotNull { it.minecraftName }.toSet() - permissions.provider.setUserRoles(playerUUID, groupSet) + val roleSet = roles.mapNotNull { it.minecraftName }.toSet() + permissions.provider.setUserRoles(playerUUID, roleSet) } } diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/placeholders/TabGroupListPlaceholder.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/hooks/placeholders/TabRoleListPlaceholder.kt similarity index 84% rename from pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/placeholders/TabGroupListPlaceholder.kt rename to pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/hooks/placeholders/TabRoleListPlaceholder.kt index e3f3eb5f4..40151897a 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/placeholders/TabGroupListPlaceholder.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/hooks/placeholders/TabRoleListPlaceholder.kt @@ -1,4 +1,4 @@ -package com.projectcitybuild.pcbridge.paper.features.groups.hooks.placeholders +package com.projectcitybuild.pcbridge.paper.features.roles.hooks.placeholders import com.projectcitybuild.pcbridge.paper.architecture.state.events.PlayerStateCreatedEvent import com.projectcitybuild.pcbridge.paper.architecture.state.events.PlayerStateUpdatedEvent @@ -6,14 +6,14 @@ import com.projectcitybuild.pcbridge.paper.architecture.tablist.TabRenderer import com.projectcitybuild.pcbridge.paper.architecture.tablist.UpdatableTabPlaceholder import com.projectcitybuild.pcbridge.paper.core.libs.observability.logging.log import com.projectcitybuild.pcbridge.paper.core.libs.store.SessionStore -import com.projectcitybuild.pcbridge.paper.features.groups.domain.RolesFilter +import com.projectcitybuild.pcbridge.paper.features.roles.domain.RolesFilter import net.kyori.adventure.text.Component import org.bukkit.Server import org.bukkit.entity.Player import org.bukkit.event.EventHandler import java.util.UUID -class TabGroupListPlaceholder( +class TabRoleListPlaceholder( private val rolesFilter: RolesFilter, private val session: SessionStore, private val server: Server, @@ -37,7 +37,7 @@ class TabGroupListPlaceholder( @EventHandler suspend fun onPlayerStateCreated(event: PlayerStateCreatedEvent) { - log.debug { "PlayerStateCreatedEvent: updating tab group list for player" } + log.debug { "PlayerStateCreatedEvent: updating tab role list for player" } update(event.playerUUID) } @@ -46,7 +46,7 @@ class TabGroupListPlaceholder( if (event.prevState?.syncedValue?.roles == event.state.syncedValue?.roles) { return } - log.debug { "PlayerStateUpdatedEvent: updating tab group list for player" } + log.debug { "PlayerStateUpdatedEvent: updating tab role list for player" } update(event.playerUUID) } diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/placeholders/TabGroupsPlaceholder.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/hooks/placeholders/TabRolesPlaceholder.kt similarity index 72% rename from pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/placeholders/TabGroupsPlaceholder.kt rename to pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/hooks/placeholders/TabRolesPlaceholder.kt index c56479c32..c8673c62e 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/groups/hooks/placeholders/TabGroupsPlaceholder.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/roles/hooks/placeholders/TabRolesPlaceholder.kt @@ -1,32 +1,32 @@ -package com.projectcitybuild.pcbridge.paper.features.groups.hooks.placeholders +package com.projectcitybuild.pcbridge.paper.features.roles.hooks.placeholders import com.projectcitybuild.pcbridge.paper.architecture.state.events.PlayerStateCreatedEvent import com.projectcitybuild.pcbridge.paper.architecture.state.events.PlayerStateUpdatedEvent import com.projectcitybuild.pcbridge.paper.architecture.tablist.TabRenderer import com.projectcitybuild.pcbridge.paper.architecture.tablist.UpdatableTabPlaceholder import com.projectcitybuild.pcbridge.paper.core.libs.observability.logging.log -import com.projectcitybuild.pcbridge.paper.features.groups.domain.repositories.ChatGroupRepository +import com.projectcitybuild.pcbridge.paper.features.roles.domain.repositories.ChatRoleRepository import net.kyori.adventure.text.Component import org.bukkit.Server import org.bukkit.entity.Player import org.bukkit.event.EventHandler import java.util.UUID -class TabGroupsPlaceholder( - private val chatGroupRepository: ChatGroupRepository, +class TabRolesPlaceholder( + private val chatRoleRepository: ChatRoleRepository, private val server: Server, private val tabRenderer: TabRenderer, ): UpdatableTabPlaceholder { override val placeholder: String = "groups" override suspend fun value(player: Player): Component { - return chatGroupRepository.getGroupsComponent(player.uniqueId).value?.appendSpace() + return chatRoleRepository.getRolesComponent(player.uniqueId).value?.appendSpace() ?: Component.empty() } @EventHandler suspend fun onPlayerStateCreated(event: PlayerStateCreatedEvent) { - log.debug { "PlayerStateCreatedEvent: updating tab groups for player" } + log.debug { "PlayerStateCreatedEvent: updating tab roles for player" } update(event.playerUUID) } @@ -35,7 +35,7 @@ class TabGroupsPlaceholder( if (event.prevState?.syncedValue?.roles == event.state.syncedValue?.roles) { return } - log.debug { "PlayerStateUpdatedEvent: updating tab groups for player" } + log.debug { "PlayerStateUpdatedEvent: updating tab roles for player" } update(event.playerUUID) } From 109f5e370b966193696d300c2d3e3cc9259c708b Mon Sep 17 00:00:00 2001 From: andyksaw Date: Sat, 28 Feb 2026 18:25:12 +1100 Subject: [PATCH 4/4] Add missing sync after verification --- .../pcbridge/paper/features/register/RegisterModule.kt | 1 + .../features/register/listeners/VerifyCodeDialogListener.kt | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/register/RegisterModule.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/register/RegisterModule.kt index eca9fb49a..ee0f0ae51 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/register/RegisterModule.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/register/RegisterModule.kt @@ -22,6 +22,7 @@ val registerModule = module { factory { VerifyCodeDialogListener( registerHttpService = get().register, + syncPlayer = get(), ) } } \ No newline at end of file diff --git a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/register/listeners/VerifyCodeDialogListener.kt b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/register/listeners/VerifyCodeDialogListener.kt index 876889bf4..c22bab8d8 100644 --- a/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/register/listeners/VerifyCodeDialogListener.kt +++ b/pcbridge-paper/src/main/kotlin/com/projectcitybuild/pcbridge/paper/features/register/listeners/VerifyCodeDialogListener.kt @@ -7,6 +7,7 @@ import com.projectcitybuild.pcbridge.paper.core.libs.observability.logging.log import com.projectcitybuild.pcbridge.paper.core.libs.observability.logging.logSync import com.projectcitybuild.pcbridge.paper.features.register.dialogs.VerifyRegistrationCodeDialog import com.projectcitybuild.pcbridge.paper.features.register.registerTracer +import com.projectcitybuild.pcbridge.paper.features.sync.domain.actions.SyncPlayer import com.projectcitybuild.pcbridge.paper.l10n.l10n import io.papermc.paper.connection.PlayerGameConnection import io.papermc.paper.event.player.PlayerCustomClickEvent @@ -15,6 +16,7 @@ import org.bukkit.event.Listener class VerifyCodeDialogListener( private val registerHttpService: RegisterHttpService, + private val syncPlayer: SyncPlayer, ) : Listener { @EventHandler suspend fun onPlayerCustomClickEvent( @@ -50,6 +52,8 @@ class VerifyCodeDialogListener( playerUUID = player.uniqueId, ) player.sendRichMessage(l10n.registrationComplete) + syncPlayer.execute(playerUUID = player.uniqueId) + } catch (_: ResponseParserError.NotFound) { val dialog = VerifyRegistrationCodeDialog.build( email = null,