From 6c2f590bd06d4229e5c55e7b63604b6f84a75ffb Mon Sep 17 00:00:00 2001 From: andyksaw Date: Wed, 16 Oct 2024 19:27:46 +0900 Subject: [PATCH] Remove obsolete functionality and revamp syncing --- build.gradle.kts | 2 +- .../pcbridge/http/HttpService.kt | 28 +-- .../pcbridge/http/clients/PCBClientFactory.kt | 21 +- .../pcbridge/http/requests/PCBRequest.kt | 154 +++---------- .../pcbridge/http/responses/Account.kt | 2 + .../pcbridge/http/responses/AuthURL.kt | 8 - .../pcbridge/http/responses/DonationPerk.kt | 2 + .../pcbridge/http/responses/DonationTier.kt | 2 + .../pcbridge/http/responses/Group.kt | 8 +- .../responses/{Aggregate.kt => PlayerData.kt} | 2 +- .../pcbridge/http/responses/PlayerWarning.kt | 26 --- .../http/services/pcb/IPBanHttpService.kt | 72 ------- .../services/pcb/PlayerGroupHttpService.kt | 55 ----- ...ateHttpService.kt => PlayerHttpService.kt} | 8 +- .../services/pcb/PlayerWarningHttpService.kt | 61 ------ ...kHTTPService.kt => RegisterHttpService.kt} | 20 +- .../http/services/pcb/UUIDBanHttpService.kt | 81 ------- .../projectcitybuild/pcbridge/Container.kt | 203 +++--------------- .../com/projectcitybuild/pcbridge/Plugin.kt | 65 +----- .../pcbridge/core/state/ServerState.kt | 26 +-- .../pcbridge/core/state/Store.kt | 1 + ...seConnection.kt => AuthorizeConnection.kt} | 14 +- .../pcbridge/features/bans/actions/BanIP.kt | 54 ----- .../pcbridge/features/bans/actions/BanUUID.kt | 53 ----- .../features/bans/actions/CheckUUIDBan.kt | 42 ---- .../pcbridge/features/bans/actions/UnbanIP.kt | 42 ---- .../features/bans/actions/UnbanUUID.kt | 39 ---- .../features/bans/commands/BanCommand.kt | 76 ------- .../features/bans/commands/BanIPCommand.kt | 77 ------- .../features/bans/commands/CheckBanCommand.kt | 69 ------ .../features/bans/commands/UnbanCommand.kt | 63 ------ .../features/bans/commands/UnbanIPCommand.kt | 63 ------ .../bans/events/ConnectionPermittedEvent.kt | 4 +- .../listeners/AuthorizeConnectionListener.kt | 60 +++--- .../bans/repositories/AggregateRepository.kt | 21 -- .../bans/repositories/IPBanRepository.kt | 41 ---- .../bans/repositories/PlayerBanRepository.kt | 43 ---- .../bans/repositories/PlayerRepository.kt | 23 ++ .../bans/repositories/PlayerUUIDRepository.kt | 37 ---- .../listeners/SyncBadgesOnJoinListener.kt | 25 --- .../listeners/AnnounceJoinListener.kt | 22 +- .../listeners/AnnounceQuitListener.kt | 13 +- .../repositories/PlayerConfigRepository.kt | 3 +- .../features/mute/commands/MuteCommand.kt | 61 ------ .../features/mute/commands/UnmuteCommand.kt | 61 ------ .../mute/listeners/MuteChatListener.kt | 25 --- .../events/PlayerStateCreatedEvent.kt | 22 ++ .../events/PlayerStateDestroyedEvent.kt | 22 ++ .../listeners/PlayerStateListener.kt | 77 +++++++ .../actions/GenerateAccountVerificationURL.kt | 33 --- .../sync/actions/UpdatePlayerGroups.kt | 71 +++--- .../features/sync/commands/SyncCommand.kt | 72 +------ .../sync/commands/SyncOtherCommand.kt | 140 ++++++------ .../sync/listener/SyncRankOnJoinListener.kt | 8 +- .../sync/repositories/SyncRepository.kt | 21 -- .../actions/GetUnacknowledgedWarnings.kt | 37 ---- .../commands/WarningAcknowledgeCommand.kt | 37 ---- .../listeners/NotifyWarningsOnJoinListener.kt | 62 ------ .../repositories/PlayerWarningRepository.kt | 23 -- pcbridge-spigot/src/main/resources/plugin.yml | 18 +- ...tionTest.kt => AuthorizeConnectionTest.kt} | 32 +-- 61 files changed, 423 insertions(+), 2130 deletions(-) delete mode 100644 pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/AuthURL.kt rename pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/{Aggregate.kt => PlayerData.kt} (95%) delete mode 100644 pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/PlayerWarning.kt delete mode 100644 pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/IPBanHttpService.kt delete mode 100644 pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/PlayerGroupHttpService.kt rename pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/{AggregateHttpService.kt => PlayerHttpService.kt} (81%) delete mode 100644 pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/PlayerWarningHttpService.kt rename pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/{AccountLinkHTTPService.kt => RegisterHttpService.kt} (63%) delete mode 100644 pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/UUIDBanHttpService.kt rename pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/{AuthoriseConnection.kt => AuthorizeConnection.kt} (71%) delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/BanIP.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/BanUUID.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/CheckUUIDBan.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/UnbanIP.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/UnbanUUID.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/BanCommand.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/BanIPCommand.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/CheckBanCommand.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/UnbanCommand.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/UnbanIPCommand.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/AggregateRepository.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/IPBanRepository.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/PlayerBanRepository.kt create mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/PlayerRepository.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/PlayerUUIDRepository.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/chat/listeners/SyncBadgesOnJoinListener.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/mute/commands/MuteCommand.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/mute/commands/UnmuteCommand.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/mute/listeners/MuteChatListener.kt create mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/playerstate/events/PlayerStateCreatedEvent.kt create mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/playerstate/events/PlayerStateDestroyedEvent.kt create mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/playerstate/listeners/PlayerStateListener.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/actions/GenerateAccountVerificationURL.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/warnings/actions/GetUnacknowledgedWarnings.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/warnings/commands/WarningAcknowledgeCommand.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/warnings/listeners/NotifyWarningsOnJoinListener.kt delete mode 100644 pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/warnings/repositories/PlayerWarningRepository.kt rename pcbridge-spigot/test/com/projectcitybuild/pcbridge/features/bans/actions/{AuthoriseConnectionTest.kt => AuthorizeConnectionTest.kt} (70%) diff --git a/build.gradle.kts b/build.gradle.kts index 0a08dd28..a6ce93ef 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile val sharedGroup = "com.projectcitybuild.pcbridge" -val sharedVersion = "6.0.0" +val sharedVersion = "6.1.0" group = sharedGroup version = sharedVersion diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/HttpService.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/HttpService.kt index a7fe1a20..743e0701 100644 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/HttpService.kt +++ b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/HttpService.kt @@ -4,13 +4,9 @@ import com.projectcitybuild.pcbridge.http.clients.MojangClient import com.projectcitybuild.pcbridge.http.clients.PCBClientFactory import com.projectcitybuild.pcbridge.http.parsing.ResponseParser import com.projectcitybuild.pcbridge.http.services.mojang.PlayerUUIDHttpService -import com.projectcitybuild.pcbridge.http.services.pcb.AccountLinkHTTPService -import com.projectcitybuild.pcbridge.http.services.pcb.AggregateHttpService -import com.projectcitybuild.pcbridge.http.services.pcb.IPBanHttpService -import com.projectcitybuild.pcbridge.http.services.pcb.PlayerGroupHttpService -import com.projectcitybuild.pcbridge.http.services.pcb.PlayerWarningHttpService +import com.projectcitybuild.pcbridge.http.services.pcb.RegisterHttpService +import com.projectcitybuild.pcbridge.http.services.pcb.PlayerHttpService import com.projectcitybuild.pcbridge.http.services.pcb.TelemetryHttpService -import com.projectcitybuild.pcbridge.http.services.pcb.UUIDBanHttpService class HttpService( private val authToken: String, @@ -37,24 +33,12 @@ class HttpService( val playerUuid get() = PlayerUUIDHttpService(mojangClient, responseParser) - val playerGroup - get() = PlayerGroupHttpService(pcbClient, responseParser) - - val playerWarning - get() = PlayerWarningHttpService(pcbClient, responseParser) - - val uuidBan - get() = UUIDBanHttpService(pcbClient, responseParser) - - val ipBan - get() = IPBanHttpService(pcbClient, responseParser) - - val aggregate - get() = AggregateHttpService(pcbClient, responseParser) + val player + get() = PlayerHttpService(pcbClient, responseParser) val telemetry get() = TelemetryHttpService(pcbClient, responseParser) - val verificationURL - get() = AccountLinkHTTPService(pcbClient, responseParser) + val register + get() = RegisterHttpService(pcbClient, responseParser) } diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/clients/PCBClientFactory.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/clients/PCBClientFactory.kt index 810e9c27..530de8cc 100644 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/clients/PCBClientFactory.kt +++ b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/clients/PCBClientFactory.kt @@ -10,25 +10,22 @@ internal class PCBClientFactory( private val baseUrl: String, private val withLogging: Boolean, ) { - fun build(): Retrofit { - val authenticatedClient = makeAuthenticatedClient() - return Retrofit.Builder() - .baseUrl(baseUrl) - .client(authenticatedClient) - .addConverterFactory(GsonConverterFactory.create()) - .build() - } + fun build(): Retrofit = Retrofit.Builder() + .baseUrl(baseUrl) + .client(makeAuthenticatedClient()) + .addConverterFactory(GsonConverterFactory.create()) + .build() private fun makeAuthenticatedClient(): OkHttpClient { var clientFactory = OkHttpClient().newBuilder() .addInterceptor { chain -> - // Add access token as header to each API request val request = chain.request() - val requestBuilder = request.newBuilder().header("Authorization", "Bearer $authToken") - val nextRequest = requestBuilder.build() + .newBuilder() + .header("Authorization", "Bearer $authToken") + .build() - chain.proceed(nextRequest) + chain.proceed(request) } if (withLogging) { diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/requests/PCBRequest.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/requests/PCBRequest.kt index 6d8cd9d8..cf13b6a0 100644 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/requests/PCBRequest.kt +++ b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/requests/PCBRequest.kt @@ -1,152 +1,52 @@ package com.projectcitybuild.pcbridge.http.requests import com.projectcitybuild.pcbridge.http.parsing.ApiResponse -import com.projectcitybuild.pcbridge.http.responses.Account -import com.projectcitybuild.pcbridge.http.responses.Aggregate -import com.projectcitybuild.pcbridge.http.responses.AuthURL -import com.projectcitybuild.pcbridge.http.responses.DonationPerk -import com.projectcitybuild.pcbridge.http.responses.IPBan -import com.projectcitybuild.pcbridge.http.responses.PlayerBan -import com.projectcitybuild.pcbridge.http.responses.PlayerWarning +import com.projectcitybuild.pcbridge.http.responses.PlayerData import retrofit2.http.Field import retrofit2.http.FormUrlEncoded import retrofit2.http.GET import retrofit2.http.POST +import retrofit2.http.PUT import retrofit2.http.Path import retrofit2.http.Query internal interface PCBRequest { /** - * Begins the authentication flow by exchanging a player's UUID - * for a URL that they can click and login with + * Fetches all data for the given UUID, such as ban status, + * user groups and badges */ - @POST("auth/minecraft") - @FormUrlEncoded - suspend fun getVerificationUrl( - @Field("minecraft_uuid") uuid: String, - ): ApiResponse + @GET("v2/minecraft/player/{uuid}") + suspend fun getPlayer( + @Path(value = "uuid") uuid: String, + @Query("ip") ip: String, + ): ApiResponse /** - * Fetches the groups that the given UUID belongs to + * Begins registration of a PCB account linked to the current + * Minecraft player */ - @GET("auth/minecraft/{uuid}") - suspend fun getUserGroups( + @POST("v2/minecraft/player/{uuid}/register") + @FormUrlEncoded + suspend fun sendRegisterCode( @Path(value = "uuid") uuid: String, - ): ApiResponse + @Field(value = "alias") playerName: String, + @Field(value = "email") email: String, + ): ApiResponse /** - * Fetches various data for the given uuid, such as ban status - * and user groups. This is to make the login more efficient by - * combining everything into one request + * Finishes registration by verifying the code sent to them + * over email */ - @GET("v2/minecraft/{uuid}/aggregate") - suspend fun getAggregate( - @Path(value = "uuid") uuid: String, - @Query("ip") ip: String, - ): ApiResponse - - @GET("v2/minecraft/{uuid}/donation-tiers") - suspend fun getDonationTier( - @Path(value = "uuid") uuid: String, - ): ApiResponse> - - @POST("v2/bans/ip/ban") - @FormUrlEncoded - suspend fun banIP( - @Field("ip_address") ip: String, - @Field("banner_player_id") bannerPlayerId: String?, - @Field("banner_player_type") bannerPlayerType: String = "minecraft_uuid", - @Field("banner_player_alias") bannerPlayerAlias: String, - @Field("reason") reason: String, - ): ApiResponse - - @POST("v2/bans/ip/unban") - @FormUrlEncoded - suspend fun unbanIP( - @Field("ip_address") ip: String, - @Field("unbanner_player_id") unbannerPlayerId: String?, - @Field("unbanner_player_type") unbannerPlayerType: String = "minecraft_uuid", - @Field("unbanner_player_alias") unbannerPlayerAlias: String, - ): ApiResponse - - @POST("v2/bans/ip/status") - @FormUrlEncoded - suspend fun getIPStatus( - @Field("ip_address") ip: String, - ): ApiResponse - - @POST("v2/bans/player/ban") + @PUT("v2/minecraft/player/{uuid}/register") @FormUrlEncoded - suspend fun banUUID( - @Field("banned_player_id") bannedPlayerId: String, - @Field("banned_player_type") bannedPlayerType: String = "minecraft_uuid", - @Field("banned_player_alias") bannedPlayerAlias: String, - @Field("banner_player_id") bannerPlayerId: String?, - @Field("banner_player_type") bannerPlayerType: String = "minecraft_uuid", - @Field("banner_player_alias") bannerPlayerAlias: String, - @Field("reason") reason: String? = null, - @Field("expires_at") expiresAt: Long?, - ): ApiResponse - - @POST("v2/bans/player/unban") - @FormUrlEncoded - suspend fun unbanUUID( - @Field("banned_player_id") bannedPlayerId: String, - @Field("banned_player_type") bannedPlayerType: String = "minecraft_uuid", - @Field("unbanner_player_id") unbannerPlayerId: String?, - @Field("unbanner_player_type") unbannerPlayerType: String = "minecraft_uuid", - ): ApiResponse - - @POST("v2/bans/player/status") - @FormUrlEncoded - suspend fun getUuidBanStatus( - @Field("player_id") playerId: String, - @Field("player_type") playerType: String = "minecraft_uuid", - ): ApiResponse - - @POST("v2/bans/player/all") - @FormUrlEncoded - suspend fun getUUIDBans( - @Field("player_id") playerId: String, - @Field("player_id_type") playerType: String = "minecraft_uuid", - ): ApiResponse> - - @POST("v2/bans/player/ban") - @FormUrlEncoded - suspend fun convertToPermanentBan( - @Field("ban_id") bannedPlayerId: String, - @Field("banner_player_id") bannerPlayerId: String, - @Field("banner_player_type") bannerPlayerType: String = "minecraft_uuid", - @Field("banner_player_alias") bannerPlayerAlias: String, - @Field("reason") reason: String? = null, - ): ApiResponse - - @GET("v2/warnings") - suspend fun getWarnings( - @Query("player_id") playerId: String, - @Query("player_type") playerType: String = "minecraft_uuid", - @Query("player_alias") playerAlias: String, - ): ApiResponse> - - @POST("v2/warnings") - @FormUrlEncoded - suspend fun createWarning( - @Field("warned_player_id") warnedPlayerId: String, - @Field("warned_player_type") warnedPlayerType: String = "minecraft_uuid", - @Field("warned_player_alias") warnedPlayerAlias: String, - @Field("warner_player_id") warnerPlayerId: String, - @Field("warner_player_type") warnerPlayerType: String = "minecraft_uuid", - @Field("warner_player_alias") warnerPlayerAlias: String, - @Field("reason") reason: String, - @Field("weight") weight: Int = 1, - ): ApiResponse - - @POST("v2/warnings/acknowledge") - @FormUrlEncoded - suspend fun acknowledgeWarning( - @Field("warning_id") warningId: Int, - ): ApiResponse + suspend fun verifyRegisterCode( + @Path(value = "uuid") uuid: String, + @Field(value = "code") code: String, + ): ApiResponse + /** + * Updates the last seen date of the player + */ @POST("v2/minecraft/telemetry/seen") @FormUrlEncoded suspend fun telemetrySeen( diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/Account.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/Account.kt index 2803f472..476cfe74 100644 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/Account.kt +++ b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/Account.kt @@ -1,8 +1,10 @@ package com.projectcitybuild.pcbridge.http.responses import com.google.gson.annotations.SerializedName +import kotlinx.serialization.Serializable import java.util.UUID +@Serializable data class Account( @SerializedName("account_id") val id: String = UUID.randomUUID().toString(), diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/AuthURL.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/AuthURL.kt deleted file mode 100644 index ee517202..00000000 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/AuthURL.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.projectcitybuild.pcbridge.http.responses - -import com.google.gson.annotations.SerializedName - -data class AuthURL( - @SerializedName("url") - val url: String, -) diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/DonationPerk.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/DonationPerk.kt index 616f8261..bee40fdf 100644 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/DonationPerk.kt +++ b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/DonationPerk.kt @@ -1,9 +1,11 @@ package com.projectcitybuild.pcbridge.http.responses import com.google.gson.annotations.SerializedName +import kotlinx.serialization.Serializable import java.time.LocalDate import java.time.ZoneId +@Serializable data class DonationPerk( @SerializedName("donation_perks_id") val id: Int = Math.random().toInt(), diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/DonationTier.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/DonationTier.kt index 83383d43..878af15d 100644 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/DonationTier.kt +++ b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/DonationTier.kt @@ -1,7 +1,9 @@ package com.projectcitybuild.pcbridge.http.responses import com.google.gson.annotations.SerializedName +import kotlinx.serialization.Serializable +@Serializable data class DonationTier( @SerializedName("donation_tier_id") val id: Int = Math.random().toInt(), diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/Group.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/Group.kt index 5092ffba..c834d61f 100644 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/Group.kt +++ b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/Group.kt @@ -1,7 +1,9 @@ package com.projectcitybuild.pcbridge.http.responses import com.google.gson.annotations.SerializedName +import kotlinx.serialization.Serializable +@Serializable data class Group( @SerializedName("group_id") val id: Int = Math.random().toInt(), @@ -11,10 +13,4 @@ data class Group( val alias: String? = null, @SerializedName("minecraft_name") val minecraftName: String?, - @SerializedName("is_default") - private val _isDefault: Boolean = false, - @SerializedName("is_staff") - private val _isStaff: Boolean = false, - @SerializedName("is_admin") - private val _isAdmin: Boolean = false, ) diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/Aggregate.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/PlayerData.kt similarity index 95% rename from pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/Aggregate.kt rename to pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/PlayerData.kt index 5e760bca..a6833c04 100644 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/Aggregate.kt +++ b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/PlayerData.kt @@ -2,7 +2,7 @@ package com.projectcitybuild.pcbridge.http.responses import com.google.gson.annotations.SerializedName -data class Aggregate( +data class PlayerData( @SerializedName("account") val account: Account? = null, @SerializedName("ban") diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/PlayerWarning.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/PlayerWarning.kt deleted file mode 100644 index 8c04d50c..00000000 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/responses/PlayerWarning.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.projectcitybuild.pcbridge.http.responses - -import com.google.gson.annotations.SerializedName - -data class PlayerWarning( - @SerializedName("id") - val id: Int, - @SerializedName("warned_player_id") - val warnedPlayerId: String, - @SerializedName("warner_player_id") - val warnerPlayerId: String, - @SerializedName("reason") - val reason: String, - @SerializedName("additional_info") - val additionalInfo: String?, - @SerializedName("weight") - val weight: Int, - @SerializedName("is_acknowledged") - val isAcknowledged: Boolean, - @SerializedName("created_at") - val createdAt: Long, - @SerializedName("updated_at") - val updatedAt: Long, - @SerializedName("acknowledged_at") - val acknowledgedAt: Long?, -) diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/IPBanHttpService.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/IPBanHttpService.kt deleted file mode 100644 index e820fd3f..00000000 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/IPBanHttpService.kt +++ /dev/null @@ -1,72 +0,0 @@ -package com.projectcitybuild.pcbridge.http.services.pcb - -import com.projectcitybuild.pcbridge.http.parsing.ResponseParser -import com.projectcitybuild.pcbridge.http.pcb -import com.projectcitybuild.pcbridge.http.responses.IPBan -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import retrofit2.Retrofit -import java.util.UUID - -class IPBanHttpService( - private val retrofit: Retrofit, - private val responseParser: ResponseParser, -) { - class IPAlreadyBannedException : Exception() - - class IPNotBannedException : Exception() - - suspend fun get(ip: String): IPBan? { - val response = - responseParser.parse { - retrofit.pcb().getIPStatus(ip = ip) - } - return response.data - } - - @Throws(IPAlreadyBannedException::class) - suspend fun ban( - ip: String, - bannerUUID: UUID?, - bannerName: String, - reason: String, - ) = withContext(Dispatchers.IO) { - try { - responseParser.parse { - retrofit.pcb().banIP( - ip = ip, - bannerPlayerId = bannerUUID.toString(), - bannerPlayerAlias = bannerName, - reason = reason, - ) - } - } catch (e: ResponseParser.HTTPError) { - if (e.errorBody?.id == "ip_already_banned") { - throw IPAlreadyBannedException() - } - throw e - } - } - - @Throws(IPNotBannedException::class) - suspend fun unban( - ip: String, - unbannerUUID: UUID?, - unbannerName: String, - ) = withContext(Dispatchers.IO) { - try { - responseParser.parse { - retrofit.pcb().unbanIP( - ip = ip, - unbannerPlayerId = unbannerUUID.toString(), - unbannerPlayerAlias = unbannerName, - ) - } - } catch (e: ResponseParser.HTTPError) { - if (e.errorBody?.id == "ip_not_banned") { - throw IPNotBannedException() - } - throw e - } - } -} diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/PlayerGroupHttpService.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/PlayerGroupHttpService.kt deleted file mode 100644 index 637c3028..00000000 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/PlayerGroupHttpService.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.projectcitybuild.pcbridge.http.services.pcb - -import com.projectcitybuild.pcbridge.http.parsing.ResponseParser -import com.projectcitybuild.pcbridge.http.pcb -import com.projectcitybuild.pcbridge.http.responses.DonationPerk -import com.projectcitybuild.pcbridge.http.responses.Group -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import retrofit2.Retrofit -import java.util.UUID - -class PlayerGroupHttpService( - private val retrofit: Retrofit, - private val responseParser: ResponseParser, -) { - class NoLinkedAccountException : Exception() - - @Throws(NoLinkedAccountException::class) - suspend fun getGroups(playerUUID: UUID): List = - withContext(Dispatchers.IO) { - val response = - try { - responseParser.parse { - retrofit.pcb().getUserGroups( - uuid = playerUUID.toString(), - ) - } - } catch (e: ResponseParser.HTTPError) { - if (e.errorBody?.id == "account_not_linked") { - throw NoLinkedAccountException() - } - throw e - } - response.data?.groups ?: listOf() - } - - @Throws(NoLinkedAccountException::class) - suspend fun getDonorPerks(playerUUID: UUID): List = - withContext(Dispatchers.IO) { - val response = - try { - responseParser.parse { - retrofit.pcb().getDonationTier( - uuid = playerUUID.toString(), - ) - } - } catch (e: ResponseParser.HTTPError) { - if (e.errorBody?.id == "account_not_linked") { - throw NoLinkedAccountException() - } - throw e - } - response.data?.toList() ?: listOf() - } -} diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/AggregateHttpService.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/PlayerHttpService.kt similarity index 81% rename from pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/AggregateHttpService.kt rename to pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/PlayerHttpService.kt index 59928f48..223ca7ba 100644 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/AggregateHttpService.kt +++ b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/PlayerHttpService.kt @@ -2,24 +2,24 @@ package com.projectcitybuild.pcbridge.http.services.pcb import com.projectcitybuild.pcbridge.http.parsing.ResponseParser import com.projectcitybuild.pcbridge.http.pcb -import com.projectcitybuild.pcbridge.http.responses.Aggregate +import com.projectcitybuild.pcbridge.http.responses.PlayerData import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import retrofit2.Retrofit import java.util.UUID -class AggregateHttpService( +class PlayerHttpService( private val retrofit: Retrofit, private val responseParser: ResponseParser, ) { suspend fun get( playerUUID: UUID, ip: String, - ): Aggregate? = + ): PlayerData? = withContext(Dispatchers.IO) { val response = responseParser.parse { - retrofit.pcb().getAggregate( + retrofit.pcb().getPlayer( uuid = playerUUID.toString(), ip = ip, ) diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/PlayerWarningHttpService.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/PlayerWarningHttpService.kt deleted file mode 100644 index 13e6f3cf..00000000 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/PlayerWarningHttpService.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.projectcitybuild.pcbridge.http.services.pcb - -import com.projectcitybuild.pcbridge.http.parsing.ResponseParser -import com.projectcitybuild.pcbridge.http.pcb -import com.projectcitybuild.pcbridge.http.responses.PlayerWarning -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import retrofit2.Retrofit -import java.util.UUID - -class PlayerWarningHttpService( - private val retrofit: Retrofit, - private val responseParser: ResponseParser, -) { - suspend fun get( - playerUUID: UUID, - playerName: String, - ): List = - withContext(Dispatchers.IO) { - val response = - responseParser.parse { - retrofit.pcb().getWarnings( - playerId = playerUUID.toString(), - playerAlias = playerName, - ) - } - response.data ?: listOf() - } - - suspend fun create( - warnedPlayerUUID: UUID, - warnedPlayerName: String, - warnerPlayerUUID: UUID, - warnerPlayerName: String, - reason: String, - ): PlayerWarning? = - withContext(Dispatchers.IO) { - val response = - responseParser.parse { - retrofit.pcb().createWarning( - warnedPlayerId = warnedPlayerUUID.toString(), - warnedPlayerAlias = warnedPlayerName, - warnerPlayerId = warnerPlayerUUID.toString(), - warnerPlayerAlias = warnerPlayerName, - reason = reason, - ) - } - response.data - } - - suspend fun acknowledge(warningId: Int): PlayerWarning? = - withContext(Dispatchers.IO) { - val response = - responseParser.parse { - retrofit.pcb().acknowledgeWarning( - warningId = warningId, - ) - } - response.data - } -} diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/AccountLinkHTTPService.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/RegisterHttpService.kt similarity index 63% rename from pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/AccountLinkHTTPService.kt rename to pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/RegisterHttpService.kt index 59d3d52c..d3fed98b 100644 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/AccountLinkHTTPService.kt +++ b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/RegisterHttpService.kt @@ -8,26 +8,22 @@ import retrofit2.Retrofit import java.util.UUID import kotlin.jvm.Throws -class AccountLinkHTTPService( +class RegisterHttpService( private val retrofit: Retrofit, private val responseParser: ResponseParser, ) { class AlreadyLinkedException : Exception() @Throws(AlreadyLinkedException::class) - suspend fun generateVerificationURL(playerUUID: UUID): String? = + suspend fun sendCode(playerUUID: UUID, playerAlias: String, email: String) = withContext(Dispatchers.IO) { try { - val response = - responseParser.parse { - retrofit.pcb().getVerificationUrl(uuid = playerUUID.toString()) - } - val data = response.data - - if (data == null || data.url.isEmpty()) { - null - } else { - data.url + responseParser.parse { + retrofit.pcb().sendRegisterCode( + uuid = playerUUID.toString(), + playerName = playerAlias, + email = email, + ) } } catch (e: ResponseParser.HTTPError) { if (e.errorBody?.id == "already_authenticated") { diff --git a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/UUIDBanHttpService.kt b/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/UUIDBanHttpService.kt deleted file mode 100644 index e27c745c..00000000 --- a/pcbridge-http/src/main/kotlin/com/projectcitybuild/pcbridge/http/services/pcb/UUIDBanHttpService.kt +++ /dev/null @@ -1,81 +0,0 @@ -package com.projectcitybuild.pcbridge.http.services.pcb - -import com.projectcitybuild.pcbridge.http.parsing.ResponseParser -import com.projectcitybuild.pcbridge.http.pcb -import com.projectcitybuild.pcbridge.http.responses.PlayerBan -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import retrofit2.Retrofit -import java.util.UUID - -class UUIDBanHttpService( - private val retrofit: Retrofit, - private val responseParser: ResponseParser, -) { - class UUIDAlreadyBannedException : Exception() - - class UUIDNotBannedException : Exception() - - suspend fun get(targetPlayerUUID: UUID): PlayerBan? = - withContext(Dispatchers.IO) { - val response = - responseParser.parse { - retrofit.pcb().getUuidBanStatus( - playerId = targetPlayerUUID.toString(), - ) - } - val ban = response.data - if (ban?.unbannedAt != null) { - null - } - ban - } - - @Throws(UUIDAlreadyBannedException::class) - suspend fun ban( - targetPlayerUUID: UUID, - targetPlayerName: String, - bannerPlayerUUID: UUID?, - bannerPlayerName: String, - reason: String?, - expiryDate: Long? = null, - ) = withContext(Dispatchers.IO) { - try { - responseParser.parse { - retrofit.pcb().banUUID( - bannedPlayerId = targetPlayerUUID.toString(), - bannedPlayerAlias = targetPlayerName, - bannerPlayerId = bannerPlayerUUID.toString(), - bannerPlayerAlias = bannerPlayerName, - reason = reason, - expiresAt = expiryDate, - ) - } - } catch (e: ResponseParser.HTTPError) { - if (e.errorBody?.id == "player_already_banned") { - throw UUIDAlreadyBannedException() - } - throw e - } - } - - @Throws(UUIDNotBannedException::class) - suspend fun unban( - targetPlayerUUID: UUID, - unbannerUUID: UUID?, - ) = withContext(Dispatchers.IO) { - try { - responseParser.parse { - retrofit.pcb().unbanUUID( - bannedPlayerId = targetPlayerUUID.toString(), - unbannerPlayerId = unbannerUUID.toString(), - ) - } - } catch (e: ResponseParser.HTTPError) { - if (e.errorBody?.id == "player_not_banned") { - throw UUIDNotBannedException() - } - throw e - } - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/Container.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/Container.kt index d4733f05..614da68f 100644 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/Container.kt +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/Container.kt @@ -15,27 +15,13 @@ import com.projectcitybuild.pcbridge.core.state.Store import com.projectcitybuild.pcbridge.data.PluginConfig import com.projectcitybuild.pcbridge.features.announcements.listeners.AnnouncementEnableListener import com.projectcitybuild.pcbridge.features.announcements.repositories.AnnouncementRepository -import com.projectcitybuild.pcbridge.features.bans.actions.AuthoriseConnection -import com.projectcitybuild.pcbridge.features.bans.actions.BanIP -import com.projectcitybuild.pcbridge.features.bans.actions.BanUUID -import com.projectcitybuild.pcbridge.features.bans.actions.CheckUUIDBan -import com.projectcitybuild.pcbridge.features.bans.actions.UnbanIP -import com.projectcitybuild.pcbridge.features.bans.actions.UnbanUUID -import com.projectcitybuild.pcbridge.features.bans.commands.BanCommand -import com.projectcitybuild.pcbridge.features.bans.commands.BanIPCommand -import com.projectcitybuild.pcbridge.features.bans.commands.CheckBanCommand -import com.projectcitybuild.pcbridge.features.bans.commands.UnbanCommand -import com.projectcitybuild.pcbridge.features.bans.commands.UnbanIPCommand +import com.projectcitybuild.pcbridge.features.bans.actions.AuthorizeConnection import com.projectcitybuild.pcbridge.features.bans.listeners.AuthorizeConnectionListener -import com.projectcitybuild.pcbridge.features.bans.repositories.AggregateRepository -import com.projectcitybuild.pcbridge.features.bans.repositories.IPBanRepository -import com.projectcitybuild.pcbridge.features.bans.repositories.PlayerBanRepository -import com.projectcitybuild.pcbridge.features.bans.repositories.PlayerUUIDRepository +import com.projectcitybuild.pcbridge.features.bans.repositories.PlayerRepository import com.projectcitybuild.pcbridge.features.chat.ChatBadgeFormatter import com.projectcitybuild.pcbridge.features.chat.ChatGroupFormatter import com.projectcitybuild.pcbridge.features.chat.listeners.EmojiChatListener import com.projectcitybuild.pcbridge.features.chat.listeners.FormatNameChatListener -import com.projectcitybuild.pcbridge.features.chat.listeners.SyncBadgesOnJoinListener import com.projectcitybuild.pcbridge.features.chat.repositories.ChatBadgeRepository import com.projectcitybuild.pcbridge.features.chat.repositories.ChatGroupRepository import com.projectcitybuild.pcbridge.features.invisframes.commands.InvisFrameCommand @@ -47,25 +33,16 @@ import com.projectcitybuild.pcbridge.features.joinmessages.listeners.AnnounceQui import com.projectcitybuild.pcbridge.features.joinmessages.listeners.FirstTimeJoinListener import com.projectcitybuild.pcbridge.features.joinmessages.listeners.ServerOverviewJoinListener import com.projectcitybuild.pcbridge.features.joinmessages.repositories.PlayerConfigRepository -import com.projectcitybuild.pcbridge.features.mute.commands.MuteCommand -import com.projectcitybuild.pcbridge.features.mute.commands.UnmuteCommand -import com.projectcitybuild.pcbridge.features.mute.listeners.MuteChatListener import com.projectcitybuild.pcbridge.features.nightvision.commands.NightVisionCommand +import com.projectcitybuild.pcbridge.features.playerstate.listeners.PlayerStateListener import com.projectcitybuild.pcbridge.features.staffchat.commands.StaffChatCommand -import com.projectcitybuild.pcbridge.features.sync.actions.GenerateAccountVerificationURL import com.projectcitybuild.pcbridge.features.sync.actions.SyncPlayerGroups -import com.projectcitybuild.pcbridge.features.sync.actions.UpdatePlayerGroups import com.projectcitybuild.pcbridge.features.sync.commands.SyncCommand -import com.projectcitybuild.pcbridge.features.sync.commands.SyncOtherCommand import com.projectcitybuild.pcbridge.features.sync.listener.SyncRankOnJoinListener import com.projectcitybuild.pcbridge.features.sync.repositories.SyncRepository import com.projectcitybuild.pcbridge.features.telemetry.listeners.TelemetryPlayerConnectListener import com.projectcitybuild.pcbridge.features.telemetry.repositories.TelemetryRepository import com.projectcitybuild.pcbridge.features.utilities.commands.PCBridgeCommand -import com.projectcitybuild.pcbridge.features.warnings.actions.GetUnacknowledgedWarnings -import com.projectcitybuild.pcbridge.features.warnings.commands.WarningAcknowledgeCommand -import com.projectcitybuild.pcbridge.features.warnings.listeners.NotifyWarningsOnJoinListener -import com.projectcitybuild.pcbridge.features.warnings.repositories.PlayerWarningRepository import com.projectcitybuild.pcbridge.features.warps.Warp import com.projectcitybuild.pcbridge.features.warps.commands.WarpCommand import com.projectcitybuild.pcbridge.features.warps.commands.WarpsCommand @@ -108,14 +85,13 @@ fun pluginModule(_plugin: JavaPlugin) = chat() joinMessages() invisFrames() - mute() nightVision() + playerState() staffChat() sync() telemetry() utilities() warps() - warnings() } private fun Module.spigot(plugin: JavaPlugin) { @@ -316,8 +292,6 @@ private fun Module.joinMessages() { factory { AnnounceJoinListener( config = get(), - store = get(), - time = get(), ) } @@ -345,123 +319,61 @@ private fun Module.joinMessages() { } } -private fun Module.bans() { - factory { - AggregateRepository( - httpService = get().aggregate, - ) - } - - factory { - PlayerBanRepository( - httpService = get().uuidBan, - ) - } - +private fun Module.playerState() { factory { - PlayerUUIDRepository( + PlayerStateListener( + store = get(), server = get(), - httpService = get().playerUuid, + time = get(), + minecraftDispatcher = { get().minecraftDispatcher }, ) } factory { - IPBanRepository( - httpService = get().ipBan, + AnnounceJoinListener( + config = get(), ) } factory { - BanCommand( - banUUID = - BanUUID( - playerBanRepository = get(), - playerUUIDRepository = get(), - server = get(), - ), - server = get(), + AnnounceQuitListener( + config = get(), + store = get(), + time = get(), ) } factory { - BanIPCommand( - banIP = - BanIP( - ipBanRepository = get(), - server = get(), - ), + FirstTimeJoinListener( + config = get(), server = get(), + playerConfigRepository = get(), + time = get(), ) } factory { - UnbanCommand( - unbanUUID = - UnbanUUID( - playerBanRepository = get(), - playerUUIDRepository = get(), - ), - ) - } - - factory { - UnbanIPCommand( - unbanIP = - UnbanIP( - ipBanRepository = get(), - ), + ServerOverviewJoinListener( + config = get(), ) } +} +private fun Module.bans() { factory { - CheckBanCommand( - checkUUIDBan = - CheckUUIDBan( - dateTimeFormatter = get(), - playerUUIDRepository = get(), - playerBanRepository = get(), - ), + PlayerRepository( + httpService = get().player, ) } factory { AuthorizeConnectionListener( - aggregateRepository = get(), - authoriseConnection = AuthoriseConnection(), + playerRepository = get(), + authorizeConnection = AuthorizeConnection(), dateTimeFormatter = get(), sentry = get(), server = get(), minecraftDispatcher = { get().minecraftDispatcher }, - store = get(), - ) - } -} - -private fun Module.mute() { - single(named("mute_cache")) { - // We use a regular cache instead of the server state here - // so that mutes persist even if the player leaves, but - // invalidates if the plugin is reloaded/shutdown - Cache.Builder().build() - } - - factory { - MuteCommand( - server = get(), - mutedPlayers = get(named("mute_cache")), - ) - } - - factory { - UnmuteCommand( - server = get(), - mutedPlayers = get(named("mute_cache")), - ) - } - - factory { - MuteChatListener( - mutedPlayers = get(named("mute_cache")), ) } } @@ -545,12 +457,6 @@ private fun Module.chat() { groupCache = get(named("group_cache")), ) } - - factory { - SyncBadgesOnJoinListener( - store = get(), - ) - } } private fun Module.telemetry() { @@ -576,27 +482,6 @@ private fun Module.staffChat() { } private fun Module.sync() { - factory { - SyncRepository( - playerGroupHttpService = get().playerGroup, - accountLinkHttpService = get().verificationURL, - config = get(), - ) - } - - factory { - UpdatePlayerGroups( - permissions = get(), - syncRepository = get(), - ) - } - - factory { - GenerateAccountVerificationURL( - syncRepository = get(), - ) - } - factory { SyncPlayerGroups( permissions = get(), @@ -605,17 +490,13 @@ private fun Module.sync() { } factory { - SyncCommand( - generateAccountVerificationURL = get(), - updatePlayerGroups = get(), + SyncRepository( + config = get(), ) } factory { - SyncOtherCommand( - server = get(), - updatePlayerGroups = get(), - ) + SyncCommand() } factory { @@ -636,27 +517,3 @@ private fun Module.utilities() { PCBridgeCommand.TabCompleter() } } - -private fun Module.warnings() { - factory { - PlayerWarningRepository( - playerWarningHttpService = get().playerWarning, - ) - } - - factory { - WarningAcknowledgeCommand( - warningRepository = get(), - ) - } - - factory { - NotifyWarningsOnJoinListener( - getUnacknowledgedWarnings = - GetUnacknowledgedWarnings( - dateTimeFormatter = get(), - warningRepository = get(), - ), - ) - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/Plugin.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/Plugin.kt index 40ea32ad..da9b6bac 100644 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/Plugin.kt +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/Plugin.kt @@ -4,15 +4,9 @@ import com.github.shynixn.mccoroutine.bukkit.SuspendingJavaPlugin import com.projectcitybuild.pcbridge.core.errors.SentryReporter import com.projectcitybuild.pcbridge.core.errors.trace import com.projectcitybuild.pcbridge.features.announcements.listeners.AnnouncementEnableListener -import com.projectcitybuild.pcbridge.features.bans.commands.BanCommand -import com.projectcitybuild.pcbridge.features.bans.commands.BanIPCommand -import com.projectcitybuild.pcbridge.features.bans.commands.CheckBanCommand -import com.projectcitybuild.pcbridge.features.bans.commands.UnbanCommand -import com.projectcitybuild.pcbridge.features.bans.commands.UnbanIPCommand import com.projectcitybuild.pcbridge.features.bans.listeners.AuthorizeConnectionListener import com.projectcitybuild.pcbridge.features.chat.listeners.EmojiChatListener import com.projectcitybuild.pcbridge.features.chat.listeners.FormatNameChatListener -import com.projectcitybuild.pcbridge.features.chat.listeners.SyncBadgesOnJoinListener import com.projectcitybuild.pcbridge.features.invisframes.commands.InvisFrameCommand import com.projectcitybuild.pcbridge.features.invisframes.listeners.FrameItemInsertListener import com.projectcitybuild.pcbridge.features.invisframes.listeners.FrameItemRemoveListener @@ -21,18 +15,13 @@ import com.projectcitybuild.pcbridge.features.joinmessages.listeners.AnnounceJoi import com.projectcitybuild.pcbridge.features.joinmessages.listeners.AnnounceQuitListener import com.projectcitybuild.pcbridge.features.joinmessages.listeners.FirstTimeJoinListener import com.projectcitybuild.pcbridge.features.joinmessages.listeners.ServerOverviewJoinListener -import com.projectcitybuild.pcbridge.features.mute.commands.MuteCommand -import com.projectcitybuild.pcbridge.features.mute.commands.UnmuteCommand -import com.projectcitybuild.pcbridge.features.mute.listeners.MuteChatListener import com.projectcitybuild.pcbridge.features.nightvision.commands.NightVisionCommand +import com.projectcitybuild.pcbridge.features.playerstate.listeners.PlayerStateListener import com.projectcitybuild.pcbridge.features.staffchat.commands.StaffChatCommand import com.projectcitybuild.pcbridge.features.sync.commands.SyncCommand -import com.projectcitybuild.pcbridge.features.sync.commands.SyncOtherCommand import com.projectcitybuild.pcbridge.features.sync.listener.SyncRankOnJoinListener import com.projectcitybuild.pcbridge.features.telemetry.listeners.TelemetryPlayerConnectListener import com.projectcitybuild.pcbridge.features.utilities.commands.PCBridgeCommand -import com.projectcitybuild.pcbridge.features.warnings.commands.WarningAcknowledgeCommand -import com.projectcitybuild.pcbridge.features.warnings.listeners.NotifyWarningsOnJoinListener import com.projectcitybuild.pcbridge.features.warps.commands.WarpCommand import com.projectcitybuild.pcbridge.features.warps.commands.WarpsCommand import com.projectcitybuild.pcbridge.integrations.DynmapIntegration @@ -109,14 +98,6 @@ private class Lifecycle : KoinComponent { handler = get(), argsParser = StaffChatCommand.Args.Parser(), ) - register( - handler = get(), - argsParser = MuteCommand.Args.Parser(), - ) - register( - handler = get(), - argsParser = UnmuteCommand.Args.Parser(), - ) register( handler = get(), argsParser = NightVisionCommand.Args.Parser(), @@ -125,56 +106,26 @@ private class Lifecycle : KoinComponent { handler = get(), argsParser = InvisFrameCommand.Args.Parser(), ) - register( - handler = get(), - argsParser = BanCommand.Args.Parser(), - ) - register( - handler = get(), - argsParser = BanIPCommand.Args.Parser(), - ) - register( - handler = get(), - argsParser = CheckBanCommand.Args.Parser(), - ) - register( - handler = get(), - argsParser = UnbanCommand.Args.Parser(), - ) - register( - handler = get(), - argsParser = UnbanIPCommand.Args.Parser(), - ) register( handler = get(), argsParser = SyncCommand.Args.Parser(), ) - register( - handler = get(), - argsParser = SyncOtherCommand.Args.Parser(), - ) - register( - handler = get(), - argsParser = WarningAcknowledgeCommand.Args.Parser(), - ) } listenerRegistry.register( get(), get(), - get(), - get(), + get(), + get(), get(), - get(), - get(), + get(), + get(), get(), get(), get(), - get(), + get(), + get(), get(), - get(), - get(), - get(), - get(), + get(), ) get().enable() diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/core/state/ServerState.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/core/state/ServerState.kt index 3521ad88..3dfb7680 100644 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/core/state/ServerState.kt +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/core/state/ServerState.kt @@ -1,6 +1,8 @@ package com.projectcitybuild.pcbridge.core.state +import com.projectcitybuild.pcbridge.http.responses.Account import com.projectcitybuild.pcbridge.http.responses.Badge +import com.projectcitybuild.pcbridge.http.responses.DonationPerk import com.projectcitybuild.pcbridge.support.serializable.LocalDateTimeSerializer import com.projectcitybuild.pcbridge.support.serializable.UUIDSerializer import kotlinx.serialization.Serializable @@ -26,27 +28,13 @@ data class ServerState( * which one was last broadcast when reloading */ val lastBroadcastIndex: Int, -) { - companion object { - fun default() = - ServerState( - players = mutableMapOf(), - lastBroadcastIndex = -1, - ) - } -} +) @Serializable data class PlayerState( @Serializable(with = LocalDateTimeSerializer::class) val connectedAt: LocalDateTime?, - val badges: List, -) { - companion object { - fun empty() = - PlayerState( - connectedAt = null, - badges = emptyList(), - ) - } -} + val account: Account? = null, + val badges: List = emptyList(), + val donationPerks: List = emptyList(), +) diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/core/state/Store.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/core/state/Store.kt index 0d96e54a..59a10a36 100644 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/core/state/Store.kt +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/core/state/Store.kt @@ -8,6 +8,7 @@ import kotlinx.coroutines.withContext private val mutex = Mutex() +// TODO: splice the store so that each feature can maintain its own state slice class Store { val state: ServerState get() = _state diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/AuthoriseConnection.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/AuthorizeConnection.kt similarity index 71% rename from pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/AuthoriseConnection.kt rename to pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/AuthorizeConnection.kt index 5b39e864..a0d61a49 100644 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/AuthoriseConnection.kt +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/AuthorizeConnection.kt @@ -1,10 +1,10 @@ package com.projectcitybuild.pcbridge.features.bans.actions -import com.projectcitybuild.pcbridge.http.responses.Aggregate +import com.projectcitybuild.pcbridge.http.responses.PlayerData import com.projectcitybuild.pcbridge.http.responses.IPBan import com.projectcitybuild.pcbridge.http.responses.PlayerBan -class AuthoriseConnection { +class AuthorizeConnection { sealed class ConnectResult { object Allowed : ConnectResult() @@ -17,20 +17,20 @@ class AuthoriseConnection { data class IP(val value: IPBan) : Ban() } - fun execute(aggregate: Aggregate): ConnectResult { - val ban = getBan(aggregate) + fun execute(playerData: PlayerData): ConnectResult { + val ban = getBan(playerData) if (ban != null) { return ConnectResult.Denied(ban = ban) } return ConnectResult.Allowed } - private fun getBan(aggregate: Aggregate): Ban? { - val playerBan = aggregate.playerBan + private fun getBan(playerData: PlayerData): Ban? { + val playerBan = playerData.playerBan if (playerBan != null && playerBan.isActive) { return Ban.UUID(playerBan) } - val ipBan = aggregate.ipBan + val ipBan = playerData.ipBan if (ipBan != null && ipBan.isActive) { return Ban.IP(ipBan) } diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/BanIP.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/BanIP.kt deleted file mode 100644 index bcaf3b6b..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/BanIP.kt +++ /dev/null @@ -1,54 +0,0 @@ -package com.projectcitybuild.pcbridge.features.bans.actions - -import com.projectcitybuild.pcbridge.features.bans.Sanitizer -import com.projectcitybuild.pcbridge.features.bans.isValidIP -import com.projectcitybuild.pcbridge.features.bans.repositories.IPBanRepository -import com.projectcitybuild.pcbridge.http.services.pcb.IPBanHttpService -import com.projectcitybuild.pcbridge.utils.Failure -import com.projectcitybuild.pcbridge.utils.Result -import com.projectcitybuild.pcbridge.utils.Success -import net.kyori.adventure.text.Component -import org.bukkit.Server -import org.bukkit.event.player.PlayerKickEvent -import java.util.UUID - -class BanIP( - private val ipBanRepository: IPBanRepository, - private val server: Server, -) { - enum class FailureReason { - IP_ALREADY_BANNED, - INVALID_IP, - } - - suspend fun execute( - ip: String, - bannerUUID: UUID?, - bannerName: String, - reason: String, - ): Result { - val sanitizedIP = Sanitizer.sanitizedIP(ip) - if (!isValidIP(sanitizedIP)) { - return Failure(FailureReason.INVALID_IP) - } - try { - ipBanRepository.ban( - ip = sanitizedIP, - bannerUUID = bannerUUID, - bannerName = bannerName, - reason = reason, - ) - } catch (e: IPBanHttpService.IPAlreadyBannedException) { - return Failure(FailureReason.IP_ALREADY_BANNED) - } - - server.onlinePlayers - .firstOrNull { it.address.toString() == ip } - ?.kick( - Component.text("You have been banned.\n\nAppeal @ projectcitybuild.com"), - PlayerKickEvent.Cause.BANNED, - ) - - return Success(Unit) - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/BanUUID.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/BanUUID.kt deleted file mode 100644 index 18ffebc4..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/BanUUID.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.projectcitybuild.pcbridge.features.bans.actions - -import com.projectcitybuild.pcbridge.features.bans.repositories.PlayerBanRepository -import com.projectcitybuild.pcbridge.features.bans.repositories.PlayerUUIDRepository -import com.projectcitybuild.pcbridge.http.services.pcb.UUIDBanHttpService -import com.projectcitybuild.pcbridge.utils.Failure -import com.projectcitybuild.pcbridge.utils.Result -import com.projectcitybuild.pcbridge.utils.Success -import net.kyori.adventure.text.Component -import org.bukkit.Server -import org.bukkit.event.player.PlayerKickEvent -import java.util.UUID - -class BanUUID( - private val playerBanRepository: PlayerBanRepository, - private val playerUUIDRepository: PlayerUUIDRepository, - private val server: Server, -) { - enum class FailureReason { - PlayerDoesNotExist, - PlayerAlreadyBanned, - } - - suspend fun ban( - targetPlayerName: String, - bannerUUID: UUID?, - bannerName: String, - reason: String?, - ): Result { - try { - val targetPlayerUUID = - playerUUIDRepository.get(targetPlayerName) - ?: return Failure(FailureReason.PlayerDoesNotExist) - - playerBanRepository.ban( - targetPlayerUUID = targetPlayerUUID, - targetPlayerName = targetPlayerName, - bannerPlayerUUID = bannerUUID, - bannerPlayerName = bannerName, - reason = reason, - ) - - server.getPlayer(targetPlayerUUID)?.kick( - Component.text("You have been banned.\n\nAppeal @ projectcitybuild.com"), - PlayerKickEvent.Cause.BANNED, - ) - - return Success(Unit) - } catch (e: UUIDBanHttpService.UUIDAlreadyBannedException) { - return Failure(FailureReason.PlayerAlreadyBanned) - } - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/CheckUUIDBan.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/CheckUUIDBan.kt deleted file mode 100644 index d777e930..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/CheckUUIDBan.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.projectcitybuild.pcbridge.features.bans.actions - -import com.projectcitybuild.pcbridge.core.datetime.DateTimeFormatter -import com.projectcitybuild.pcbridge.features.bans.repositories.PlayerBanRepository -import com.projectcitybuild.pcbridge.features.bans.repositories.PlayerUUIDRepository -import com.projectcitybuild.pcbridge.utils.Failure -import com.projectcitybuild.pcbridge.utils.Result -import com.projectcitybuild.pcbridge.utils.Success - -class CheckUUIDBan( - private val playerBanRepository: PlayerBanRepository, - private val playerUUIDRepository: PlayerUUIDRepository, - private val dateTimeFormatter: DateTimeFormatter, -) { - enum class FailureReason { - PLAYER_DOES_NOT_EXIST, - } - - data class BanRecord( - val reason: String, - val dateOfBan: String, - val expiryDate: String, - ) - - suspend fun getBan(targetPlayerName: String): Result { - val targetPlayerUUID = - playerUUIDRepository.get(targetPlayerName) - ?: return Failure(FailureReason.PLAYER_DOES_NOT_EXIST) - - val ban = - playerBanRepository.get(targetPlayerUUID = targetPlayerUUID) - ?: return Success(null) - - val banRecord = - BanRecord( - reason = ban.reason ?: "No reason given", - dateOfBan = ban.createdAt.let { dateTimeFormatter.convert(it) }, - expiryDate = ban.expiresAt?.let { dateTimeFormatter.convert(it) } ?: "Never", - ) - return Success(banRecord) - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/UnbanIP.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/UnbanIP.kt deleted file mode 100644 index 87165c02..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/UnbanIP.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.projectcitybuild.pcbridge.features.bans.actions - -import com.projectcitybuild.pcbridge.features.bans.Sanitizer -import com.projectcitybuild.pcbridge.features.bans.isValidIP -import com.projectcitybuild.pcbridge.features.bans.repositories.IPBanRepository -import com.projectcitybuild.pcbridge.http.services.pcb.IPBanHttpService -import com.projectcitybuild.pcbridge.utils.Failure -import com.projectcitybuild.pcbridge.utils.Result -import com.projectcitybuild.pcbridge.utils.Success -import java.util.UUID - -class UnbanIP( - private val ipBanRepository: IPBanRepository, -) { - enum class FailureReason { - IP_NOT_BANNED, - INVALID_IP, - } - - suspend fun execute( - ip: String, - unbannerUUID: UUID?, - unbannerName: String, - ): Result { - val sanitizedIP = Sanitizer.sanitizedIP(ip) - if (!isValidIP(sanitizedIP)) { - return Failure(FailureReason.INVALID_IP) - } - - try { - ipBanRepository.unban( - ip = ip, - unbannerUUID = unbannerUUID, - unbannerName = unbannerName, - ) - } catch (e: IPBanHttpService.IPNotBannedException) { - return Failure(FailureReason.IP_NOT_BANNED) - } - - return Success(Unit) - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/UnbanUUID.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/UnbanUUID.kt deleted file mode 100644 index b8454e9b..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/actions/UnbanUUID.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.projectcitybuild.pcbridge.features.bans.actions - -import com.projectcitybuild.pcbridge.features.bans.repositories.PlayerBanRepository -import com.projectcitybuild.pcbridge.features.bans.repositories.PlayerUUIDRepository -import com.projectcitybuild.pcbridge.http.services.pcb.UUIDBanHttpService -import com.projectcitybuild.pcbridge.utils.Failure -import com.projectcitybuild.pcbridge.utils.Result -import com.projectcitybuild.pcbridge.utils.Success -import java.util.UUID - -class UnbanUUID( - private val playerBanRepository: PlayerBanRepository, - private val playerUUIDRepository: PlayerUUIDRepository, -) { - enum class FailureReason { - PlayerDoesNotExist, - PlayerNotBanned, - } - - suspend fun unban( - targetPlayerName: String, - unbannerUUID: UUID?, - ): Result { - try { - val targetPlayerUUID = - playerUUIDRepository.get(targetPlayerName) - ?: return Failure(FailureReason.PlayerDoesNotExist) - - playerBanRepository.unban( - targetPlayerUUID = targetPlayerUUID, - unbannerUUID = unbannerUUID, - ) - - return Success(Unit) - } catch (e: UUIDBanHttpService.UUIDNotBannedException) { - return Failure(FailureReason.PlayerNotBanned) - } - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/BanCommand.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/BanCommand.kt deleted file mode 100644 index 7bfec149..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/BanCommand.kt +++ /dev/null @@ -1,76 +0,0 @@ -package com.projectcitybuild.pcbridge.features.bans.commands - -import com.projectcitybuild.pcbridge.features.bans.actions.BanUUID -import com.projectcitybuild.pcbridge.support.messages.CommandHelpBuilder -import com.projectcitybuild.pcbridge.support.spigot.BadCommandUsageException -import com.projectcitybuild.pcbridge.support.spigot.CommandArgsParser -import com.projectcitybuild.pcbridge.support.spigot.SpigotCommand -import com.projectcitybuild.pcbridge.utils.Failure -import com.projectcitybuild.pcbridge.utils.Success -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.NamedTextColor -import net.kyori.adventure.text.format.TextDecoration -import org.bukkit.Server -import org.bukkit.command.CommandSender -import org.bukkit.entity.Player - -class BanCommand( - private val banUUID: BanUUID, - private val server: Server, -) : SpigotCommand { - override val label = "ban" - - override val usage = CommandHelpBuilder() - - override suspend fun run( - sender: CommandSender, - args: Args, - ) { - val result = - banUUID.ban( - targetPlayerName = args.targetPlayerName, - bannerUUID = if (sender is Player) sender.uniqueId else null, - bannerName = sender.name, - reason = args.reason, - ) - when (result) { - is Failure -> - sender.sendMessage( - Component.text(result.reason.toMessage(args.targetPlayerName)) - .color(NamedTextColor.RED), - ) - is Success -> - server.broadcast( - Component.text("${args.targetPlayerName} has been banned") - .color(NamedTextColor.GRAY) - .decorate(TextDecoration.ITALIC), - ) - } - } - - data class Args( - val targetPlayerName: String, - val reason: String, - ) { - class Parser : CommandArgsParser { - override fun parse(args: List): Args { - if (args.isEmpty()) { - throw BadCommandUsageException() - } - return Args( - targetPlayerName = args[0], - reason = if (args.size > 1) args.drop(1).joinToString(separator = " ") else "", - ) - } - } - } -} - -private fun BanUUID.FailureReason.toMessage(targetPlayerName: String) = - when (this) { - BanUUID.FailureReason.PlayerDoesNotExist, - -> "Error: Could not find UUID for $targetPlayerName. This player likely doesn't exist" - - BanUUID.FailureReason.PlayerAlreadyBanned, - -> "Error: $targetPlayerName is already banned" - } diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/BanIPCommand.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/BanIPCommand.kt deleted file mode 100644 index 0d6bb6ff..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/BanIPCommand.kt +++ /dev/null @@ -1,77 +0,0 @@ -package com.projectcitybuild.pcbridge.features.bans.commands - -import com.projectcitybuild.pcbridge.features.bans.actions.BanIP -import com.projectcitybuild.pcbridge.support.messages.CommandHelpBuilder -import com.projectcitybuild.pcbridge.support.spigot.BadCommandUsageException -import com.projectcitybuild.pcbridge.support.spigot.CommandArgsParser -import com.projectcitybuild.pcbridge.support.spigot.SpigotCommand -import com.projectcitybuild.pcbridge.utils.Failure -import com.projectcitybuild.pcbridge.utils.Success -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.NamedTextColor -import net.kyori.adventure.text.format.TextDecoration -import org.bukkit.Server -import org.bukkit.command.CommandSender -import org.bukkit.entity.Player - -class BanIPCommand( - private val server: Server, - private val banIP: BanIP, -) : SpigotCommand { - override val label = "banip" - - override val usage = CommandHelpBuilder() - - override suspend fun run( - sender: CommandSender, - args: Args, - ) { - val targetIP = - server.onlinePlayers - .firstOrNull { it.name.lowercase() == args.target.lowercase() } - ?.address?.toString() - ?: args.target - - val result = - banIP.execute( - ip = targetIP, - bannerUUID = if (sender is Player) sender.uniqueId else null, - bannerName = sender.name, - reason = args.reason, - ) - val message = - when (result) { - is Failure -> - when (result.reason) { - BanIP.FailureReason.IP_ALREADY_BANNED -> - Component.text("$targetIP is already banned") - .color(NamedTextColor.RED) - BanIP.FailureReason.INVALID_IP -> - Component.text("$targetIP is not a valid IP") - .color(NamedTextColor.RED) - } - is Success -> - Component.text("IP $targetIP has been banned") - .color(NamedTextColor.GRAY) - .decorate(TextDecoration.ITALIC) - } - sender.sendMessage(message) - } - - data class Args( - val target: String, - val reason: String, - ) { - class Parser : CommandArgsParser { - override fun parse(args: List): Args { - if (args.isEmpty()) { - throw BadCommandUsageException() - } - return Args( - target = args[0], - reason = if (args.size > 1) args.drop(1).joinToString(separator = " ") else "", - ) - } - } - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/CheckBanCommand.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/CheckBanCommand.kt deleted file mode 100644 index 31fe0d1c..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/CheckBanCommand.kt +++ /dev/null @@ -1,69 +0,0 @@ -package com.projectcitybuild.pcbridge.features.bans.commands - -import com.projectcitybuild.pcbridge.features.bans.actions.CheckUUIDBan -import com.projectcitybuild.pcbridge.support.messages.CommandHelpBuilder -import com.projectcitybuild.pcbridge.support.spigot.BadCommandUsageException -import com.projectcitybuild.pcbridge.support.spigot.CommandArgsParser -import com.projectcitybuild.pcbridge.support.spigot.SpigotCommand -import com.projectcitybuild.pcbridge.utils.Failure -import com.projectcitybuild.pcbridge.utils.Success -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.NamedTextColor -import net.md_5.bungee.api.ChatColor -import org.bukkit.command.CommandSender - -class CheckBanCommand( - private val checkUUIDBan: CheckUUIDBan, -) : SpigotCommand { - override val label = "checkban" - - override val usage = CommandHelpBuilder() - - override suspend fun run( - sender: CommandSender, - args: Args, - ) { - val result = checkUUIDBan.getBan(args.targetPlayerName) - val message = - when (result) { - is Failure -> - when (result.reason) { - CheckUUIDBan.FailureReason.PLAYER_DOES_NOT_EXIST -> - Component - .text("Could not find UUID for ${args.targetPlayerName}. This player likely doesn't exist") - .color(NamedTextColor.RED) - } - is Success -> - result.value.let { ban -> - if (ban == null) { - Component.text("${args.targetPlayerName} is not currently banned") - .color(NamedTextColor.RED) - } else { - Component.text( - """ - ${ChatColor.RED}${args.targetPlayerName} is currently banned. - ${ChatColor.GRAY}--- - ${ChatColor.GRAY}Reason » ${ChatColor.WHITE}${ban.reason} - ${ChatColor.GRAY}Date » ${ChatColor.WHITE}${ban.dateOfBan} - ${ChatColor.GRAY}Expires » ${ChatColor.WHITE}${ban.expiryDate} - """.trimIndent(), - ) - } - } - } - sender.sendMessage(message) - } - - data class Args( - val targetPlayerName: String, - ) { - class Parser : CommandArgsParser { - override fun parse(args: List): Args { - if (args.isEmpty()) { - throw BadCommandUsageException() - } - return Args(targetPlayerName = args[0]) - } - } - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/UnbanCommand.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/UnbanCommand.kt deleted file mode 100644 index cdde597d..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/UnbanCommand.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.projectcitybuild.pcbridge.features.bans.commands - -import com.projectcitybuild.pcbridge.features.bans.actions.UnbanUUID -import com.projectcitybuild.pcbridge.support.messages.CommandHelpBuilder -import com.projectcitybuild.pcbridge.support.spigot.BadCommandUsageException -import com.projectcitybuild.pcbridge.support.spigot.CommandArgsParser -import com.projectcitybuild.pcbridge.support.spigot.SpigotCommand -import com.projectcitybuild.pcbridge.utils.Failure -import com.projectcitybuild.pcbridge.utils.Success -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.NamedTextColor -import net.kyori.adventure.text.format.TextDecoration -import org.bukkit.command.CommandSender -import org.bukkit.entity.Player - -class UnbanCommand( - private val unbanUUID: UnbanUUID, -) : SpigotCommand { - override val label = "unban" - - override val usage = CommandHelpBuilder() // TODO - - override suspend fun run( - sender: CommandSender, - args: Args, - ) { - val result = - unbanUUID.unban( - targetPlayerName = args.targetPlayerName, - unbannerUUID = if (sender is Player) sender.uniqueId else null, - ) - val message = - when (result) { - is Failure -> - Component.text(result.reason.toMessage(args.targetPlayerName)) - .color(NamedTextColor.RED) - is Success -> - Component.text("{${args.targetPlayerName} has been unbanned") - .color(NamedTextColor.GRAY) - .decorate(TextDecoration.ITALIC) - } - sender.sendMessage(message) - } - - data class Args( - val targetPlayerName: String, - ) { - class Parser : CommandArgsParser { - override fun parse(args: List): Args { - if (args.isEmpty()) { - throw BadCommandUsageException() - } - return Args(targetPlayerName = args[0]) - } - } - } -} - -private fun UnbanUUID.FailureReason.toMessage(targetPlayerName: String) = - when (this) { - UnbanUUID.FailureReason.PlayerDoesNotExist -> "Could not find UUID for $targetPlayerName. This player likely doesn't exist" - UnbanUUID.FailureReason.PlayerNotBanned -> "$targetPlayerName is not currently banned" - } diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/UnbanIPCommand.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/UnbanIPCommand.kt deleted file mode 100644 index 8e0a986b..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/commands/UnbanIPCommand.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.projectcitybuild.pcbridge.features.bans.commands - -import com.projectcitybuild.pcbridge.features.bans.actions.UnbanIP -import com.projectcitybuild.pcbridge.support.messages.CommandHelpBuilder -import com.projectcitybuild.pcbridge.support.spigot.BadCommandUsageException -import com.projectcitybuild.pcbridge.support.spigot.CommandArgsParser -import com.projectcitybuild.pcbridge.support.spigot.SpigotCommand -import com.projectcitybuild.pcbridge.utils.Failure -import com.projectcitybuild.pcbridge.utils.Success -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.NamedTextColor -import org.bukkit.command.CommandSender -import org.bukkit.entity.Player - -class UnbanIPCommand( - private val unbanIP: UnbanIP, -) : SpigotCommand { - override val label = "unbanip" - - override val usage = CommandHelpBuilder() - - override suspend fun run( - sender: CommandSender, - args: Args, - ) { - val result = - unbanIP.execute( - ip = args.ip, - unbannerUUID = if (sender is Player) sender.uniqueId else null, - unbannerName = sender.name, - ) - - val message = - when (result) { - is Failure -> - Component.text(result.reason.toMessage(args.ip)) - .color(NamedTextColor.RED) - is Success -> - Component.text("IP ${args.ip} has been unbanned") - .color(NamedTextColor.GRAY) - } - sender.sendMessage(message) - } - - data class Args( - val ip: String, - ) { - class Parser : CommandArgsParser { - override fun parse(args: List): Args { - if (args.isEmpty()) { - throw BadCommandUsageException() - } - return Args(ip = args[0]) - } - } - } -} - -private fun UnbanIP.FailureReason.toMessage(targetIP: String) = - when (this) { - UnbanIP.FailureReason.IP_NOT_BANNED -> "$targetIP is not currently banned" - UnbanIP.FailureReason.INVALID_IP -> "$targetIP is not a valid IP" - } diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/events/ConnectionPermittedEvent.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/events/ConnectionPermittedEvent.kt index b57a9287..eaecaa47 100644 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/events/ConnectionPermittedEvent.kt +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/events/ConnectionPermittedEvent.kt @@ -1,12 +1,12 @@ package com.projectcitybuild.pcbridge.features.bans.events -import com.projectcitybuild.pcbridge.http.responses.Aggregate +import com.projectcitybuild.pcbridge.http.responses.PlayerData import org.bukkit.event.Event import org.bukkit.event.HandlerList import java.util.UUID class ConnectionPermittedEvent( - val aggregate: Aggregate, + val playerData: PlayerData, val playerUUID: UUID, ) : Event() { override fun getHandlers(): HandlerList { diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/listeners/AuthorizeConnectionListener.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/listeners/AuthorizeConnectionListener.kt index 5947dad6..c9690cc7 100644 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/listeners/AuthorizeConnectionListener.kt +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/listeners/AuthorizeConnectionListener.kt @@ -3,13 +3,10 @@ package com.projectcitybuild.pcbridge.features.bans.listeners import com.projectcitybuild.pcbridge.core.datetime.DateTimeFormatter import com.projectcitybuild.pcbridge.core.errors.SentryReporter import com.projectcitybuild.pcbridge.core.logger.log -import com.projectcitybuild.pcbridge.core.state.PlayerState -import com.projectcitybuild.pcbridge.core.state.Store -import com.projectcitybuild.pcbridge.features.bans.Sanitizer -import com.projectcitybuild.pcbridge.features.bans.actions.AuthoriseConnection +import com.projectcitybuild.pcbridge.features.bans.actions.AuthorizeConnection import com.projectcitybuild.pcbridge.features.bans.events.ConnectionPermittedEvent -import com.projectcitybuild.pcbridge.features.bans.repositories.AggregateRepository -import com.projectcitybuild.pcbridge.http.responses.Aggregate +import com.projectcitybuild.pcbridge.features.bans.repositories.PlayerRepository +import com.projectcitybuild.pcbridge.http.responses.PlayerData import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import net.kyori.adventure.text.Component @@ -23,13 +20,12 @@ import java.time.format.FormatStyle import kotlin.coroutines.CoroutineContext class AuthorizeConnectionListener( - private val aggregateRepository: AggregateRepository, - private val authoriseConnection: AuthoriseConnection, + private val playerRepository: PlayerRepository, + private val authorizeConnection: AuthorizeConnection, private val dateTimeFormatter: DateTimeFormatter, private val sentry: SentryReporter, private val server: Server, private val minecraftDispatcher: () -> CoroutineContext, - private val store: Store, ) : Listener { @EventHandler(priority = EventPriority.HIGHEST) suspend fun handle(event: AsyncPlayerPreLoginEvent) { @@ -46,35 +42,27 @@ class AuthorizeConnectionListener( */ runBlocking { runCatching { - val aggregate = - aggregateRepository.get( + val playerData = + playerRepository.get( playerUUID = event.uniqueId, - ip = Sanitizer.sanitizedIP(event.address.toString()), - ) ?: Aggregate() + ip = event.address, + ) ?: PlayerData() - val result = authoriseConnection.execute(aggregate) - if (result is AuthoriseConnection.ConnectResult.Denied) { - event.disallow( + when (val result = authorizeConnection.execute(playerData)) { + is AuthorizeConnection.ConnectResult.Denied -> event.disallow( AsyncPlayerPreLoginEvent.Result.KICK_BANNED, result.ban.toMessage(dateTimeFormatter), ) - return@runBlocking - } - store.mutate { state -> - state.copy( - players = - state.players - .apply { put(event.uniqueId, PlayerState.empty()) }, - ) - } - - withContext(minecraftDispatcher()) { - server.pluginManager.callEvent( - ConnectionPermittedEvent( - aggregate = aggregate, - playerUUID = event.uniqueId, - ), - ) + is AuthorizeConnection.ConnectResult.Allowed -> { + withContext(minecraftDispatcher()) { + server.pluginManager.callEvent( + ConnectionPermittedEvent( + playerData = playerData, + playerUUID = event.uniqueId, + ), + ) + } + } } }.onFailure { log.error(it) { "An error occurred while authorizing a connection" } @@ -90,9 +78,9 @@ class AuthorizeConnectionListener( } } -private fun AuthoriseConnection.Ban.toMessage(dateTimeFormatter: DateTimeFormatter): Component { +private fun AuthorizeConnection.Ban.toMessage(dateTimeFormatter: DateTimeFormatter): Component { return when (this) { - is AuthoriseConnection.Ban.UUID -> + is AuthorizeConnection.Ban.UUID -> MiniMessage.miniMessage().deserialize( """ You are currently banned. @@ -104,7 +92,7 @@ private fun AuthoriseConnection.Ban.toMessage(dateTimeFormatter: DateTimeFormatt """.trimIndent(), ) - is AuthoriseConnection.Ban.IP -> + is AuthorizeConnection.Ban.IP -> MiniMessage.miniMessage().deserialize( """ You are currently IP banned. diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/AggregateRepository.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/AggregateRepository.kt deleted file mode 100644 index d8777a7d..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/AggregateRepository.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.projectcitybuild.pcbridge.features.bans.repositories - -import com.projectcitybuild.pcbridge.http.responses.Aggregate -import com.projectcitybuild.pcbridge.http.services.pcb.AggregateHttpService -import java.util.UUID -import kotlin.jvm.Throws - -class AggregateRepository( - private val httpService: AggregateHttpService, -) { - @Throws(Exception::class) - suspend fun get( - playerUUID: UUID, - ip: String, - ): Aggregate? { - return httpService.get( - playerUUID = playerUUID, - ip = ip, - ) - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/IPBanRepository.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/IPBanRepository.kt deleted file mode 100644 index c7201c32..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/IPBanRepository.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.projectcitybuild.pcbridge.features.bans.repositories - -import com.projectcitybuild.pcbridge.http.responses.IPBan -import com.projectcitybuild.pcbridge.http.services.pcb.IPBanHttpService -import java.util.UUID - -class IPBanRepository( - private val httpService: IPBanHttpService, -) { - suspend fun get(ip: String): IPBan? { - return httpService.get(ip) - } - - @Throws(IPBanHttpService.IPAlreadyBannedException::class) - suspend fun ban( - ip: String, - bannerUUID: UUID?, - bannerName: String, - reason: String, - ) { - httpService.ban( - ip = ip, - bannerUUID = bannerUUID, - bannerName = bannerName, - reason = reason, - ) - } - - @Throws(IPBanHttpService.IPNotBannedException::class) - suspend fun unban( - ip: String, - unbannerUUID: UUID?, - unbannerName: String, - ) { - httpService.unban( - ip = ip, - unbannerUUID = unbannerUUID, - unbannerName = unbannerName, - ) - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/PlayerBanRepository.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/PlayerBanRepository.kt deleted file mode 100644 index 47b21a28..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/PlayerBanRepository.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.projectcitybuild.pcbridge.features.bans.repositories - -import com.projectcitybuild.pcbridge.http.responses.PlayerBan -import com.projectcitybuild.pcbridge.http.services.pcb.UUIDBanHttpService -import java.util.UUID - -class PlayerBanRepository( - private val httpService: UUIDBanHttpService, -) { - suspend fun get(targetPlayerUUID: UUID): PlayerBan? { - return httpService.get(targetPlayerUUID) - } - - @Throws(UUIDBanHttpService.UUIDAlreadyBannedException::class) - suspend fun ban( - targetPlayerUUID: UUID, - targetPlayerName: String, - bannerPlayerUUID: UUID?, - bannerPlayerName: String, - reason: String?, - expiryDate: Long? = null, - ) { - httpService.ban( - targetPlayerUUID = targetPlayerUUID, - targetPlayerName = targetPlayerName, - bannerPlayerUUID = bannerPlayerUUID, - bannerPlayerName = bannerPlayerName, - reason = reason, - expiryDate = expiryDate, - ) - } - - @Throws(UUIDBanHttpService.UUIDNotBannedException::class) - suspend fun unban( - targetPlayerUUID: UUID, - unbannerUUID: UUID?, - ) { - httpService.unban( - targetPlayerUUID = targetPlayerUUID, - unbannerUUID = unbannerUUID, - ) - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/PlayerRepository.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/PlayerRepository.kt new file mode 100644 index 00000000..1c93a9fd --- /dev/null +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/PlayerRepository.kt @@ -0,0 +1,23 @@ +package com.projectcitybuild.pcbridge.features.bans.repositories + +import com.projectcitybuild.pcbridge.features.bans.Sanitizer +import com.projectcitybuild.pcbridge.http.responses.PlayerData +import com.projectcitybuild.pcbridge.http.services.pcb.PlayerHttpService +import java.net.InetAddress +import java.util.UUID +import kotlin.jvm.Throws + +class PlayerRepository( + private val httpService: PlayerHttpService, +) { + @Throws(Exception::class) + suspend fun get( + playerUUID: UUID, + ip: InetAddress, + ): PlayerData? { + return httpService.get( + playerUUID = playerUUID, + ip = Sanitizer.sanitizedIP(ip.toString()), + ) + } +} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/PlayerUUIDRepository.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/PlayerUUIDRepository.kt deleted file mode 100644 index 531411df..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/bans/repositories/PlayerUUIDRepository.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.projectcitybuild.pcbridge.features.bans.repositories - -import com.projectcitybuild.pcbridge.http.responses.MojangPlayer -import com.projectcitybuild.pcbridge.http.services.mojang.PlayerUUIDHttpService -import com.projectcitybuild.pcbridge.utils.extensions.toDashFormattedUUID -import org.bukkit.Server -import java.util.UUID - -open class PlayerUUIDRepository( - private val server: Server, - private val httpService: PlayerUUIDHttpService, -) { - // TODO: cache with expiry time - private val mojangPlayerCache = HashMap() - - suspend fun get(playerName: String): UUID? { - val onlinePlayerUUID = server.getPlayer(playerName)?.uniqueId - if (onlinePlayerUUID != null) { - return onlinePlayerUUID - } - return fetchFromMojang(playerName = playerName)?.let { - UUID.fromString(it.uuid.toDashFormattedUUID()) - } - } - - private suspend fun fetchFromMojang(playerName: String): MojangPlayer? { - val cacheHit = mojangPlayerCache[playerName] - if (cacheHit != null) { - return cacheHit - } - return try { - httpService.get(playerName) - } catch (e: PlayerUUIDHttpService.PlayerNotFoundException) { - null - } - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/chat/listeners/SyncBadgesOnJoinListener.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/chat/listeners/SyncBadgesOnJoinListener.kt deleted file mode 100644 index 054251c7..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/chat/listeners/SyncBadgesOnJoinListener.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.projectcitybuild.pcbridge.features.chat.listeners - -import com.projectcitybuild.pcbridge.core.state.Store -import com.projectcitybuild.pcbridge.features.bans.events.ConnectionPermittedEvent -import org.bukkit.event.EventHandler -import org.bukkit.event.Listener - -class SyncBadgesOnJoinListener( - private val store: Store, -) : Listener { - @EventHandler - suspend fun onConnectionPermitted(event: ConnectionPermittedEvent) { - store.mutate { state -> - val player = - state.players[event.playerUUID]!!.copy( - badges = event.aggregate.badges, - ) - val players = - state.players.apply { - put(event.playerUUID, player) - } - state.copy(players = players) - } - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/joinmessages/listeners/AnnounceJoinListener.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/joinmessages/listeners/AnnounceJoinListener.kt index decd0597..00664030 100644 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/joinmessages/listeners/AnnounceJoinListener.kt +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/joinmessages/listeners/AnnounceJoinListener.kt @@ -1,9 +1,6 @@ package com.projectcitybuild.pcbridge.features.joinmessages.listeners import com.projectcitybuild.pcbridge.core.config.Config -import com.projectcitybuild.pcbridge.core.datetime.LocalizedTime -import com.projectcitybuild.pcbridge.core.state.PlayerState -import com.projectcitybuild.pcbridge.core.state.Store import net.kyori.adventure.text.Component import net.kyori.adventure.text.minimessage.MiniMessage import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder @@ -14,27 +11,14 @@ import org.bukkit.event.player.PlayerJoinEvent class AnnounceJoinListener( private val config: Config, - private val store: Store, - private val time: LocalizedTime, ) : Listener { @EventHandler(priority = EventPriority.NORMAL) - suspend fun onPlayerJoin(event: PlayerJoinEvent) { - store.mutate { state -> - val players = - state.players.also { - it[event.player.uniqueId] = - it - .getOrDefault(event.player.uniqueId, defaultValue = PlayerState.empty()) - .copy(connectedAt = time.now()) - } - state.copy( - players = players, - ) - } + fun onPlayerJoin(event: PlayerJoinEvent) { + val joinMessage = config.get().messages.join event.joinMessage( MiniMessage.miniMessage().deserialize( - config.get().messages.join, + joinMessage, Placeholder.component("name", Component.text(event.player.name)), ), ) diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/joinmessages/listeners/AnnounceQuitListener.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/joinmessages/listeners/AnnounceQuitListener.kt index 07ef65fe..556d8a06 100644 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/joinmessages/listeners/AnnounceQuitListener.kt +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/joinmessages/listeners/AnnounceQuitListener.kt @@ -19,21 +19,16 @@ class AnnounceQuitListener( private val time: LocalizedTime, ) : Listener { @EventHandler(priority = EventPriority.NORMAL) - suspend fun onPlayerQuit(event: PlayerQuitEvent) { + fun onPlayerQuit(event: PlayerQuitEvent) { val playerState = store.state.players[event.player.uniqueId] val joinTime = playerState?.connectedAt ?: time.now() - - store.mutate { state -> - state.copy( - players = state.players.apply { remove(event.player.uniqueId) }, - ) - } - val timeOnline = sessionTime(start = joinTime) + val leaveMessage = config.get().messages.leave + event.quitMessage( MiniMessage.miniMessage().deserialize( - config.get().messages.leave, + leaveMessage, Placeholder.component("name", Component.text(event.player.name)), Placeholder.component("time_online", Component.text(timeOnline)), ), diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/joinmessages/repositories/PlayerConfigRepository.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/joinmessages/repositories/PlayerConfigRepository.kt index 8626bf23..d8bb45da 100644 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/joinmessages/repositories/PlayerConfigRepository.kt +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/joinmessages/repositories/PlayerConfigRepository.kt @@ -18,8 +18,7 @@ class PlayerConfigRepository( connection.prepareStatement("SELECT * FROM players WHERE `uuid`=(?) LIMIT 1") .apply { setString(1, uuid.toString()) } .use { it.executeQuery() } - .use { it.firstRow() } - ?.toPlayerConfig() + .use { it.firstRow()?.toPlayerConfig() } } } diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/mute/commands/MuteCommand.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/mute/commands/MuteCommand.kt deleted file mode 100644 index c6bcbb16..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/mute/commands/MuteCommand.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.projectcitybuild.pcbridge.features.mute.commands - -import com.projectcitybuild.pcbridge.support.messages.CommandHelpBuilder -import com.projectcitybuild.pcbridge.support.spigot.BadCommandUsageException -import com.projectcitybuild.pcbridge.support.spigot.CommandArgsParser -import com.projectcitybuild.pcbridge.support.spigot.SpigotCommand -import io.github.reactivecircus.cache4k.Cache -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.NamedTextColor -import net.kyori.adventure.text.format.TextDecoration -import org.bukkit.Server -import org.bukkit.command.CommandSender -import java.util.UUID - -class MuteCommand( - private val server: Server, - private val mutedPlayers: Cache, -) : SpigotCommand { - override val label = "mute" - - override val usage = CommandHelpBuilder() // TODO - - override suspend fun run( - sender: CommandSender, - args: Args, - ) { - val player = server.getPlayer(args.playerName) - checkNotNull(player) { - "Player ${args.playerName} not found" - } - check(mutedPlayers.get(player.uniqueId) == null) { - "Player ${args.playerName} is already muted" - } - mutedPlayers.put(player.uniqueId, Unit) - - sender.sendMessage( - Component.text("Player ${args.playerName} has been muted") - .color(NamedTextColor.GRAY) - .decorate(TextDecoration.ITALIC), - ) - - player.sendMessage( - Component.text("You have been muted") - .color(NamedTextColor.RED) - .decorate(TextDecoration.ITALIC), - ) - } - - data class Args( - val playerName: String, - ) { - class Parser : CommandArgsParser { - override fun parse(args: List): Args { - if (args.isEmpty()) { - throw BadCommandUsageException() - } - return Args(playerName = args[0]) - } - } - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/mute/commands/UnmuteCommand.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/mute/commands/UnmuteCommand.kt deleted file mode 100644 index 20d2144c..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/mute/commands/UnmuteCommand.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.projectcitybuild.pcbridge.features.mute.commands - -import com.projectcitybuild.pcbridge.support.messages.CommandHelpBuilder -import com.projectcitybuild.pcbridge.support.spigot.BadCommandUsageException -import com.projectcitybuild.pcbridge.support.spigot.CommandArgsParser -import com.projectcitybuild.pcbridge.support.spigot.SpigotCommand -import io.github.reactivecircus.cache4k.Cache -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.NamedTextColor -import net.kyori.adventure.text.format.TextDecoration -import org.bukkit.Server -import org.bukkit.command.CommandSender -import java.util.UUID - -class UnmuteCommand( - private val server: Server, - private val mutedPlayers: Cache, -) : SpigotCommand { - override val label = "unmute" - - override val usage = CommandHelpBuilder() // TODO - - override suspend fun run( - sender: CommandSender, - args: Args, - ) { - val player = server.getPlayer(args.playerName) - checkNotNull(player) { - "Player ${args.playerName} not found" - } - check(mutedPlayers.get(player.uniqueId) != null) { - "Player ${args.playerName} is not currently muted" - } - mutedPlayers.invalidate(player.uniqueId) - - sender.sendMessage( - Component.text("Player ${args.playerName} has been unmuted") - .color(NamedTextColor.GRAY) - .decorate(TextDecoration.ITALIC), - ) - - player.sendMessage( - Component.text("You have been unmuted") - .color(NamedTextColor.LIGHT_PURPLE) - .decorate(TextDecoration.ITALIC), - ) - } - - data class Args( - val playerName: String, - ) { - class Parser : CommandArgsParser { - override fun parse(args: List): Args { - if (args.isEmpty()) { - throw BadCommandUsageException() - } - return Args(playerName = args[0]) - } - } - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/mute/listeners/MuteChatListener.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/mute/listeners/MuteChatListener.kt deleted file mode 100644 index d7bd2184..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/mute/listeners/MuteChatListener.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.projectcitybuild.pcbridge.features.mute.listeners - -import io.github.reactivecircus.cache4k.Cache -import io.papermc.paper.event.player.AsyncChatEvent -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.NamedTextColor -import org.bukkit.event.EventHandler -import org.bukkit.event.EventPriority -import org.bukkit.event.Listener -import java.util.UUID - -class MuteChatListener( - private val mutedPlayers: Cache, -) : Listener { - @EventHandler(priority = EventPriority.HIGHEST) - fun onChat(event: AsyncChatEvent) { - if (mutedPlayers.get(event.player.uniqueId) != null) { - event.isCancelled = true - event.player.sendMessage( - Component.text("You cannot talk while muted") - .color(NamedTextColor.RED), - ) - } - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/playerstate/events/PlayerStateCreatedEvent.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/playerstate/events/PlayerStateCreatedEvent.kt new file mode 100644 index 00000000..d493e3c0 --- /dev/null +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/playerstate/events/PlayerStateCreatedEvent.kt @@ -0,0 +1,22 @@ +package com.projectcitybuild.pcbridge.features.playerstate.events + +import com.projectcitybuild.pcbridge.http.responses.PlayerData +import org.bukkit.event.Event +import org.bukkit.event.HandlerList +import java.util.UUID + +class PlayerStateCreatedEvent( + val playerData: PlayerData, + val playerUUID: UUID, +) : Event() { + override fun getHandlers(): HandlerList { + return HANDLERS + } + + companion object { + private val HANDLERS = HandlerList() + + @JvmStatic + fun getHandlerList() = HANDLERS + } +} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/playerstate/events/PlayerStateDestroyedEvent.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/playerstate/events/PlayerStateDestroyedEvent.kt new file mode 100644 index 00000000..d58dd69f --- /dev/null +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/playerstate/events/PlayerStateDestroyedEvent.kt @@ -0,0 +1,22 @@ +package com.projectcitybuild.pcbridge.features.playerstate.events + +import com.projectcitybuild.pcbridge.core.state.PlayerState +import org.bukkit.event.Event +import org.bukkit.event.HandlerList +import java.util.UUID + +class PlayerStateDestroyedEvent( + val playerData: PlayerState?, + val playerUUID: UUID, +) : Event() { + override fun getHandlers(): HandlerList { + return HANDLERS + } + + companion object { + private val HANDLERS = HandlerList() + + @JvmStatic + fun getHandlerList() = HANDLERS + } +} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/playerstate/listeners/PlayerStateListener.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/playerstate/listeners/PlayerStateListener.kt new file mode 100644 index 00000000..2f258ad0 --- /dev/null +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/playerstate/listeners/PlayerStateListener.kt @@ -0,0 +1,77 @@ +package com.projectcitybuild.pcbridge.features.playerstate.listeners + +import com.projectcitybuild.pcbridge.core.datetime.LocalizedTime +import com.projectcitybuild.pcbridge.core.logger.log +import com.projectcitybuild.pcbridge.core.state.PlayerState +import com.projectcitybuild.pcbridge.core.state.Store +import com.projectcitybuild.pcbridge.features.bans.events.ConnectionPermittedEvent +import com.projectcitybuild.pcbridge.features.playerstate.events.PlayerStateCreatedEvent +import com.projectcitybuild.pcbridge.features.playerstate.events.PlayerStateDestroyedEvent +import kotlinx.coroutines.withContext +import org.bukkit.Server +import org.bukkit.event.EventHandler +import org.bukkit.event.EventPriority +import org.bukkit.event.Listener +import org.bukkit.event.player.PlayerQuitEvent +import kotlin.coroutines.CoroutineContext + +/** + * Listens to connection events and creates/destroys the connecting player's state + */ +class PlayerStateListener( + private val store: Store, + private val server: Server, + private val time: LocalizedTime, + private val minecraftDispatcher: () -> CoroutineContext, +) : Listener { + /** + * Creates a PlayerState for the connecting user + */ + @EventHandler + suspend fun onConnectionPermitted(event: ConnectionPermittedEvent) { + log.info { "Creating player state for ${event.playerUUID}" } + + val data = event.playerData + val playerState = PlayerState( + connectedAt = time.now(), + account = data.account, + badges = data.badges, + donationPerks = data.donationPerks, + ) + store.mutate { state -> + state.copy(players = state.players.apply { put(event.playerUUID, playerState) }) + } + withContext(minecraftDispatcher()) { + server.pluginManager.callEvent( + PlayerStateCreatedEvent( + playerData = event.playerData, + playerUUID = event.playerUUID, + ), + ) + } + } + + /** + * Destroys PlayerState for the disconnecting user. + * + * Note: Runs at highest priority so that it's invoked last + */ + @EventHandler(priority = EventPriority.HIGHEST) + suspend fun onPlayerQuit(event: PlayerQuitEvent) { + val uuid = event.player.uniqueId + log.info { "Destroying player state for $uuid" } + val prevState = store.state.players[uuid] + + store.mutate { state -> + state.copy(players = state.players.apply { remove(uuid) }) + } + withContext(minecraftDispatcher()) { + server.pluginManager.callEvent( + PlayerStateDestroyedEvent( + playerData = prevState, + playerUUID = uuid, + ), + ) + } + } +} \ No newline at end of file diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/actions/GenerateAccountVerificationURL.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/actions/GenerateAccountVerificationURL.kt deleted file mode 100644 index 77b02379..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/actions/GenerateAccountVerificationURL.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.projectcitybuild.pcbridge.features.sync.actions - -import com.projectcitybuild.pcbridge.features.sync.repositories.SyncRepository -import com.projectcitybuild.pcbridge.http.services.pcb.AccountLinkHTTPService -import com.projectcitybuild.pcbridge.utils.Failure -import com.projectcitybuild.pcbridge.utils.Result -import com.projectcitybuild.pcbridge.utils.Success -import java.util.UUID - -class GenerateAccountVerificationURL( - private val syncRepository: SyncRepository, -) { - data class VerificationURL(val urlString: String) - - enum class FailureReason { - ALREADY_LINKED, - EMPTY_RESPONSE, - } - - suspend fun generate(playerUUID: UUID): Result { - return try { - val url = syncRepository.generateVerificationURL(playerUUID) - - return if (url.isNullOrEmpty()) { - Failure(FailureReason.EMPTY_RESPONSE) - } else { - Success(VerificationURL(url)) - } - } catch (e: AccountLinkHTTPService.AlreadyLinkedException) { - Failure(FailureReason.ALREADY_LINKED) - } - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/actions/UpdatePlayerGroups.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/actions/UpdatePlayerGroups.kt index def0e2bb..8105c8ba 100644 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/actions/UpdatePlayerGroups.kt +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/actions/UpdatePlayerGroups.kt @@ -1,36 +1,35 @@ -package com.projectcitybuild.pcbridge.features.sync.actions - -import com.projectcitybuild.pcbridge.core.permissions.Permissions -import com.projectcitybuild.pcbridge.features.sync.repositories.SyncRepository -import com.projectcitybuild.pcbridge.http.services.pcb.PlayerGroupHttpService -import com.projectcitybuild.pcbridge.utils.Failure -import com.projectcitybuild.pcbridge.utils.Result -import com.projectcitybuild.pcbridge.utils.Success -import java.util.UUID - -class UpdatePlayerGroups( - private val permissions: Permissions, - private val syncRepository: SyncRepository, -) { - enum class FailureReason { - ACCOUNT_NOT_LINKED, - } - - suspend fun execute(playerUUID: UUID): Result { - val groupSet = mutableSetOf() - - try { - groupSet.addAll(syncRepository.getGroups(playerUUID = playerUUID)) - - val donorPerks = syncRepository.getDonorPerks(playerUUID) - val donorTierGroups = syncRepository.getDonorTiers(donorPerks) - groupSet.addAll(donorTierGroups) - } catch (e: PlayerGroupHttpService.NoLinkedAccountException) { - return Failure(FailureReason.ACCOUNT_NOT_LINKED) - } - - permissions.setUserGroups(playerUUID, groupSet.toList()) - - return Success(Unit) - } -} +// package com.projectcitybuild.pcbridge.features.sync.actions +// +// import com.projectcitybuild.pcbridge.core.permissions.Permissions +// import com.projectcitybuild.pcbridge.features.sync.repositories.SyncRepository +// import com.projectcitybuild.pcbridge.utils.Failure +// import com.projectcitybuild.pcbridge.utils.Result +// import com.projectcitybuild.pcbridge.utils.Success +// import java.util.UUID +// +// class UpdatePlayerGroups( +// private val permissions: Permissions, +// private val syncRepository: SyncRepository, +// ) { +// enum class FailureReason { +// ACCOUNT_NOT_LINKED, +// } +// +// suspend fun execute(playerUUID: UUID): Result { +// val groupSet = mutableSetOf() +// +// try { +// groupSet.addAll(syncRepository.getGroups(playerUUID = playerUUID)) +// +// val donorPerks = syncRepository.getDonorPerks(playerUUID) +// val donorTierGroups = syncRepository.getDonorTiers(donorPerks) +// groupSet.addAll(donorTierGroups) +// } catch (e: PlayerGroupHttpService.NoLinkedAccountException) { +// return Failure(FailureReason.ACCOUNT_NOT_LINKED) +// } +// +// permissions.setUserGroups(playerUUID, groupSet.toList()) +// +// return Success(Unit) +// } +// } diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/commands/SyncCommand.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/commands/SyncCommand.kt index b574ce1a..a4c09c13 100644 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/commands/SyncCommand.kt +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/commands/SyncCommand.kt @@ -1,24 +1,13 @@ package com.projectcitybuild.pcbridge.features.sync.commands -import com.projectcitybuild.pcbridge.features.sync.actions.GenerateAccountVerificationURL -import com.projectcitybuild.pcbridge.features.sync.actions.UpdatePlayerGroups import com.projectcitybuild.pcbridge.support.messages.CommandHelpBuilder import com.projectcitybuild.pcbridge.support.spigot.BadCommandUsageException import com.projectcitybuild.pcbridge.support.spigot.CommandArgsParser import com.projectcitybuild.pcbridge.support.spigot.SpigotCommand -import com.projectcitybuild.pcbridge.utils.Failure -import com.projectcitybuild.pcbridge.utils.Success -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.event.ClickEvent -import net.kyori.adventure.text.event.HoverEvent -import net.kyori.adventure.text.format.NamedTextColor -import net.kyori.adventure.text.format.TextDecoration import org.bukkit.command.CommandSender import org.bukkit.entity.Player class SyncCommand( - private val generateAccountVerificationURL: GenerateAccountVerificationURL, - private val updatePlayerGroups: UpdatePlayerGroups, ) : SpigotCommand { override val label = "sync" @@ -31,66 +20,7 @@ class SyncCommand( check(sender is Player) { "Only players can use this command" } - when (args.finishSyncing) { - false -> generateVerificationURL(sender) - true -> syncGroups(sender) - } - } - - private suspend fun generateVerificationURL(player: Player) { - val result = generateAccountVerificationURL.generate(player.uniqueId) - - when (result) { - is Failure -> - when (result.reason) { - GenerateAccountVerificationURL.FailureReason.ALREADY_LINKED, - -> syncGroups(player) - - GenerateAccountVerificationURL.FailureReason.EMPTY_RESPONSE, - -> - player.sendMessage( - Component.text("Failed to generate verification URL: No URL received from server") - .color(NamedTextColor.RED), - ) - } - is Success -> - player.sendMessage( - Component.text() - .append( - Component.text("To link your account, please "), - ) - .append( - Component.text("click here") - .decorate(TextDecoration.UNDERLINED) - .decorate(TextDecoration.BOLD) - .clickEvent(ClickEvent.openUrl(result.value.urlString)) - .hoverEvent(HoverEvent.showText(Component.text(result.value.urlString))), - ) - .append( - Component.text(" and login if required"), - ), - ) - } - } - - private suspend fun syncGroups(player: Player) { - val result = updatePlayerGroups.execute(player.uniqueId) - - val message = - when (result) { - is Failure -> - when (result.reason) { - UpdatePlayerGroups.FailureReason.ACCOUNT_NOT_LINKED, - -> - Component.text("Sync failed. Did you finish registering your account?") - .color(NamedTextColor.RED) - } - is Success -> { - Component.text("Account linked! Your rank will be automatically synchronized with the PCB network") - .color(NamedTextColor.GREEN) - } - } - player.sendMessage(message) + // TODO } data class Args( diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/commands/SyncOtherCommand.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/commands/SyncOtherCommand.kt index d6e561b8..a5912b2c 100644 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/commands/SyncOtherCommand.kt +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/commands/SyncOtherCommand.kt @@ -1,70 +1,70 @@ -package com.projectcitybuild.pcbridge.features.sync.commands - -import com.projectcitybuild.pcbridge.features.sync.actions.UpdatePlayerGroups -import com.projectcitybuild.pcbridge.support.messages.CommandHelpBuilder -import com.projectcitybuild.pcbridge.support.spigot.BadCommandUsageException -import com.projectcitybuild.pcbridge.support.spigot.CommandArgsParser -import com.projectcitybuild.pcbridge.support.spigot.SpigotCommand -import com.projectcitybuild.pcbridge.utils.Failure -import com.projectcitybuild.pcbridge.utils.Success -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.NamedTextColor -import net.kyori.adventure.text.format.TextDecoration -import org.bukkit.Server -import org.bukkit.command.CommandSender - -class SyncOtherCommand( - private val server: Server, - private val updatePlayerGroups: UpdatePlayerGroups, -) : SpigotCommand { - override val label = "syncother" - - override val usage = CommandHelpBuilder() - - override suspend fun run( - sender: CommandSender, - args: Args, - ) { - val targetPlayer = server.getPlayer(args.targetPlayerName) - checkNotNull(targetPlayer) { - "Player ${args.targetPlayerName} not found" - } - val result = updatePlayerGroups.execute(targetPlayer.uniqueId) - when (result) { - is Failure -> - when (result.reason) { - UpdatePlayerGroups.FailureReason.ACCOUNT_NOT_LINKED, - -> - sender.sendMessage( - Component.text("Error: Player does not have a linked PCB account") - .color(NamedTextColor.RED), - ) - } - is Success -> { - sender.sendMessage( - Component.text("${targetPlayer.name} has been synchronized") - .color(NamedTextColor.GRAY) - .decorate(TextDecoration.ITALIC), - ) - targetPlayer.sendMessage( - Component.text("Your rank has been synchronized") - .color(NamedTextColor.GRAY) - .decorate(TextDecoration.ITALIC), - ) - } - } - } - - data class Args( - val targetPlayerName: String, - ) { - class Parser : CommandArgsParser { - override fun parse(args: List): Args { - if (args.isEmpty() || args.size > 1) { - throw BadCommandUsageException() - } - return Args(targetPlayerName = args[0]) - } - } - } -} +// package com.projectcitybuild.pcbridge.features.sync.commands +// +// import com.projectcitybuild.pcbridge.features.sync.actions.UpdatePlayerGroups +// import com.projectcitybuild.pcbridge.support.messages.CommandHelpBuilder +// import com.projectcitybuild.pcbridge.support.spigot.BadCommandUsageException +// import com.projectcitybuild.pcbridge.support.spigot.CommandArgsParser +// import com.projectcitybuild.pcbridge.support.spigot.SpigotCommand +// import com.projectcitybuild.pcbridge.utils.Failure +// import com.projectcitybuild.pcbridge.utils.Success +// import net.kyori.adventure.text.Component +// import net.kyori.adventure.text.format.NamedTextColor +// import net.kyori.adventure.text.format.TextDecoration +// import org.bukkit.Server +// import org.bukkit.command.CommandSender +// +// class SyncOtherCommand( +// private val server: Server, +// private val updatePlayerGroups: UpdatePlayerGroups, +// ) : SpigotCommand { +// override val label = "syncother" +// +// override val usage = CommandHelpBuilder() +// +// override suspend fun run( +// sender: CommandSender, +// args: Args, +// ) { +// val targetPlayer = server.getPlayer(args.targetPlayerName) +// checkNotNull(targetPlayer) { +// "Player ${args.targetPlayerName} not found" +// } +// val result = updatePlayerGroups.execute(targetPlayer.uniqueId) +// when (result) { +// is Failure -> +// when (result.reason) { +// UpdatePlayerGroups.FailureReason.ACCOUNT_NOT_LINKED, +// -> +// sender.sendMessage( +// Component.text("Error: Player does not have a linked PCB account") +// .color(NamedTextColor.RED), +// ) +// } +// is Success -> { +// sender.sendMessage( +// Component.text("${targetPlayer.name} has been synchronized") +// .color(NamedTextColor.GRAY) +// .decorate(TextDecoration.ITALIC), +// ) +// targetPlayer.sendMessage( +// Component.text("Your rank has been synchronized") +// .color(NamedTextColor.GRAY) +// .decorate(TextDecoration.ITALIC), +// ) +// } +// } +// } +// +// data class Args( +// val targetPlayerName: String, +// ) { +// class Parser : CommandArgsParser { +// override fun parse(args: List): Args { +// if (args.isEmpty() || args.size > 1) { +// throw BadCommandUsageException() +// } +// return Args(targetPlayerName = args[0]) +// } +// } +// } +// } diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/listener/SyncRankOnJoinListener.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/listener/SyncRankOnJoinListener.kt index b15db567..e79af6a7 100644 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/listener/SyncRankOnJoinListener.kt +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/listener/SyncRankOnJoinListener.kt @@ -1,6 +1,6 @@ package com.projectcitybuild.pcbridge.features.sync.listener -import com.projectcitybuild.pcbridge.features.bans.events.ConnectionPermittedEvent +import com.projectcitybuild.pcbridge.features.playerstate.events.PlayerStateCreatedEvent import com.projectcitybuild.pcbridge.features.sync.actions.SyncPlayerGroups import org.bukkit.event.EventHandler import org.bukkit.event.Listener @@ -9,11 +9,11 @@ class SyncRankOnJoinListener( private val syncPlayerGroups: SyncPlayerGroups, ) : Listener { @EventHandler - fun onConnectionPermitted(event: ConnectionPermittedEvent) { + fun onPlayerStateCreated(event: PlayerStateCreatedEvent) { syncPlayerGroups.execute( playerUUID = event.playerUUID, - groups = event.aggregate.account?.groups ?: emptyList(), - donationPerks = event.aggregate.donationPerks, + groups = event.playerData.account?.groups ?: emptyList(), + donationPerks = event.playerData.donationPerks, ) } } diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/repositories/SyncRepository.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/repositories/SyncRepository.kt index 15110f2b..ac5b77a3 100644 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/repositories/SyncRepository.kt +++ b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/sync/repositories/SyncRepository.kt @@ -3,26 +3,10 @@ package com.projectcitybuild.pcbridge.features.sync.repositories import com.projectcitybuild.pcbridge.core.config.Config import com.projectcitybuild.pcbridge.core.logger.log import com.projectcitybuild.pcbridge.http.responses.DonationPerk -import com.projectcitybuild.pcbridge.http.services.pcb.AccountLinkHTTPService -import com.projectcitybuild.pcbridge.http.services.pcb.PlayerGroupHttpService -import java.util.UUID class SyncRepository( - private val playerGroupHttpService: PlayerGroupHttpService, - private val accountLinkHttpService: AccountLinkHTTPService, private val config: Config, ) { - @Throws(PlayerGroupHttpService.NoLinkedAccountException::class) - suspend fun getGroups(playerUUID: UUID): List { - return playerGroupHttpService.getGroups(playerUUID) - .mapNotNull { it.minecraftName } - } - - @Throws(PlayerGroupHttpService.NoLinkedAccountException::class) - suspend fun getDonorPerks(playerUUID: UUID): List { - return playerGroupHttpService.getDonorPerks(playerUUID) - } - fun getDonorTiers(perks: List): List { return perks.mapNotNull { donorPerk -> val tierName = donorPerk.donationTier.name @@ -39,9 +23,4 @@ class SyncRepository( } } } - - @Throws(AccountLinkHTTPService.AlreadyLinkedException::class) - suspend fun generateVerificationURL(playerUUID: UUID): String? { - return accountLinkHttpService.generateVerificationURL(playerUUID) - } } diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/warnings/actions/GetUnacknowledgedWarnings.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/warnings/actions/GetUnacknowledgedWarnings.kt deleted file mode 100644 index 4f62c5f3..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/warnings/actions/GetUnacknowledgedWarnings.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.projectcitybuild.pcbridge.features.warnings.actions - -import com.projectcitybuild.pcbridge.core.datetime.DateTimeFormatter -import com.projectcitybuild.pcbridge.features.warnings.repositories.PlayerWarningRepository -import java.util.UUID - -class GetUnacknowledgedWarnings( - private val warningRepository: PlayerWarningRepository, - private val dateTimeFormatter: DateTimeFormatter, -) { - data class FormattedWarning( - val id: Int, - val reason: String, - val isAcknowledged: Boolean, - val createdAt: String, - ) - - suspend fun execute( - playerUUID: UUID, - playerName: String, - ): List { - return warningRepository - .get(playerUUID, playerName) - .filter { !it.isAcknowledged } - .map { - FormattedWarning( - id = it.id, - reason = it.reason, - isAcknowledged = it.isAcknowledged, - createdAt = - it.createdAt.let { createdAt -> - dateTimeFormatter.convert(createdAt) - }, - ) - } - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/warnings/commands/WarningAcknowledgeCommand.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/warnings/commands/WarningAcknowledgeCommand.kt deleted file mode 100644 index 3167148d..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/warnings/commands/WarningAcknowledgeCommand.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.projectcitybuild.pcbridge.features.warnings.commands - -import com.projectcitybuild.pcbridge.features.warnings.repositories.PlayerWarningRepository -import com.projectcitybuild.pcbridge.support.messages.CommandHelpBuilder -import com.projectcitybuild.pcbridge.support.spigot.BadCommandUsageException -import com.projectcitybuild.pcbridge.support.spigot.CommandArgsParser -import com.projectcitybuild.pcbridge.support.spigot.SpigotCommand -import org.bukkit.command.CommandSender - -class WarningAcknowledgeCommand( - private val warningRepository: PlayerWarningRepository, -) : SpigotCommand { - override val label = "warning" - - override val usage = CommandHelpBuilder() - - override suspend fun run( - sender: CommandSender, - args: Args, - ) { - warningRepository.acknowledge(args.id) - sender.sendMessage("Warning acknowledged and hidden") - } - - data class Args( - val id: Int, - ) { - class Parser : CommandArgsParser { - override fun parse(args: List): Args { - if (args.isEmpty()) { - throw BadCommandUsageException() - } - return Args(id = args[0].toInt()) - } - } - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/warnings/listeners/NotifyWarningsOnJoinListener.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/warnings/listeners/NotifyWarningsOnJoinListener.kt deleted file mode 100644 index e7d95899..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/warnings/listeners/NotifyWarningsOnJoinListener.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.projectcitybuild.pcbridge.features.warnings.listeners - -import com.projectcitybuild.pcbridge.features.warnings.actions.GetUnacknowledgedWarnings -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.event.ClickEvent -import net.kyori.adventure.text.format.NamedTextColor -import net.kyori.adventure.text.format.TextDecoration -import org.bukkit.event.EventHandler -import org.bukkit.event.Listener -import org.bukkit.event.player.PlayerJoinEvent - -class NotifyWarningsOnJoinListener( - private val getUnacknowledgedWarnings: GetUnacknowledgedWarnings, -) : Listener { - @EventHandler - suspend fun onPlayerJoin(event: PlayerJoinEvent) { - val player = event.player - val warnings = - getUnacknowledgedWarnings.execute( - playerUUID = player.uniqueId, - playerName = player.name, - ) - if (warnings.isEmpty()) { - return - } - - val message = - Component.text() - .append( - Component.text("You have ").color(NamedTextColor.RED), - Component.text(warnings.size).decorate(TextDecoration.BOLD), - Component.text(" unacknowledged warnings").color(NamedTextColor.RED), - Component.newline(), - Component.text("---").color(NamedTextColor.GRAY), - Component.newline(), - ) - - warnings.forEach { warning -> - message.append( - Component.text(warning.reason), - Component.newline(), - Component.text("Date: ").color(NamedTextColor.GRAY), - Component.text(warning.createdAt), - Component.newline(), - Component.newline(), - Component.text("[I ACKNOWLEDGE]") - .color(NamedTextColor.GOLD) - .decorate(TextDecoration.BOLD, TextDecoration.UNDERLINED) - .clickEvent(ClickEvent.runCommand("/warning acknowledge ${warning.id}")), - Component.newline(), - Component.text("---").color(NamedTextColor.GRAY), - Component.newline(), - ) - } - message.append( - Component.text("Click the 'acknowledge' button to mark it as read and hide it") - .color(NamedTextColor.GRAY) - .decorate(TextDecoration.ITALIC), - ) - player.sendMessage(message) - } -} diff --git a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/warnings/repositories/PlayerWarningRepository.kt b/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/warnings/repositories/PlayerWarningRepository.kt deleted file mode 100644 index 8f5b0fef..00000000 --- a/pcbridge-spigot/src/main/kotlin/com/projectcitybuild/pcbridge/features/warnings/repositories/PlayerWarningRepository.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.projectcitybuild.pcbridge.features.warnings.repositories - -import com.projectcitybuild.pcbridge.http.responses.PlayerWarning -import com.projectcitybuild.pcbridge.http.services.pcb.PlayerWarningHttpService -import java.util.UUID - -class PlayerWarningRepository( - private val playerWarningHttpService: PlayerWarningHttpService, -) { - suspend fun get( - playerUUID: UUID, - playerName: String, - ): List { - return playerWarningHttpService.get( - playerUUID = playerUUID, - playerName = playerName, - ) - } - - suspend fun acknowledge(warningId: Int): PlayerWarning? { - return playerWarningHttpService.acknowledge(warningId) - } -} diff --git a/pcbridge-spigot/src/main/resources/plugin.yml b/pcbridge-spigot/src/main/resources/plugin.yml index a925142e..75568d5d 100644 --- a/pcbridge-spigot/src/main/resources/plugin.yml +++ b/pcbridge-spigot/src/main/resources/plugin.yml @@ -2,7 +2,7 @@ name: PCBridge main: com.projectcitybuild.pcbridge.Plugin website: https://github.com/projectcitybuild/PCBridge author: Andy -version: 6.0.0 +version: 6.1.0 api-version: 1.20 softdepend: @@ -17,10 +17,6 @@ commands: permission: pcbridge.ban.ban banip: permission: pcbridge.ban.banip - checkban: - permission: pcbridge.ban.check - mute: - permission: pcbridge.chat.mute pcbridge: permission: pcbridge.utils invisframe: @@ -29,17 +25,7 @@ commands: permission: pcbridge.build.nightvision sync: permission: pcbridge.sync.login - syncother: - permission: pcbridge.sync.other - unban: - permission: pcbridge.ban.ban - unbanip: - permission: pcbridge.ban.banip - unmute: - permission: pcbridge.chat.mute warp: permission: pcbridge.warps.teleport warps: - permission: pcbridge.warps.list - warning: - permission: pcbridge.warning.acknowledge \ No newline at end of file + permission: pcbridge.warps.list \ No newline at end of file diff --git a/pcbridge-spigot/test/com/projectcitybuild/pcbridge/features/bans/actions/AuthoriseConnectionTest.kt b/pcbridge-spigot/test/com/projectcitybuild/pcbridge/features/bans/actions/AuthorizeConnectionTest.kt similarity index 70% rename from pcbridge-spigot/test/com/projectcitybuild/pcbridge/features/bans/actions/AuthoriseConnectionTest.kt rename to pcbridge-spigot/test/com/projectcitybuild/pcbridge/features/bans/actions/AuthorizeConnectionTest.kt index 3530c074..8501cdf2 100644 --- a/pcbridge-spigot/test/com/projectcitybuild/pcbridge/features/bans/actions/AuthoriseConnectionTest.kt +++ b/pcbridge-spigot/test/com/projectcitybuild/pcbridge/features/bans/actions/AuthorizeConnectionTest.kt @@ -1,6 +1,6 @@ package com.projectcitybuild.pcbridge.features.bans.actions -import com.projectcitybuild.pcbridge.http.responses.Aggregate +import com.projectcitybuild.pcbridge.http.responses.PlayerData import com.projectcitybuild.pcbridge.http.responses.IPBan import com.projectcitybuild.pcbridge.http.responses.PlayerBan import kotlinx.coroutines.test.runTest @@ -10,12 +10,12 @@ import org.junit.jupiter.api.Test import java.time.LocalDate import java.time.ZoneId -class AuthoriseConnectionTest { - private lateinit var useCase: AuthoriseConnection +class AuthorizeConnectionTest { + private lateinit var useCase: AuthorizeConnection @BeforeEach fun setUp() { - useCase = AuthoriseConnection() + useCase = AuthorizeConnection() } @Test @@ -24,11 +24,11 @@ class AuthoriseConnectionTest { val ban = PlayerBan() val result = useCase.execute( - Aggregate(playerBan = ban), + PlayerData(playerBan = ban), ) assertEquals( - AuthoriseConnection.ConnectResult.Denied( - AuthoriseConnection.Ban.UUID(ban), + AuthorizeConnection.ConnectResult.Denied( + AuthorizeConnection.Ban.UUID(ban), ), result, ) @@ -43,10 +43,10 @@ class AuthoriseConnectionTest { ) val result = useCase.execute( - Aggregate(playerBan = ban), + PlayerData(playerBan = ban), ) assertEquals( - AuthoriseConnection.ConnectResult.Allowed, + AuthorizeConnection.ConnectResult.Allowed, result, ) } @@ -57,11 +57,11 @@ class AuthoriseConnectionTest { val ban = IPBan() val result = useCase.execute( - Aggregate(ipBan = ban), + PlayerData(ipBan = ban), ) assertEquals( - AuthoriseConnection.ConnectResult.Denied( - AuthoriseConnection.Ban.IP(ban), + AuthorizeConnection.ConnectResult.Denied( + AuthorizeConnection.Ban.IP(ban), ), result, ) @@ -76,10 +76,10 @@ class AuthoriseConnectionTest { ) val result = useCase.execute( - Aggregate(ipBan = ban), + PlayerData(ipBan = ban), ) assertEquals( - AuthoriseConnection.ConnectResult.Allowed, + AuthorizeConnection.ConnectResult.Allowed, result, ) } @@ -89,10 +89,10 @@ class AuthoriseConnectionTest { runTest { val result = useCase.execute( - Aggregate(playerBan = null, ipBan = null), + PlayerData(playerBan = null, ipBan = null), ) assertEquals( - AuthoriseConnection.ConnectResult.Allowed, + AuthorizeConnection.ConnectResult.Allowed, result, ) }