diff --git a/build.gradle.kts b/build.gradle.kts index 6264480..1eb412c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,20 +1,14 @@ -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion plugins { - kotlin("jvm") version "1.8.0" - id("com.github.johnrengelman.shadow") version "8.1.1" - java + alias(libs.plugins.kotlin) + alias(libs.plugins.shadow) } allprojects { group = "app.simplecloud.plugin" - version = "1.0-SNAPSHOT" - - apply { - plugin("java") - plugin("org.jetbrains.kotlin.jvm") - plugin("com.github.johnrengelman.shadow") - } + version = "1.1-SNAPSHOT" repositories { mavenCentral() @@ -23,30 +17,47 @@ allprojects { maven("https://oss.sonatype.org/content/repositories/central") maven("https://repo.papermc.io/repository/maven-public/") maven("https://jitpack.io") + maven("https://repo.dmulloy2.net/repository/public/") } +} - kotlin { - jvmToolchain(17) +subprojects { + + apply { + plugin("org.jetbrains.kotlin.jvm") + plugin("com.gradleup.shadow") } dependencies { + compileOnly(rootProject.libs.kotlin.jvm) + compileOnly(rootProject.libs.kotlin.test) + compileOnly("net.luckperms:api:5.4") + compileOnly("space.chunks.custom-names:custom-names-api:1.0.6") implementation("net.kyori:adventure-api:4.14.0") implementation("com.google.code.gson:gson:2.10.1") implementation("net.kyori:adventure-text-minimessage:4.14.0") } -} -subprojects { - dependencies { - implementation(kotlin("stdlib")) + java { + toolchain.languageVersion.set(JavaLanguageVersion.of(21)) + } + + tasks.test { + useJUnitPlatform() } - tasks.withType { - kotlinOptions.jvmTarget = "17" + kotlin { + jvmToolchain(21) + compilerOptions { + jvmTarget = JvmTarget.JVM_21 + languageVersion = KotlinVersion.KOTLIN_2_0 + apiVersion = KotlinVersion.KOTLIN_2_0 + } } - tasks.named("shadowJar", ShadowJar::class) { + tasks.shadowJar { mergeServiceFiles() + archiveFileName.set("${project.name}.jar") } } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..c74196c --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,15 @@ +[versions] +kotlin = "2.0.20" +shadow = "8.3.3" +paper-api = "1.21.4-R0.1-SNAPSHOT" +paperweight = "2.0.0-beta.12" + +[libraries] +kotlin-jvm = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } +kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } +paper-api = { module = "io.papermc.paper:paper-api", version.ref = "paper-api" } + +[plugins] +paperweight-userdev = { id = "io.papermc.paperweight.userdev", version.ref = "paperweight" } +kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } +shadow = { id = "com.gradleup.shadow", version.ref = "shadow" } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 06febab..348fbf3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists \ No newline at end of file diff --git a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesActor.kt b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesActor.kt index 9a95beb..4b58d54 100644 --- a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesActor.kt +++ b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesActor.kt @@ -1,18 +1,18 @@ package app.simplecloud.plugin.prefixes.api import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.TextColor import java.util.* interface PrefixesActor { - fun applyGroup(target: UUID, group: PrefixesGroup) - - fun setPrefix(target: UUID, prefix: Component) - - fun setSuffix(target: UUID, suffix: Component) - - fun setColor(target: UUID, color: String) - - fun formatMessage(target: UUID, format: String, message: Component): Component - + fun registerViewer(target: UUID, api: PrefixesApi) + fun hasViewer(target: UUID): Boolean + fun removeViewer(target: UUID) + fun applyGroup(target: UUID, group: PrefixesGroup, vararg viewers: UUID) + fun setPrefix(target: UUID, prefix: Component, vararg viewers: UUID) + fun setSuffix(target: UUID, suffix: Component, vararg viewers: UUID) + fun setColor(target: UUID, color: TextColor, vararg viewers: UUID) + fun apply(target: UUID, prefix: Component, color: TextColor, suffix: Component, priority: Int, vararg viewers: UUID) + fun formatMessage(target: UUID, viewer: UUID?, format: String, message: Component): Component fun remove(target: UUID) } \ No newline at end of file diff --git a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesApi.kt b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesApi.kt index 51c4590..75810bc 100644 --- a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesApi.kt +++ b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesApi.kt @@ -1,37 +1,72 @@ package app.simplecloud.plugin.prefixes.api +import net.kyori.adventure.audience.Audience import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.TextColor import java.util.* interface PrefixesApi { + /** + * Registers a player to be able to see prefixes + * @param uniqueId UUID of the target player + */ + fun registerViewer(uniqueId: UUID) + + /** + * Returns if a viewer exists + * @param uniqueId UUID of the target player + */ + fun hasViewer(uniqueId: UUID): Boolean + + /** + * Removes a viewer + * @param uniqueId UUID of the target player + */ + fun removeViewer(uniqueId: UUID) + /** * Sets the prefix and suffix of a player in both Tab and Chat * @param uniqueId UUID of the target player * @param group + * @param viewers A list of all viewers of this change (if empty, everyone is affected) */ - fun setWholeName(uniqueId: UUID, group: PrefixesGroup) + fun setWholeName(uniqueId: UUID, group: PrefixesGroup, vararg viewers: UUID) /** * Sets the prefix and suffix of a player in both Tab and Chat * @param uniqueId UUID of the target player * @param groupName + * @param viewers A list of all viewers of this change (if empty, everyone is affected) + */ + fun setWholeName(uniqueId: UUID, groupName: String, vararg viewers: UUID) + + /** + * Sets the prefix and suffix of a player in both Tab and Chat + * @param uniqueId UUID of the target player + * @param prefix the targets prefix + * @param color the targets team color + * @param suffix the targets suffix + * @param priority the users Tablist priority + * @param viewers A list of all viewers of this change (if empty, everyone is affected) */ - fun setWholeName(uniqueId: UUID, groupName: String) + fun setWholeName(uniqueId: UUID, prefix: Component, color: TextColor, suffix: Component, priority: Int, vararg viewers: UUID) /** * Sets the prefix of a player in both Tab and Chat * @param uniqueId UUID of the target player * @param prefix prefix to set + * @param viewers A list of all viewers of this change (if empty, everyone is affected) */ - fun setPrefix(uniqueId: UUID, prefix: Component) + fun setPrefix(uniqueId: UUID, prefix: Component, vararg viewers: UUID) /** * Sets the prefix of a player in both Tab and Chat * @param uniqueId UUID of the target player * @param suffix suffix to set + * @param viewers A list of all viewers of this change (if empty, everyone is affected) */ - fun setSuffix(uniqueId: UUID, suffix: Component) + fun setSuffix(uniqueId: UUID, suffix: Component, vararg viewers: UUID) /** * Returns all registered [PrefixesGroup] ordered by priority @@ -59,9 +94,10 @@ interface PrefixesApi { /** * Changes the Scoreboard Team color of the target player (Used in 1.12+ to make player names colorful) * @param uniqueId UUID of the target player - * @param color Color string (ChatColor on spigot, hex colors on other server implementations) + * @param color the [TextColor] of the target players team + * @param viewers A list of all viewers of this change (if empty, everyone is affected) */ - fun setColor(uniqueId: UUID, color: String) + fun setColor(uniqueId: UUID, color: TextColor, vararg viewers: UUID) /** * Sets the used PrefixesConfig @@ -69,4 +105,70 @@ interface PrefixesApi { */ fun setConfig(config: PrefixesConfig) + /** + * Returns a formatted chat message of the target player that will be sent to the viewer + * @param target UUID of the target player + * @param viewer UUID of the viewing player (if null, only default prefix and suffix of the players group will be shown) + * @param format the chat format the message should follow + * @param message Message sent by the [target] + */ + fun formatChatMessage(target: UUID, viewer: UUID?, format: String, message: Component): Component + /** + * Sets the prefix and suffix of a player in both Tab and Chat + * @param uniqueId UUID of the target player + * @param group + * @param viewers A list of all viewers of this change (if empty, everyone is affected) + */ + fun setWholeName(uniqueId: UUID, group: PrefixesGroup, viewers: Audience) + + /** + * Sets the prefix and suffix of a player in both Tab and Chat + * @param uniqueId UUID of the target player + * @param groupName + * @param viewers An [Audience] of all viewers of this change (if empty, everyone is affected) + */ + fun setWholeName(uniqueId: UUID, groupName: String, viewers: Audience) + + /** + * Sets the prefix and suffix of a player in both Tab and Chat + * @param uniqueId UUID of the target player + * @param prefix the targets prefix + * @param color the targets team color + * @param suffix the targets suffix + * @param viewers An [Audience] of all viewers of this change (if empty, everyone is affected) + */ + fun setWholeName(uniqueId: UUID, prefix: Component, color: TextColor, suffix: Component, priority: Int, viewers: Audience) + /** + * Sets the prefix of a player in both Tab and Chat + * @param uniqueId UUID of the target player + * @param prefix prefix to set + * @param viewers A list of all viewers of this change (if empty, everyone is affected) + */ + fun setPrefix(uniqueId: UUID, prefix: Component, viewers: Audience) + + /** + * Sets the prefix of a player in both Tab and Chat + * @param uniqueId UUID of the target player + * @param suffix suffix to set + * @param viewers An [Audience] of all viewers of this change (if empty, everyone is affected) + */ + fun setSuffix(uniqueId: UUID, suffix: Component, viewers: Audience) + + /** + * Changes the Scoreboard Team color of the target player (Used in 1.12+ to make player names colorful) + * @param uniqueId UUID of the target player + * @param color [TextColor] the color of the target players team + * @param viewers An [Audience] of all viewers of this change (if empty, everyone is affected) + */ + fun setColor(uniqueId: UUID, color: TextColor, viewers: Audience) + + /** + * Returns a formatted chat message of the target player that will be sent to the viewer + * @param target UUID of the target player + * @param viewer An [Audience] of the viewing player (if empty, only default prefix and suffix of the targets group will be shown) + * @param format the chat format the message should follow + * @param message Message sent by the [target] + */ + fun formatChatMessage(target: UUID, viewer: Audience, format: String, message: Component): Component + } \ No newline at end of file diff --git a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesChatLoader.kt b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesChatLoader.kt new file mode 100644 index 0000000..9814e08 --- /dev/null +++ b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesChatLoader.kt @@ -0,0 +1,12 @@ +package app.simplecloud.plugin.prefixes.api + +import app.simplecloud.plugin.prefixes.api.impl.PrefixesApiImpl + +interface PrefixesChatLoader { + + /** + * Instantiates the chat provider of PrefixesApi (useful for sharding) + * @param api the [PrefixesApiImpl] object the ChatLoader belongs to + */ + fun load(api: PrefixesApiImpl) +} \ No newline at end of file diff --git a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesDisplay.kt b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesDisplay.kt new file mode 100644 index 0000000..2e607aa --- /dev/null +++ b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesDisplay.kt @@ -0,0 +1,32 @@ +package app.simplecloud.plugin.prefixes.api + +import net.kyori.adventure.text.format.TextColor + +interface PrefixesDisplay { + fun createTeam(id: String, priority: Int = 0): T? + fun getTeam(id: String): T? + fun updatePrefix(id: String, prefix: C) + fun getPriority(team: T): Int? + fun updateSuffix(id: String, suffix: C) + + fun updatePriority(id: String, priority: Int): T? + fun updateColor(id: String, color: TextColor) + fun update(id: String, prefix: C, suffix: C, priority: Int) + + fun toPriorityString(priority: Int): String { + if (priority < 0) return "000" + if (priority > 999) return "999" + var result = priority.toString() + for (i in 0 until 3 - result.length) { + result = "0${result}" + } + return result + } + + fun setPlayer(id: String, player: P) + fun removePlayer(player: P) + fun setViewer(player: P): Boolean + fun addViewer(player: P): Boolean + fun removeViewer(player: P): Boolean + fun getViewers(): Set

+} \ No newline at end of file diff --git a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesGlobalDisplay.kt b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesGlobalDisplay.kt new file mode 100644 index 0000000..8b43fc9 --- /dev/null +++ b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesGlobalDisplay.kt @@ -0,0 +1,90 @@ +package app.simplecloud.plugin.prefixes.api + +import net.kyori.adventure.text.format.TextColor +import java.util.* + +open class PrefixesGlobalDisplay { + + + private val displays = mutableMapOf>() + + + private var defaultDisplay: PrefixesDisplay? = null + + private fun executeFor(players: List, action: (display: PrefixesDisplay) -> Unit) { + displays.filter { players.isEmpty() || players.contains(it.key) }.forEach { display -> + action(display.value) + } + if (players.isEmpty()) + defaultDisplay?.let { action(it) } + } + + fun getDisplay(player: UUID): Optional> { + return Optional.ofNullable(displays.getOrDefault(player, null)) + } + + fun removeDisplay(player: UUID) { + displays.remove(player) + } + + fun getDefaultDisplay(): PrefixesDisplay? { + return defaultDisplay + } + + fun setDefaultDisplay(display: PrefixesDisplay) { + this.defaultDisplay = display + } + + fun register(uuid: UUID, display: PrefixesDisplay) { + displays[uuid] = display + } + + fun createTeam(id: String) { + executeFor(displays.keys.toList()) { + it.createTeam(id) + } + } + + fun updatePrefix(id: String, prefix: C, vararg players: UUID) { + executeFor(players.toList()) { + it.updatePrefix(id, prefix) + } + } + + fun updateSuffix(id: String, suffix: C, vararg players: UUID) { + executeFor(players.toList()) { + it.updateSuffix(id, suffix) + } + } + + fun updatePriority(id: String, priority: Int, vararg players: UUID) { + executeFor(players.toList()) { + it.updatePriority(id, priority) + } + } + + fun update(id: String, prefix: C, suffix: C, priority: Int, vararg players: UUID) { + executeFor(players.toList()) { + it.update(id, prefix, suffix, priority) + } + } + + open fun setPlayer(id: String, player: P, vararg players: UUID) { + executeFor(players.toList()) { + it.setPlayer(id, player) + } + } + + fun removePlayer(player: P, vararg players: UUID) { + executeFor(players.toList()) { + it.removePlayer(player) + } + } + + fun updateColor(id: String, color: TextColor, vararg players: UUID) { + executeFor(players.toList()) { + it.updateColor(id, color) + } + } + +} \ No newline at end of file diff --git a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesGroup.kt b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesGroup.kt index 69c61e0..533ff5a 100644 --- a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesGroup.kt +++ b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesGroup.kt @@ -1,16 +1,16 @@ package app.simplecloud.plugin.prefixes.api import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.TextColor import java.util.* import java.util.concurrent.CompletableFuture interface PrefixesGroup { fun getName(): String - fun getPrefix(): Component - fun getColor(): String - fun getSuffix(): Component + fun getPrefix(): Component? + fun getColor(): TextColor? + fun getSuffix(): Component? fun getPriority(): Int fun containsPlayer(uniqueId: UUID): Boolean - fun containsPlayerFuture(uniqueId: UUID): CompletableFuture } \ No newline at end of file diff --git a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesPluginLoader.kt b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesPluginLoader.kt new file mode 100644 index 0000000..d326c3c --- /dev/null +++ b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesPluginLoader.kt @@ -0,0 +1,12 @@ +package app.simplecloud.plugin.prefixes.api + +import app.simplecloud.plugin.prefixes.api.impl.PrefixesApiImpl + +interface PrefixesPluginLoader { + + /** + * Instantiates a new PrefixesApi (useful for sharding) + * @return a [PrefixesApiImpl] (null if load failed) + */ + fun load(): PrefixesApiImpl? +} \ No newline at end of file diff --git a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesScoreboard.kt b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesScoreboard.kt deleted file mode 100644 index 96ed135..0000000 --- a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/PrefixesScoreboard.kt +++ /dev/null @@ -1,19 +0,0 @@ -package app.simplecloud.plugin.prefixes.api - -import java.util.* - -interface PrefixesScoreboard { - - fun createTeam(uniqueId: UUID) - - fun updatePrefix(uniqueId: UUID, prefix: T) - - fun updateSuffix(uniqueId: UUID, suffix: T) - - fun update(uniqueId: UUID, prefix: T, suffix: T) - - fun apply(uniqueId: UUID, player: P) - - fun remove(player: P) - -} \ No newline at end of file diff --git a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/impl/PrefixesActorBlankImpl.kt b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/impl/PrefixesActorBlankImpl.kt index b7d0688..875cbaa 100644 --- a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/impl/PrefixesActorBlankImpl.kt +++ b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/impl/PrefixesActorBlankImpl.kt @@ -1,29 +1,46 @@ package app.simplecloud.plugin.prefixes.api.impl import app.simplecloud.plugin.prefixes.api.PrefixesActor +import app.simplecloud.plugin.prefixes.api.PrefixesApi import app.simplecloud.plugin.prefixes.api.PrefixesGroup import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.TextColor import java.util.* class PrefixesActorBlankImpl : PrefixesActor { + override fun registerViewer(target: UUID, api: PrefixesApi) { + throw NotImplementedError("You need to define a PrefixesActor to use this") + } + + override fun hasViewer(target: UUID): Boolean { + throw NotImplementedError("You need to define a PrefixesActor to use this") + } + + override fun removeViewer(target: UUID) { + throw NotImplementedError("You need to define a PrefixesActor to use this") + } + + override fun applyGroup(target: UUID, group: PrefixesGroup, vararg viewers: UUID) { + throw NotImplementedError("You need to define a PrefixesActor to use this") + } - override fun applyGroup(target: UUID, group: PrefixesGroup) { + override fun setPrefix(target: UUID, prefix: Component, vararg viewers: UUID) { throw NotImplementedError("You need to define a PrefixesActor to use this") } - override fun setPrefix(target: UUID, prefix: Component) { + override fun setSuffix(target: UUID, suffix: Component, vararg viewers: UUID) { throw NotImplementedError("You need to define a PrefixesActor to use this") } - override fun setSuffix(target: UUID, suffix: Component) { + override fun setColor(target: UUID, color: TextColor, vararg viewers: UUID) { throw NotImplementedError("You need to define a PrefixesActor to use this") } - override fun setColor(target: UUID, color: String) { + override fun apply(target: UUID, prefix: Component, color: TextColor, suffix: Component, priority: Int, vararg viewers: UUID) { throw NotImplementedError("You need to define a PrefixesActor to use this") } - override fun formatMessage(target: UUID, format: String, message: Component): Component { + override fun formatMessage(target: UUID, viewer: UUID?, format: String, message: Component): Component { throw NotImplementedError("You need to define a PrefixesActor to use this") } diff --git a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/impl/PrefixesApiImpl.kt b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/impl/PrefixesApiImpl.kt index bb1fe36..8e5c5df 100644 --- a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/impl/PrefixesApiImpl.kt +++ b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/impl/PrefixesApiImpl.kt @@ -4,7 +4,10 @@ import app.simplecloud.plugin.prefixes.api.PrefixesActor import app.simplecloud.plugin.prefixes.api.PrefixesApi import app.simplecloud.plugin.prefixes.api.PrefixesConfig import app.simplecloud.plugin.prefixes.api.PrefixesGroup +import net.kyori.adventure.audience.Audience +import net.kyori.adventure.identity.Identity import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.TextColor import java.util.* abstract class PrefixesApiImpl : PrefixesApi { @@ -13,6 +16,18 @@ abstract class PrefixesApiImpl : PrefixesApi { private var actor: PrefixesActor = PrefixesActorBlankImpl() private lateinit var config: PrefixesConfig + override fun registerViewer(uniqueId: UUID) { + actor.registerViewer(uniqueId, this) + } + + override fun hasViewer(uniqueId: UUID): Boolean { + return actor.hasViewer(uniqueId) + } + + override fun removeViewer(uniqueId: UUID) { + actor.removeViewer(uniqueId) + } + override fun getGroups(): MutableList { return groups } @@ -31,27 +46,84 @@ abstract class PrefixesApiImpl : PrefixesApi { this.actor = actor } - override fun setWholeName(uniqueId: UUID, group: PrefixesGroup) { - actor.applyGroup(uniqueId, group) + override fun setWholeName(uniqueId: UUID, group: PrefixesGroup, viewers: Audience) { + val uuids = toUUIDList(viewers) + setWholeName(uniqueId, group, *uuids.toTypedArray()) } - override fun setWholeName(uniqueId: UUID, groupName: String) { + override fun setWholeName(uniqueId: UUID, groupName: String, viewers: Audience) { setWholeName( uniqueId, - groups.stream().filter { group -> group.getName() == groupName }.findFirst().orElse(null) + groups.stream().filter { group -> group.getName() == groupName }.findFirst().orElse(null), + viewers ) } - override fun setPrefix(uniqueId: UUID, prefix: Component) { - actor.setPrefix(uniqueId, prefix) + override fun setWholeName( + uniqueId: UUID, + prefix: Component, + color: TextColor, + suffix: Component, + priority: Int, + viewers: Audience + ) { + val uuids = toUUIDList(viewers) + setWholeName(uniqueId, prefix, color, suffix, priority, *uuids.toTypedArray()) + } + + override fun formatChatMessage(target: UUID, viewer: Audience, format: String, message: Component): Component { + val uuid = toUUID(viewer) + return actor.formatMessage(target, uuid, format, message) } - override fun setSuffix(uniqueId: UUID, suffix: Component) { - actor.setSuffix(uniqueId, suffix) + override fun setPrefix(uniqueId: UUID, prefix: Component, viewers: Audience) { + val uuids = toUUIDList(viewers) + setPrefix(uniqueId, prefix, *uuids.toTypedArray()) } - override fun setColor(uniqueId: UUID, color: String) { - actor.setColor(uniqueId, color) + override fun setSuffix(uniqueId: UUID, suffix: Component, viewers: Audience) { + val uuids = toUUIDList(viewers) + setSuffix(uniqueId, suffix, *uuids.toTypedArray()) + } + + override fun setColor(uniqueId: UUID, color: TextColor, viewers: Audience) { + val uuids = toUUIDList(viewers) + setColor(uniqueId, color, *uuids.toTypedArray()) + } + + override fun setWholeName(uniqueId: UUID, group: PrefixesGroup, vararg viewers: UUID) { + actor.applyGroup(uniqueId, group, *viewers) + } + + override fun setWholeName(uniqueId: UUID, groupName: String, vararg viewers: UUID) { + setWholeName( + uniqueId, + groups.stream().filter { group -> group.getName() == groupName }.findFirst().orElse(null), + *viewers + ) + } + + override fun setWholeName( + uniqueId: UUID, + prefix: Component, + color: TextColor, + suffix: Component, + priority: Int, + vararg viewers: UUID + ) { + actor.apply(uniqueId, prefix, color, suffix, priority, *viewers) + } + + override fun setPrefix(uniqueId: UUID, prefix: Component, vararg viewers: UUID) { + actor.setPrefix(uniqueId, prefix, *viewers) + } + + override fun setSuffix(uniqueId: UUID, suffix: Component, vararg viewers: UUID) { + actor.setSuffix(uniqueId, suffix, *viewers) + } + + override fun setColor(uniqueId: UUID, color: TextColor, vararg viewers: UUID) { + actor.setColor(uniqueId, color, *viewers) } override fun setConfig(config: PrefixesConfig) { @@ -62,8 +134,21 @@ abstract class PrefixesApiImpl : PrefixesApi { return config } - fun formatChatMessage(target: UUID, format: String, message: Component): Component { - return actor.formatMessage(target, format, message) + override fun formatChatMessage(target: UUID, viewer: UUID?, format: String, message: Component): Component { + return actor.formatMessage(target, viewer, format, message) + } + + private fun toUUIDList(audience: Audience): List { + val uuids = mutableListOf() + audience.forEachAudience forEachPlayer@ { + val uuid = it.get(Identity.UUID).orElse(null) ?: return@forEachPlayer + uuids.add(uuid) + } + return uuids + } + + private fun toUUID(audience: Audience): UUID? { + return audience.get(Identity.UUID).orElse(null) } abstract fun indexGroups() diff --git a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/impl/PrefixesConfigImpl.kt b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/impl/PrefixesConfigImpl.kt index 1dea3ff..69a4609 100644 --- a/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/impl/PrefixesConfigImpl.kt +++ b/prefixes-api/src/main/kotlin/app/simplecloud/plugin/prefixes/api/impl/PrefixesConfigImpl.kt @@ -4,7 +4,7 @@ import app.simplecloud.plugin.prefixes.api.PrefixesConfig class PrefixesConfigImpl : PrefixesConfig { - private var chatFormat: String = ": " + private var chatFormat: String = ": " override fun getChatFormat(): String { return chatFormat diff --git a/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesActorMinestomImpl.kt b/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesActorMinestomImpl.kt index 353ee7b..11b6a46 100644 --- a/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesActorMinestomImpl.kt +++ b/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesActorMinestomImpl.kt @@ -1,6 +1,7 @@ package app.simplecloud.plugin.prefixes.minestom import app.simplecloud.plugin.prefixes.api.PrefixesActor +import app.simplecloud.plugin.prefixes.api.PrefixesApi import app.simplecloud.plugin.prefixes.api.PrefixesGroup import app.simplecloud.plugin.prefixes.shared.MiniMessageImpl import net.kyori.adventure.text.Component @@ -10,38 +11,52 @@ import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver import net.minestom.server.MinecraftServer import net.minestom.server.entity.Player -import net.minestom.server.scoreboard.Team import java.util.* -class PrefixesActorMinestomImpl(private var scoreboard: PrefixesScoreboardMinestomImpl) : PrefixesActor { +class PrefixesActorMinestomImpl(private var scoreboard: PrefixesGlobalDisplayMinestomImpl) : PrefixesActor { + override fun registerViewer(target: UUID, api: PrefixesApi) { + scoreboard.register(target, PrefixesTablist()) + } + + override fun hasViewer(target: UUID): Boolean { + return scoreboard.getDisplay(target).orElse(null) != null + } + + override fun removeViewer(target: UUID) { + val player = MinecraftServer.getConnectionManager().getPlayer(target) ?: return + val display = scoreboard.getDisplay(player.uuid).orElse(null) ?: return + display.removeViewer(player) + scoreboard.removeDisplay(player.uuid) + } + override fun applyGroup( target: UUID, - group: PrefixesGroup + group: PrefixesGroup, + vararg viewers: UUID, ) { - val player: Player = MinecraftServer.getConnectionManager().getPlayer(target) ?: return - scoreboard.update( - target, - group.getPrefix(), group.getSuffix() - ) - setColor(target, group.getColor()) - scoreboard.apply(target, player.username) + apply(target, group.getPrefix() ?: Component.text(""), group.getColor() ?: NamedTextColor.WHITE, group.getSuffix() ?: Component.text(""), group.getPriority(), *viewers) } override fun remove(target: UUID) { val player: Player = MinecraftServer.getConnectionManager().getPlayer(target) ?: return - scoreboard.remove(player.username) + scoreboard.removePlayer(player) } - override fun setPrefix(target: UUID, prefix: Component) { - scoreboard.updatePrefix(target, prefix) + override fun setPrefix(target: UUID, prefix: Component, vararg viewers: UUID) { + val player: Player = MinecraftServer.getConnectionManager().getPlayer(target) ?: return + scoreboard.updatePrefix(player.username, prefix) } - override fun setSuffix(target: UUID, suffix: Component) { - scoreboard.updatePrefix(target, suffix) + override fun setSuffix(target: UUID, suffix: Component, vararg viewers: UUID) { + val player: Player = MinecraftServer.getConnectionManager().getPlayer(target) ?: return + scoreboard.updateSuffix(player.username, suffix) } - override fun formatMessage(target: UUID, format: String, message: Component): Component { - val team: Team? = MinecraftServer.getTeamManager().getTeam(target.toString()) + override fun formatMessage(target: UUID, viewer: UUID?, format: String, message: Component): Component { + val targetPlayer = MinecraftServer.getConnectionManager().getPlayer(target) ?: return message + val display = if (viewer != null) scoreboard.getDisplay(viewer) + .orElse(scoreboard.getDefaultDisplay()) else scoreboard.getDefaultDisplay() ?: return message + val team = display.getTeam(targetPlayer.username) val tags = mutableListOf() if (team != null) { tags.add(Placeholder.component("prefix", team.prefix)) @@ -66,7 +81,27 @@ class PrefixesActorMinestomImpl(private var scoreboard: PrefixesScoreboardMinest return MiniMessageImpl.parse(format, tags) } - override fun setColor(target: UUID, color: String) { - scoreboard.updateColor(target, NamedTextColor.nearestTo(TextColor.fromHexString(color)!!)) + override fun setColor(target: UUID, color: TextColor, vararg viewers: UUID) { + val player: Player = MinecraftServer.getConnectionManager().getPlayer(target) ?: return + scoreboard.updateColor(player.username, color, *viewers) + } + + override fun apply( + target: UUID, + prefix: Component, + color: TextColor, + suffix: Component, + priority: Int, + vararg viewers: UUID + ) { + val player: Player = MinecraftServer.getConnectionManager().getPlayer(target) ?: return + scoreboard.update( + player.username, + prefix, suffix, priority, + *viewers + ) + setColor(target, color, *viewers) + scoreboard.removePlayer(player, *viewers) + scoreboard.addPlayer(player.username, player, *viewers) } } \ No newline at end of file diff --git a/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesExtension.kt b/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesExtension.kt index a1b7cd5..75516b9 100644 --- a/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesExtension.kt +++ b/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesExtension.kt @@ -14,6 +14,7 @@ import net.kyori.adventure.text.format.TextColor import net.minestom.server.MinecraftServer import net.minestom.server.event.player.AsyncPlayerConfigurationEvent import net.minestom.server.event.player.PlayerChatEvent +import net.minestom.server.event.player.PlayerDisconnectEvent import net.minestom.server.extensions.Extension import java.io.File @@ -31,7 +32,7 @@ class PrefixesExtension : Extension() { @Experimental prefixesApi = PrefixesApiLuckPermsImpl(LPMinestomPlugin.getApi()) //! NO OFFICIAL LUCKPERMS SUPPORT RELEASED YET ! - prefixesApi.setActor(PrefixesActorMinestomImpl(PrefixesScoreboardMinestomImpl())) + prefixesApi.setActor(PrefixesActorMinestomImpl(PrefixesGlobalDisplayMinestomImpl())) val config = PrefixesConfigParser(File(dataDirectory.toFile(), "config.json")).parse( PrefixesConfigImpl::class.java, PrefixesConfigImpl() @@ -40,18 +41,24 @@ class PrefixesExtension : Extension() { prefixesApi.setConfig(config) prefixesApi.indexGroups() MinecraftServer.getGlobalEventHandler().addListener(AsyncPlayerConfigurationEvent::class.java) { event -> + prefixesApi.registerViewer(event.player.uuid) val prefixesGroup: PrefixesGroup = prefixesApi.getHighestGroup(event.player.uuid) prefixesApi.setWholeName(event.player.uuid, prefixesGroup) } MinecraftServer.getGlobalEventHandler().addListener(PlayerChatEvent::class.java) { event -> event.setChatFormat { return@setChatFormat prefixesApi.formatChatMessage( + event.player.uuid, event.player.uuid, prefixesApi.getConfig().getChatFormat(), MiniMessageImpl.parse(event.message) ) } } + + MinecraftServer.getGlobalEventHandler().addListener(PlayerDisconnectEvent::class.java) { event -> + prefixesApi.removeViewer(event.player.uuid) + } MinecraftServer.LOGGER.info(Component.text("PrefixesApi initialized.").color(TextColor.color(0x7cf7ab))) } diff --git a/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesGlobalDisplayMinestomImpl.kt b/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesGlobalDisplayMinestomImpl.kt new file mode 100644 index 0000000..cb55ba4 --- /dev/null +++ b/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesGlobalDisplayMinestomImpl.kt @@ -0,0 +1,8 @@ +package app.simplecloud.plugin.prefixes.minestom + +import app.simplecloud.plugin.prefixes.api.PrefixesGlobalDisplay +import net.kyori.adventure.text.Component +import net.minestom.server.entity.Player +import net.minestom.server.scoreboard.Team + +class PrefixesGlobalDisplayMinestomImpl : PrefixesGlobalDisplay() \ No newline at end of file diff --git a/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesScoreboardMinestomImpl.kt b/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesScoreboardMinestomImpl.kt deleted file mode 100644 index 1b5530d..0000000 --- a/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesScoreboardMinestomImpl.kt +++ /dev/null @@ -1,61 +0,0 @@ -package app.simplecloud.plugin.prefixes.minestom - -import app.simplecloud.plugin.prefixes.api.PrefixesScoreboard -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.NamedTextColor -import net.minestom.server.MinecraftServer -import net.minestom.server.scoreboard.Team -import java.util.* - -class PrefixesScoreboardMinestomImpl : PrefixesScoreboard { - - private val teamManager = MinecraftServer.getTeamManager() - - private fun createTeamReturning(uniqueId: UUID): Team? { - if (teamManager.getTeam(uniqueId.toString()) == null) - return teamManager.createTeam(uniqueId.toString()) - return null - } - - override fun createTeam(uniqueId: UUID) { - createTeamReturning(uniqueId) - } - - override fun update(uniqueId: UUID, prefix: Component, suffix: Component) { - val team: Team = teamManager.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.prefix = prefix; - team.suffix = suffix; - } - - override fun remove(player: String) { - teamManager.deleteTeam(player) - } - - override fun apply(uniqueId: UUID, player: String) { - val team: Team = teamManager.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.addMember(player) - } - - fun update(uniqueId: UUID, prefix: Component, suffix: Component, color: NamedTextColor) { - val team: Team = teamManager.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.prefix = prefix - team.suffix = suffix - team.teamColor = color - } - - override fun updateSuffix(uniqueId: UUID, suffix: Component) { - val team: Team = teamManager.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.suffix = suffix - } - - override fun updatePrefix(uniqueId: UUID, prefix: Component) { - val team: Team = teamManager.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.prefix = prefix - } - - - fun updateColor(uniqueId: UUID, color: NamedTextColor) { - val team: Team = teamManager.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.teamColor = color - } -} \ No newline at end of file diff --git a/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesTablist.kt b/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesTablist.kt new file mode 100644 index 0000000..efdf9d5 --- /dev/null +++ b/prefixes-minestom/src/main/java/app/simplecloud/plugin/prefixes/minestom/PrefixesTablist.kt @@ -0,0 +1,200 @@ +package app.simplecloud.plugin.prefixes.minestom + +import app.simplecloud.plugin.prefixes.api.PrefixesDisplay +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.NamedTextColor +import net.kyori.adventure.text.format.TextColor +import net.minestom.server.MinecraftServer +import net.minestom.server.entity.Player +import net.minestom.server.network.packet.server.play.PlayerInfoUpdatePacket +import net.minestom.server.network.packet.server.play.TeamsPacket +import net.minestom.server.scoreboard.Team + +class PrefixesTablist : PrefixesDisplay { + + private val teams = mutableListOf() + private val priorities = mutableMapOf() + private val viewers = mutableSetOf() + private var color: TextColor = NamedTextColor.GRAY + override fun addViewer(player: Player): Boolean { + val result = viewers.add(player) + if (result) { + teams.forEach { team -> + player.sendPacket(getCreateTeamPacket(team)) + team.players.forEach { teamPlayer -> + getUpdatePacket(teamPlayer)?.let { player.sendPacket(it) } + } + } + } + + return result + } + + override fun removeViewer(player: Player): Boolean { + val result = viewers.remove(player) + if (result) { + teams.forEach { team -> + player.sendPacket(getRemoveTeamPacket(team)) + team.players.forEach { teamPlayer -> + player.sendPacket(getDefaultPlayerInfoPacket(teamPlayer)) + } + } + } + return result + } + + override fun getViewers(): Set { + return viewers + } + + override fun createTeam(id: String, priority: Int): Team? { + if (getTeam(id) != null) return null + val team = MinecraftServer.getTeamManager().createTeam("${toPriorityString(priority)}$id") + teams.add(team) + return team + } + + override fun getTeam(id: String): Team? { + return teams.firstOrNull { it.teamName.endsWith(id) } + } + + override fun getPriority(team: Team): Int? { + return priorities[team] + } + + fun copyTeam(team: Team, id: String, priority: Int): Team? { + val newTeam = createTeam(id, priority) ?: return null + newTeam.prefix = team.prefix + newTeam.suffix = team.suffix + newTeam.teamColor = team.teamColor + newTeam.players.addAll(team.players) + return newTeam + } + + override fun updatePriority(id: String, priority: Int): Team? { + val team = getTeam(id) ?: return null + val newTeam = copyTeam(team, id, priority) ?: return null + teams.remove(team) + priorities.remove(team) + teams.add(newTeam) + priorities[newTeam] = priority + return newTeam + } + + override fun updateColor(id: String, color: TextColor) { + val team = getTeam(id) ?: return + team.teamColor = NamedTextColor.nearestTo(color) + this.color = color + render(team) + } + + override fun setViewer(player: Player): Boolean { + viewers.forEach { removeViewer(it) } + return addViewer(player) + } + + override fun removePlayer(player: Player) { + teams.forEach { + if (it.players.contains(player)) { + it.removeMember(player.username) + } + } + } + + override fun setPlayer(id: String, player: Player) { + val team = getTeam(id) ?: createTeam(id) ?: return + team.addMember(player.username) + } + + override fun update(id: String, prefix: Component, suffix: Component, priority: Int) { + val team = updatePriority(id, priority) ?: createTeam(id, priority) ?: return + team.prefix = prefix + team.suffix = suffix + render(team) + } + + override fun updateSuffix(id: String, suffix: Component) { + val team = getTeam(id) ?: return + team.suffix = suffix + render(team) + } + + override fun updatePrefix(id: String, prefix: Component) { + val team = getTeam(id) ?: return + team.prefix = prefix + render(team) + } + + private fun getUpdatePacket(player: Player): PlayerInfoUpdatePacket? { + val team = teams.firstOrNull { it.players.contains(player) } ?: return null + return PlayerInfoUpdatePacket( + PlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME, PlayerInfoUpdatePacket.Entry( + player.uuid, + player.username, + listOf(), + true, + player.latency, + player.gameMode, + team.prefix.append(Component.text(player.username).color(color)).append(team.suffix), + null + ) + ) + } + + private fun getDefaultPlayerInfoPacket(player: Player): PlayerInfoUpdatePacket { + return PlayerInfoUpdatePacket( + PlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME, PlayerInfoUpdatePacket.Entry( + player.uuid, + player.username, + listOf(), + true, + player.latency, + player.gameMode, + player.displayName, + null + ) + ) + } + + private fun render(team: Team) { + viewers.forEach { viewer -> + team.players.forEach { player -> + getUpdatePacket(player)?.let { viewer.sendPacket(it) } + } + viewer.sendPacket(getUpdateTeamPacket(team)) + } + } + + private fun getUpdateTeamPacket(team: Team): TeamsPacket { + return TeamsPacket( + team.teamName, TeamsPacket.UpdateTeamAction( + team.teamDisplayName, + team.friendlyFlags, + team.nameTagVisibility, + team.collisionRule, + team.teamColor, + team.prefix, + team.suffix + ) + ) + } + + private fun getCreateTeamPacket(team: Team): TeamsPacket { + return TeamsPacket( + team.teamName, TeamsPacket.CreateTeamAction( + team.teamDisplayName, + team.friendlyFlags, + team.nameTagVisibility, + team.collisionRule, + team.teamColor, + team.prefix, + team.suffix, + team.members + ) + ) + } + + private fun getRemoveTeamPacket(team: Team): TeamsPacket { + return TeamsPacket(team.teamName, TeamsPacket.RemoveTeamAction()) + } +} \ No newline at end of file diff --git a/prefixes-minestom/src/main/resources/extension.json b/prefixes-minestom/src/main/resources/extension.json index 9fa33db..7d64099 100644 --- a/prefixes-minestom/src/main/resources/extension.json +++ b/prefixes-minestom/src/main/resources/extension.json @@ -1,7 +1,7 @@ { "entrypoint": "app.simplecloud.plugin.prefixes.minestom.PrefixesExtension", - "name": "PrefixesApi", - "version": "1.0", + "name": "Prefixes", + "version": "1.1", "dependencies": [ "LuckPerms" ] diff --git a/prefixes-paper/build.gradle.kts b/prefixes-paper/build.gradle.kts index 93a1ad5..a769c0d 100644 --- a/prefixes-paper/build.gradle.kts +++ b/prefixes-paper/build.gradle.kts @@ -1,5 +1,13 @@ +plugins { + alias(libs.plugins.paperweight.userdev) +} + dependencies { api(project(":prefixes-shared")) - api(project(":prefixes-spigot")) - compileOnly("io.papermc.paper:paper-api:1.20.2-R0.1-SNAPSHOT") + paperweight.paperDevBundle("1.21.4-R0.1-SNAPSHOT") + compileOnly(libs.paper.api) +} + +tasks.assemble { + dependsOn(tasks.reobfJar) } \ No newline at end of file diff --git a/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPlayerTeam.kt b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPlayerTeam.kt new file mode 100644 index 0000000..06ab565 --- /dev/null +++ b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPlayerTeam.kt @@ -0,0 +1,41 @@ +package app.simplecloud.plugin.prefixes.paper + +import io.papermc.paper.adventure.PaperAdventure +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.NamedTextColor +import net.kyori.adventure.text.format.TextColor +import net.minecraft.ChatFormatting +import net.minecraft.world.scores.PlayerTeam +import net.minecraft.world.scores.Scoreboard + +class PaperPlayerTeam(id: String, val priority: Int = 0) : + PlayerTeam(Scoreboard(), "${toPriorityString(priority)}${id}") { + + init { + nameTagVisibility = Visibility.NEVER + } + + var realColor: TextColor = NamedTextColor.WHITE + set(value) { + field = value + color = ChatFormatting.valueOf(NamedTextColor.nearestTo(value).toString().uppercase()) + } + + fun getFormattedName(formattedName: Component): Component { + val mutableComponent = Component.empty().append(PaperAdventure.asAdventure(this.playerPrefix)) + .append(formattedName.color(realColor)).append( + PaperAdventure.asAdventure(this.playerSuffix) + ) + return mutableComponent + } +} + +private fun toPriorityString(priority: Int): String { + if (priority < 0) return "000" + if (priority > 999) return "999" + var result = priority.toString() + for (i in 0 until 3 - result.length) { + result = "0${result}" + } + return result +} \ No newline at end of file diff --git a/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPrefixesActor.kt b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPrefixesActor.kt new file mode 100644 index 0000000..50fc9a8 --- /dev/null +++ b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPrefixesActor.kt @@ -0,0 +1,146 @@ +package app.simplecloud.plugin.prefixes.paper + +import app.simplecloud.plugin.prefixes.api.PrefixesActor +import app.simplecloud.plugin.prefixes.api.PrefixesApi +import app.simplecloud.plugin.prefixes.api.PrefixesGroup +import app.simplecloud.plugin.prefixes.shared.MiniMessageImpl +import io.papermc.paper.adventure.PaperAdventure +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.NamedTextColor +import net.kyori.adventure.text.format.TextColor +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver +import org.bukkit.Bukkit +import org.bukkit.entity.Player +import java.util.* + +class PaperPrefixesActor( + private var scoreboard: PaperPrefixesGlobalDisplay, +) : PrefixesActor { + + init { + scoreboard.setDefaultDisplay(PaperPrefixesDisplay()) + } + + override fun registerViewer(target: UUID, api: PrefixesApi) { + val targetPlayer = Bukkit.getPlayer(target) ?: return + val display = PaperPrefixesDisplay() + scoreboard.register(target, display) + display.setViewer(targetPlayer) + val defaultDisplay = scoreboard.getDefaultDisplay() ?: return + Bukkit.getOnlinePlayers().forEach { player -> + if (player.uniqueId != target) { + val team = defaultDisplay.getTeam(player.name) ?: return@forEach + apply( + player.uniqueId, + PaperAdventure.asAdventure(team.playerPrefix), + TextColor.color(team.realColor), + PaperAdventure.asAdventure(team.playerSuffix), + defaultDisplay.getPriority(team) ?: 0, + target + ) + } + } + } + + override fun hasViewer(target: UUID): Boolean { + return scoreboard.getDisplay(target).orElse(null) != null + } + + override fun removeViewer(target: UUID) { + val player = Bukkit.getPlayer(target) ?: return + val display = scoreboard.getDisplay(target).orElse(null) ?: return + display.removeViewer(player) + scoreboard.removeDisplay(target) + } + + override fun applyGroup( + target: UUID, + group: PrefixesGroup, + vararg viewers: UUID + ) { + val player: Player = Bukkit.getPlayer(target) ?: return + scoreboard.update( + player.name, + group.getPrefix() ?: Component.text(""), + group.getSuffix() ?: Component.text(""), + group.getPriority(), + *viewers + ) + if (group.getColor() != null) + setColor(target, group.getColor()!!, *viewers) + scoreboard.setPlayer(player.name, player, *viewers) + apply( + target, + group.getPrefix() ?: Component.text(""), + group.getColor() ?: NamedTextColor.WHITE, + group.getSuffix() ?: Component.text(""), + group.getPriority(), + *viewers + ) + } + + override fun remove(target: UUID) { + val player: Player = Bukkit.getPlayer(target) ?: return + scoreboard.removePlayer(player) + } + + override fun setPrefix(target: UUID, prefix: Component, vararg viewers: UUID) { + val player = Bukkit.getPlayer(target) ?: return + scoreboard.updatePrefix(player.name, prefix, *viewers) + } + + override fun setSuffix(target: UUID, suffix: Component, vararg viewers: UUID) { + val player = Bukkit.getPlayer(target) ?: return + scoreboard.updateSuffix(player.name, suffix, *viewers) + } + + override fun formatMessage(target: UUID, viewer: UUID?, format: String, message: Component): Component { + val display = if (viewer != null) scoreboard.getDisplay(viewer) + .orElseGet { scoreboard.getDefaultDisplay() } else scoreboard.getDefaultDisplay() ?: return message + val targetPlayer = Bukkit.getPlayer(target) ?: return message + val team: PaperPlayerTeam? = display.getTeam(targetPlayer.name) + val tags = mutableListOf() + if (team != null) { + tags.add(Placeholder.component("prefix", PaperAdventure.asAdventure(team.playerPrefix))) + tags.add(Placeholder.component("suffix", PaperAdventure.asAdventure(team.playerSuffix))) + tags.add( + Placeholder.component( + "name_colored", + Component.text(Bukkit.getPlayer(target)!!.name) + .color(team.realColor) + ) + ) + tags.add(Placeholder.unparsed("name", targetPlayer.name)) + } else { + tags.add(Placeholder.unparsed("name", targetPlayer.name)) + } + tags.add(Placeholder.component("message", message)) + return MiniMessageImpl.parse(format, tags) + } + + override fun setColor(target: UUID, color: TextColor, vararg viewers: UUID) { + val player = Bukkit.getPlayer(target) ?: return + scoreboard.updateColor(player.name, color, *viewers) + } + + override fun apply( + target: UUID, + prefix: Component, + color: TextColor, + suffix: Component, + priority: Int, + vararg viewers: UUID + ) { + val player: Player = Bukkit.getPlayer(target) ?: return + scoreboard.update( + player.name, + prefix, + suffix, + priority, + *viewers + ) + setColor(target, color, *viewers) + scoreboard.setPlayer(player.name, player, *viewers) + } +} \ No newline at end of file diff --git a/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPrefixesChatLoader.kt b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPrefixesChatLoader.kt new file mode 100644 index 0000000..efd2634 --- /dev/null +++ b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPrefixesChatLoader.kt @@ -0,0 +1,28 @@ +package app.simplecloud.plugin.prefixes.paper + +import app.simplecloud.plugin.prefixes.api.PrefixesChatLoader +import app.simplecloud.plugin.prefixes.api.impl.PrefixesApiImpl +import io.papermc.paper.event.player.AsyncChatEvent +import net.kyori.adventure.identity.Identity +import org.bukkit.Bukkit +import org.bukkit.event.EventHandler +import org.bukkit.event.EventPriority +import org.bukkit.event.Listener +import org.bukkit.plugin.Plugin + +class PaperPrefixesChatLoader(private val plugin: Plugin) : PrefixesChatLoader, Listener { + + private lateinit var api: PrefixesApiImpl + override fun load(api: PrefixesApiImpl) { + this.api = api + Bukkit.getPluginManager().registerEvents(this, plugin) + } + + @EventHandler(priority = EventPriority.LOWEST) + fun onChat(event: AsyncChatEvent) { + event.renderer { player, _, message, audience -> + val viewer = audience.getOrDefault(Identity.UUID, null) + api.formatChatMessage(player.uniqueId, viewer, api.getConfig().getChatFormat(), message) + } + } +} \ No newline at end of file diff --git a/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPrefixesDisplay.kt b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPrefixesDisplay.kt new file mode 100644 index 0000000..03ef68f --- /dev/null +++ b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPrefixesDisplay.kt @@ -0,0 +1,242 @@ +package app.simplecloud.plugin.prefixes.paper + +import app.simplecloud.plugin.prefixes.api.PrefixesDisplay +import io.papermc.paper.adventure.PaperAdventure +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.TextColor +import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket +import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket +import net.minecraft.world.level.GameType +import net.minecraft.world.scores.PlayerTeam +import org.bukkit.Bukkit +import org.bukkit.craftbukkit.entity.CraftPlayer +import org.bukkit.entity.Player +import java.util.* + +class PaperPrefixesDisplay : PrefixesDisplay { + + private val teams: MutableMap = mutableMapOf() + private val players: MutableMap = mutableMapOf() + private val viewers: MutableSet = mutableSetOf() + + override fun createTeam(id: String, priority: Int): PaperPlayerTeam? { + if (getTeam(id) != null) return null + val team = PaperPlayerTeam(id, priority) + teams[id] = team + return team + } + + override fun getTeam(id: String): PaperPlayerTeam? { + return teams.getOrDefault(id, null) + } + + override fun getPriority(team: PaperPlayerTeam): Int { + return team.priority + } + + override fun updatePriority(id: String, priority: Int): PaperPlayerTeam? { + val team = getTeam(id) ?: return null + val deletePacket = ClientboundSetPlayerTeamPacket.createRemovePacket(team) + viewers.forEach { viewer -> + (viewer as CraftPlayer).handle.connection.sendPacket(deletePacket) + } + val newTeam = changeTeamPriority(priority, team) ?: return null + val createPacket = ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(newTeam, true) + val addPlayersPacket = ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket( + newTeam, + getPlayersForTeam(newTeam), + ClientboundSetPlayerTeamPacket.Action.ADD + ) + viewers.forEach { viewer -> + with(viewer as CraftPlayer) { + handle.connection.sendPacket(createPacket) + handle.connection.sendPacket(addPlayersPacket) + } + } + teams[id] = newTeam + return team + } + + override fun updateColor(id: String, color: TextColor) { + val team = getTeam(id) ?: return + team.realColor = color + val updatePacket = ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(team, false) + viewers.forEach { viewer -> + (viewer as CraftPlayer).handle.connection.sendPacket(updatePacket) + } + sendUpdateDisplayNamePackets(team) + } + + override fun getViewers(): Set { + return viewers + } + + override fun removeViewer(player: Player): Boolean { + val result = viewers.remove(player) + if (result) { + teams.values.forEach { team -> + val deletePacket = ClientboundSetPlayerTeamPacket.createRemovePacket(team) + (player as CraftPlayer).handle.connection.sendPacket(deletePacket) + getPlayersForTeam(team).filter { Bukkit.getPlayer(it)?.isOnline ?: false } + .map { Bukkit.getPlayer(it)!! }.forEach { sendUpdateDisplayNamePacket(it) } + } + } + return result + } + + override fun addViewer(player: Player): Boolean { + val result = viewers.add(player) + if (result) { + teams.values.forEach { team -> + val createPacket = ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(team, false) + val addPlayersPacket = ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket( + team, + getPlayersForTeam(team), + ClientboundSetPlayerTeamPacket.Action.ADD + ) + with(player as CraftPlayer) { + handle.connection.sendPacket(createPacket) + handle.connection.sendPacket(addPlayersPacket) + } + sendUpdateDisplayNamePackets(team) + } + } + return result + } + + override fun setViewer(player: Player): Boolean { + viewers.forEach { removeViewer(it) } + return addViewer(player) + } + + override fun removePlayer(player: Player) { + val playerTeam = players[player.name] ?: return + val team = teams.filter { it.key == playerTeam }.map { it.value }.firstOrNull() ?: return + players.remove(player.name) + val packet = ClientboundSetPlayerTeamPacket.createPlayerPacket( + team, + player.name, + ClientboundSetPlayerTeamPacket.Action.REMOVE + ) + viewers.forEach { viewer -> (viewer as CraftPlayer).handle.connection.sendPacket(packet) } + sendUpdateDisplayNamePackets(team) + } + + override fun setPlayer(id: String, player: Player) { + val team = teams[id] ?: return + if (players.contains(player.name)) { + teams[players[player.name]]?.let { existing -> + val delete = ClientboundSetPlayerTeamPacket.createPlayerPacket( + existing, + player.name, + ClientboundSetPlayerTeamPacket.Action.REMOVE + ) + viewers.forEach { viewer -> (viewer as CraftPlayer).handle.connection.sendPacket(delete) } + } + + } + players[player.name] = id + val packet = ClientboundSetPlayerTeamPacket.createPlayerPacket( + team, + player.name, + ClientboundSetPlayerTeamPacket.Action.ADD + ) + viewers.forEach { viewer -> (viewer as CraftPlayer).handle.connection.sendPacket(packet) } + sendUpdateDisplayNamePackets(team) + } + + override fun update(id: String, prefix: Component, suffix: Component, priority: Int) { + val exists = getTeam(id) != null + val team = updatePriority(id, priority) ?: createTeam(id, priority) ?: return + team.playerPrefix = PaperAdventure.asVanilla(prefix) + team.playerSuffix = PaperAdventure.asVanilla(suffix) + teams[id] = team + val packet = ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(team, !exists) + + viewers.forEach { viewer -> + with(viewer as CraftPlayer) { + handle.connection.sendPacket(packet) + } + } + sendUpdateDisplayNamePackets(team) + } + + override fun updateSuffix(id: String, suffix: Component) { + val team = getTeam(id) ?: return + team.playerSuffix = PaperAdventure.asVanilla(suffix) + teams[id] = team + val packet = ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(team, false) + viewers.forEach { viewer -> + with(viewer as CraftPlayer) { + handle.connection.sendPacket(packet) + } + } + sendUpdateDisplayNamePackets(team) + } + + override fun updatePrefix(id: String, prefix: Component) { + val team = getTeam(id) ?: return + team.playerPrefix = PaperAdventure.asVanilla(prefix) + teams[id] = team + val packet = ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(team, false) + viewers.forEach { viewer -> + with(viewer as CraftPlayer) { + handle.connection.sendPacket(packet) + } + } + sendUpdateDisplayNamePackets(team) + } + + private fun sendUpdateDisplayNamePackets(team: PaperPlayerTeam) { + val id = teams.filter { it.value == team }.keys.firstOrNull() ?: return + val players = players.filter { it.value == id && Bukkit.getPlayer(it.key)?.isOnline ?: false }.keys.map { + Bukkit.getPlayer(it)!! + } + players.forEach { player -> sendUpdateDisplayNamePacket(player, team) } + } + + private fun sendUpdateDisplayNamePacket(player: Player, passed: PaperPlayerTeam? = null) { + val team = passed ?: teams[players[player.name]] + val update = ClientboundPlayerInfoUpdatePacket( + EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME), + ClientboundPlayerInfoUpdatePacket.Entry( + player.uniqueId, + null, + true, + -1, + GameType.ADVENTURE, + PaperAdventure.asVanilla(team?.getFormattedName(player.name()) ?: player.name()), + true, + -1, + null + ) + ) + viewers.forEach { viewer -> + with(viewer as CraftPlayer) { + handle.connection.sendPacket(update) + } + } + } + + private fun changeTeamPriority(priority: Int, team: PaperPlayerTeam): PaperPlayerTeam? { + val id = teams.filter { it.value == team }.keys.firstOrNull() ?: return null + val playersInTeam = getPlayersForTeam(team) + val newTeam = PaperPlayerTeam(id, priority) + playersInTeam.forEach { player -> players[player] = id } + newTeam.playerPrefix = team.playerPrefix + newTeam.displayName = team.displayName + newTeam.playerSuffix = team.playerSuffix + newTeam.nameTagVisibility = team.nameTagVisibility + newTeam.setSeeFriendlyInvisibles(team.canSeeFriendlyInvisibles()) + newTeam.deathMessageVisibility = team.deathMessageVisibility + newTeam.collisionRule = team.collisionRule + newTeam.realColor = team.realColor + return newTeam + } + + private fun getPlayersForTeam(team: PlayerTeam): List { + val id = teams.filter { it.value == team }.keys.firstOrNull() ?: return emptyList() + return players.filter { it.value == id } + .map { it.key } + } +} \ No newline at end of file diff --git a/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPrefixesGlobalDisplay.kt b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPrefixesGlobalDisplay.kt new file mode 100644 index 0000000..55290b2 --- /dev/null +++ b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPrefixesGlobalDisplay.kt @@ -0,0 +1,27 @@ +package app.simplecloud.plugin.prefixes.paper + +import app.simplecloud.plugin.prefixes.api.PrefixesGlobalDisplay +import net.kyori.adventure.text.Component +import org.bukkit.entity.Player +import space.chunks.customname.api.CustomNameManager +import java.util.* + +class PaperPrefixesGlobalDisplay( + private val name: CustomNameManager +) : PrefixesGlobalDisplay() { + + override fun setPlayer(id: String, player: Player, vararg players: UUID) { + super.setPlayer(id, player, *players) + name.forEntity(player).setName { viewer -> + val defaultDisplay = getDefaultDisplay() ?: return@setName Component.text(player.name) + val display = getDisplay(viewer.uniqueId).orElse(null) ?: defaultDisplay + val team = display.getTeam(player.name) ?: defaultDisplay.getTeam(player.name) + ?: return@setName Component.text(player.name) + return@setName team.getFormattedName( + Component.text( + player.name + ) + ) + } + } +} \ No newline at end of file diff --git a/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPrefixesLoader.kt b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPrefixesLoader.kt new file mode 100644 index 0000000..88c6815 --- /dev/null +++ b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PaperPrefixesLoader.kt @@ -0,0 +1,98 @@ +package app.simplecloud.plugin.prefixes.paper + +import app.simplecloud.plugin.prefixes.api.PrefixesApi +import app.simplecloud.plugin.prefixes.api.PrefixesChatLoader +import app.simplecloud.plugin.prefixes.api.PrefixesPluginLoader +import app.simplecloud.plugin.prefixes.api.impl.PrefixesApiImpl +import app.simplecloud.plugin.prefixes.api.impl.PrefixesConfigImpl +import app.simplecloud.plugin.prefixes.paper.event.PrefixesConfigureEvent +import app.simplecloud.plugin.prefixes.paper.event.PrefixesConfiguredEvent +import app.simplecloud.plugin.prefixes.paper.listener.LuckPermsListener +import app.simplecloud.plugin.prefixes.shared.PrefixesApiLuckPermsImpl +import app.simplecloud.plugin.prefixes.shared.PrefixesConfigParser +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.NamedTextColor +import net.luckperms.api.LuckPerms +import org.bukkit.Bukkit +import org.bukkit.entity.Player +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +import org.bukkit.event.player.PlayerJoinEvent +import org.bukkit.event.player.PlayerQuitEvent +import org.bukkit.plugin.Plugin +import org.bukkit.plugin.RegisteredServiceProvider +import org.bukkit.plugin.ServicePriority +import space.chunks.customname.api.CustomNameManager +import java.io.File + +class PaperPrefixesLoader( + private val plugin: Plugin, + private val chatLoader: PrefixesChatLoader +) : PrefixesPluginLoader, Listener { + + private lateinit var api: PrefixesApiImpl + private lateinit var actor: PaperPrefixesActor + override fun load(): PrefixesApiImpl? { + val customNameManager = Bukkit.getServicesManager().load(CustomNameManager::class.java) ?: return null + val luckPermsProvider: RegisteredServiceProvider = + Bukkit.getServicesManager().getRegistration(LuckPerms::class.java) ?: return null + actor = PaperPrefixesActor(PaperPrefixesGlobalDisplay(customNameManager)) + val luckPerms: LuckPerms = luckPermsProvider.provider + api = PrefixesApiLuckPermsImpl(luckPerms) + api.setActor(actor) + api.setConfig( + PrefixesConfigParser(File(plugin.dataFolder, "config.json")).parse( + PrefixesConfigImpl::class.java, + PrefixesConfigImpl() + ) + ) + plugin.saveResource("config.json", false) + api.indexGroups() + Bukkit.getPluginManager().registerEvents(this, plugin) + Bukkit.getServicesManager().register(PrefixesApi::class.java, api, plugin, ServicePriority.Normal) + + chatLoader.load(api) + LuckPermsListener(plugin, luckPerms, api).init() + return api + } + + @EventHandler + fun onJoin(event: PlayerJoinEvent) { + Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, Runnable { + if (!api.hasViewer(event.player.uniqueId)) { + api.registerViewer(event.player.uniqueId) + applyFirstName(api, plugin, event.player) + } + }, 10L) + } + + @EventHandler + fun onQuit(event: PlayerQuitEvent) { + api.removeViewer(event.player.uniqueId) + actor.remove(event.player.uniqueId) + } + + companion object { + fun applyFirstName(api: PrefixesApi, plugin: Plugin, player: Player) { + val group = api.getHighestGroup(player.uniqueId) + Bukkit.getScheduler().runTask(plugin, Runnable { + val prefixData = PrefixesConfigureEvent( + player, + group.getPrefix(), + group.getSuffix(), + group.getColor(), + group.getPriority() + ) + Bukkit.getPluginManager().callEvent(prefixData) + api.setWholeName( + player.uniqueId, + prefixData.prefix ?: Component.text(""), + prefixData.color ?: NamedTextColor.WHITE, + prefixData.suffix ?: Component.text(""), + prefixData.priority + ) + Bukkit.getPluginManager().callEvent(PrefixesConfiguredEvent(player)) + }) + } + } +} \ No newline at end of file diff --git a/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PrefixesActorPaperImpl.kt b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PrefixesActorPaperImpl.kt deleted file mode 100644 index 3c31411..0000000 --- a/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PrefixesActorPaperImpl.kt +++ /dev/null @@ -1,66 +0,0 @@ -package app.simplecloud.plugin.prefixes.paper - -import app.simplecloud.plugin.prefixes.api.PrefixesActor -import app.simplecloud.plugin.prefixes.api.PrefixesGroup -import app.simplecloud.plugin.prefixes.shared.MiniMessageImpl -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.NamedTextColor -import net.kyori.adventure.text.format.TextColor -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver -import org.bukkit.Bukkit -import org.bukkit.entity.Player -import org.bukkit.scoreboard.Team -import java.util.* - -class PrefixesActorPaperImpl(private var scoreboard: PrefixesScoreboardPaperImpl) : PrefixesActor { - override fun applyGroup( - target: UUID, - group: PrefixesGroup - ) { - val player: Player = Bukkit.getPlayer(target) ?: return - scoreboard.update( - target, - group.getPrefix(), group.getSuffix() - ) - setColor(target, group.getColor()) - scoreboard.apply(target, player.name) - } - - override fun remove(target: UUID) { - val player: Player = Bukkit.getPlayer(target) ?: return - scoreboard.remove(player.name) - } - - override fun setPrefix(target: UUID, prefix: Component) { - scoreboard.updatePrefix(target, prefix) - } - - override fun setSuffix(target: UUID, suffix: Component) { - scoreboard.updatePrefix(target, suffix) - } - - override fun formatMessage(target: UUID, format: String, message: Component): Component { - val team: Team? = scoreboard.getTeam(target) - val tags = mutableListOf() - if (team != null) { - tags.add(Placeholder.component("prefix", team.prefix())) - tags.add(Placeholder.component("suffix", team.suffix())) - tags.add( - Placeholder.component( - "name_colored", - Component.text(Bukkit.getPlayer(target)!!.name).color(team.color()) - ) - ) - tags.add(Placeholder.component("name", Component.text(Bukkit.getPlayer(target)!!.name))) - } else { - tags.add(Placeholder.unparsed("name", "%s")) - } - tags.add(Placeholder.component("message", message)) - return MiniMessageImpl.parse(format, tags) - } - - override fun setColor(target: UUID, color: String) { - scoreboard.updateColor(target, NamedTextColor.nearestTo(TextColor.fromHexString(color)!!)) - } -} \ No newline at end of file diff --git a/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PrefixesPlugin.kt b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PrefixesPlugin.kt index 8b199c4..be21b6a 100644 --- a/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PrefixesPlugin.kt +++ b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PrefixesPlugin.kt @@ -1,65 +1,13 @@ package app.simplecloud.plugin.prefixes.paper -import app.simplecloud.plugin.prefixes.api.PrefixesApi -import app.simplecloud.plugin.prefixes.api.PrefixesGroup -import app.simplecloud.plugin.prefixes.api.impl.PrefixesConfigImpl -import app.simplecloud.plugin.prefixes.shared.PrefixesApiLuckPermsImpl -import app.simplecloud.plugin.prefixes.shared.PrefixesConfigParser -import io.papermc.paper.event.player.AsyncChatEvent -import net.luckperms.api.LuckPerms -import org.bukkit.Bukkit -import org.bukkit.event.EventHandler -import org.bukkit.event.EventPriority import org.bukkit.event.Listener -import org.bukkit.event.player.PlayerJoinEvent -import org.bukkit.plugin.RegisteredServiceProvider -import org.bukkit.plugin.ServicePriority import org.bukkit.plugin.java.JavaPlugin -import java.io.File -import java.util.* class PrefixesPlugin : JavaPlugin(), Listener { - - private lateinit var prefixesApi: PrefixesApiLuckPermsImpl - private val scoreboard: PrefixesScoreboardPaperImpl = PrefixesScoreboardPaperImpl() - private val prefixesApiActor: PrefixesActorPaperImpl = PrefixesActorPaperImpl(scoreboard) - override fun onEnable() { - val luckPermsProvider: RegisteredServiceProvider = - Bukkit.getServicesManager().getRegistration(LuckPerms::class.java) ?: return - val luckPerms: LuckPerms = luckPermsProvider.provider - prefixesApi = PrefixesApiLuckPermsImpl(luckPerms) - scoreboard.setScoreboard(Bukkit.getScoreboardManager().mainScoreboard) - prefixesApi.setActor(prefixesApiActor) - prefixesApi.setConfig( - PrefixesConfigParser(File(dataFolder, "config.json")).parse( - PrefixesConfigImpl::class.java, - PrefixesConfigImpl() - ) - ) - saveResource("config.json", false) - prefixesApi.indexGroups() - Bukkit.getPluginManager().registerEvents(this, this) - Bukkit.getServicesManager().register(PrefixesApi::class.java, prefixesApi, this, ServicePriority.Normal) - } - - @EventHandler - fun onJoin(event: PlayerJoinEvent) { - val uniqueId: UUID = event.player.uniqueId - val playerGroup: PrefixesGroup = prefixesApi.getHighestGroup(uniqueId) - prefixesApi.setWholeName(uniqueId, playerGroup) + val loader = PaperPrefixesLoader(this, PaperPrefixesChatLoader(this)) + if (loader.load() == null) { + throw NullPointerException("The Prefixes Plugin could not load correctly") + } } - - @EventHandler(priority = EventPriority.LOWEST) - fun onChat(event: AsyncChatEvent) { - event.message( - prefixesApi.formatChatMessage( - event.player.uniqueId, - prefixesApi.getConfig().getChatFormat(), - event.message() - ) - ) - } - - } \ No newline at end of file diff --git a/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PrefixesScoreboardPaperImpl.kt b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PrefixesScoreboardPaperImpl.kt deleted file mode 100644 index 316ba4d..0000000 --- a/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/PrefixesScoreboardPaperImpl.kt +++ /dev/null @@ -1,70 +0,0 @@ -package app.simplecloud.plugin.prefixes.paper - -import app.simplecloud.plugin.prefixes.api.PrefixesScoreboard -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.NamedTextColor -import org.bukkit.Bukkit -import org.bukkit.scoreboard.Scoreboard -import org.bukkit.scoreboard.Team -import java.util.* - -class PrefixesScoreboardPaperImpl : PrefixesScoreboard { - private lateinit var scoreboard: Scoreboard - fun setScoreboard(scoreboard: Scoreboard) { - this.scoreboard = scoreboard - } - - private fun createTeamReturning(uniqueId: UUID): Team? { - if (scoreboard.getTeam(uniqueId.toString()) == null) - return scoreboard.registerNewTeam(uniqueId.toString()) - return null - } - - override fun createTeam(uniqueId: UUID) { - createTeamReturning(uniqueId) - } - - override fun update(uniqueId: UUID, prefix: Component, suffix: Component) { - val team: Team = scoreboard.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.prefix(prefix) - team.suffix(suffix) - } - - fun getTeam(uniqueId: UUID): Team? { - return scoreboard.getEntryTeam(Bukkit.getPlayer(uniqueId)!!.name) - } - - override fun remove(player: String) { - val team: Team = scoreboard.getEntryTeam(player) ?: return - team.removeEntry(player) - } - - override fun apply(uniqueId: UUID, player: String) { - val team: Team = scoreboard.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.addEntry(player) - } - - fun update(uniqueId: UUID, prefix: Component, suffix: Component, color: NamedTextColor) { - val team: Team = scoreboard.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.prefix(prefix) - team.suffix(suffix) - team.color(color) - } - - override fun updateSuffix(uniqueId: UUID, suffix: Component) { - val team: Team = scoreboard.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.suffix(suffix) - } - - override fun updatePrefix(uniqueId: UUID, prefix: Component) { - val team: Team = scoreboard.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.prefix(prefix) - } - - - fun updateColor(uniqueId: UUID, color: NamedTextColor) { - val team: Team = scoreboard.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.color(color) - } - -} \ No newline at end of file diff --git a/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/event/PrefixesConfigureEvent.kt b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/event/PrefixesConfigureEvent.kt new file mode 100644 index 0000000..1a3e481 --- /dev/null +++ b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/event/PrefixesConfigureEvent.kt @@ -0,0 +1,30 @@ +package app.simplecloud.plugin.prefixes.paper.event + +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.TextColor +import org.bukkit.entity.Player +import org.bukkit.event.Event +import org.bukkit.event.HandlerList + +/** + * This event is called when a player is ready to receive his prefix. + * You can modify each property, which will result in differences on the first render in tab. + */ +data class PrefixesConfigureEvent( + val player: Player, + var prefix: Component?, + var suffix: Component?, + var color: TextColor?, + var priority: Int, +): Event() { + companion object { + private val handlers: HandlerList = HandlerList() + @JvmStatic + fun getHandlerList(): HandlerList { + return handlers + } + } + override fun getHandlers(): HandlerList { + return Companion.handlers + } +} \ No newline at end of file diff --git a/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/event/PrefixesConfiguredEvent.kt b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/event/PrefixesConfiguredEvent.kt new file mode 100644 index 0000000..1bc5260 --- /dev/null +++ b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/event/PrefixesConfiguredEvent.kt @@ -0,0 +1,26 @@ +package app.simplecloud.plugin.prefixes.paper.event + +import org.bukkit.entity.Player +import org.bukkit.event.Event +import org.bukkit.event.HandlerList + +/** + * This event is called when a player was successfully registered in the [app.simplecloud.plugin.prefixes.api.PrefixesActor]. + * If you want to create custom logic (e.g. a custom suffix visible to the friends of this player) + * you have to do it when listening on this event to make sure it works correctly. + */ +data class PrefixesConfiguredEvent( + val player: Player +): Event() { + + companion object { + private val handlers: HandlerList = HandlerList() + @JvmStatic + fun getHandlerList(): HandlerList { + return handlers + } + } + override fun getHandlers(): HandlerList { + return Companion.handlers + } +} \ No newline at end of file diff --git a/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/listener/LuckPermsListener.kt b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/listener/LuckPermsListener.kt new file mode 100644 index 0000000..02628a1 --- /dev/null +++ b/prefixes-paper/src/main/kotlin/app/simplecloud/plugin/prefixes/paper/listener/LuckPermsListener.kt @@ -0,0 +1,27 @@ +package app.simplecloud.plugin.prefixes.paper.listener + +import app.simplecloud.plugin.prefixes.api.PrefixesApi +import net.luckperms.api.LuckPerms +import net.luckperms.api.event.user.UserDataRecalculateEvent +import org.bukkit.plugin.Plugin + +class LuckPermsListener( + private val plugin: Plugin, + private val luckPerms: LuckPerms, + private val api: PrefixesApi +) { + + fun init() { + val eventBus = luckPerms.eventBus + eventBus.subscribe(plugin, UserDataRecalculateEvent::class.java, this::onUserUpdate) + } + + private val groups: MutableMap = mutableMapOf() + + private fun onUserUpdate(event: UserDataRecalculateEvent) { + if(groups.getOrDefault(event.user.uniqueId.toString(), "") == event.user.primaryGroup) return + groups[event.user.uniqueId.toString()] = event.user.primaryGroup + api.setWholeName(event.user.uniqueId, event.user.primaryGroup) + } + +} \ No newline at end of file diff --git a/prefixes-paper/src/main/resources/paper-plugin.yml b/prefixes-paper/src/main/resources/paper-plugin.yml new file mode 100644 index 0000000..4a708bb --- /dev/null +++ b/prefixes-paper/src/main/resources/paper-plugin.yml @@ -0,0 +1,15 @@ +name: Prefixes +version: 1.1 +main: app.simplecloud.plugin.prefixes.paper.PrefixesPlugin +api-version: 1.21.4 +dependencies: + server: + LuckPerms: + load: BEFORE + require: true + CustomNames: + load: BEFORE + require: true + join-classpath: true +authors: + - dayyeeet \ No newline at end of file diff --git a/prefixes-paper/src/main/resources/plugin.yml b/prefixes-paper/src/main/resources/plugin.yml deleted file mode 100644 index 77c4ab5..0000000 --- a/prefixes-paper/src/main/resources/plugin.yml +++ /dev/null @@ -1,5 +0,0 @@ -name: PrefixesApi -version: 1.0 -main: app.simplecloud.plugin.prefixes.spigot.PrefixesPlugin -authors: - - dayyeeet \ No newline at end of file diff --git a/prefixes-shared/build.gradle.kts b/prefixes-shared/build.gradle.kts index e827456..c398fbd 100644 --- a/prefixes-shared/build.gradle.kts +++ b/prefixes-shared/build.gradle.kts @@ -1,3 +1,5 @@ dependencies { api(project(":prefixes-api")) + implementation("net.kyori:adventure-text-serializer-gson:4.14.0") + implementation("net.kyori:adventure-text-serializer-legacy:4.14.0") } \ No newline at end of file diff --git a/prefixes-shared/src/main/kotlin/app/simplecloud/plugin/prefixes/shared/ComponentSerializerImpl.kt b/prefixes-shared/src/main/kotlin/app/simplecloud/plugin/prefixes/shared/ComponentSerializerImpl.kt new file mode 100644 index 0000000..f466c83 --- /dev/null +++ b/prefixes-shared/src/main/kotlin/app/simplecloud/plugin/prefixes/shared/ComponentSerializerImpl.kt @@ -0,0 +1,27 @@ +package app.simplecloud.plugin.prefixes.shared + +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer + +class ComponentSerializerImpl { + companion object { + private val impl = + GsonComponentSerializer.builder().build() + private val legacyImpl = + LegacyComponentSerializer.builder().hexColors().character('§').useUnusualXRepeatedCharacterHexFormat() + .hexCharacter('x').build() + + private fun serialize(component: Component): String { + return impl.serialize(component) + } + + fun serializeLegacy(component: Component): String { + return legacyImpl.serialize(component) + } + + fun deserializeLegacy(text: String): Component { + return legacyImpl.deserialize(text) + } + } +} \ No newline at end of file diff --git a/prefixes-shared/src/main/kotlin/app/simplecloud/plugin/prefixes/shared/LuckPermsGroup.kt b/prefixes-shared/src/main/kotlin/app/simplecloud/plugin/prefixes/shared/LuckPermsGroup.kt index 5a41d40..445a3cf 100644 --- a/prefixes-shared/src/main/kotlin/app/simplecloud/plugin/prefixes/shared/LuckPermsGroup.kt +++ b/prefixes-shared/src/main/kotlin/app/simplecloud/plugin/prefixes/shared/LuckPermsGroup.kt @@ -2,6 +2,7 @@ package app.simplecloud.plugin.prefixes.shared import app.simplecloud.plugin.prefixes.api.PrefixesGroup import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.TextColor import net.luckperms.api.LuckPerms import net.luckperms.api.model.group.Group import java.util.* @@ -10,19 +11,19 @@ import java.util.concurrent.CompletableFuture class LuckPermsGroup(private var group: Group, private var luckPerms: LuckPerms) : PrefixesGroup { override fun getName(): String { - return group.name; + return group.name } - override fun getPrefix(): Component { - return MiniMessageImpl.parse((group.cachedData.metaData.prefix ?: "")) + override fun getPrefix(): Component? { + return group.cachedData.metaData.prefix?.let { MiniMessageImpl.parse(it) } } - override fun getColor(): String { - return group.cachedData.metaData.getMetaValue("color") ?: "WHITE" + override fun getColor(): TextColor? { + return TextColor.fromHexString(group.cachedData.metaData.getMetaValue("color") ?: "#FFFFFF") } - override fun getSuffix(): Component { - return MiniMessageImpl.parse((group.cachedData.metaData.suffix ?: "")) + override fun getSuffix(): Component? { + return group.cachedData.metaData.suffix?.let { MiniMessageImpl.parse(it) } } override fun getPriority(): Int { diff --git a/prefixes-shared/src/main/kotlin/app/simplecloud/plugin/prefixes/shared/MiniMessageImpl.kt b/prefixes-shared/src/main/kotlin/app/simplecloud/plugin/prefixes/shared/MiniMessageImpl.kt index 1727d72..77d1d5e 100644 --- a/prefixes-shared/src/main/kotlin/app/simplecloud/plugin/prefixes/shared/MiniMessageImpl.kt +++ b/prefixes-shared/src/main/kotlin/app/simplecloud/plugin/prefixes/shared/MiniMessageImpl.kt @@ -8,14 +8,23 @@ class MiniMessageImpl { companion object { private val miniMessage = MiniMessage.miniMessage() fun parse(text: String): Component { + if (text.contains("§")) { + return ComponentSerializerImpl.deserializeLegacy(text) + } return miniMessage.deserialize(text) } fun parse(text: String, vararg tags: TagResolver): Component { + if (text.contains("§")) { + return ComponentSerializerImpl.deserializeLegacy(text) + } return miniMessage.deserialize(text, TagResolver.resolver(tags.asIterable())) } fun parse(text: String, tags: Iterable): Component { + if (text.contains("§")) { + return ComponentSerializerImpl.deserializeLegacy(text) + } return miniMessage.deserialize(text, TagResolver.resolver(tags)) } } diff --git a/prefixes-spigot/build.gradle.kts b/prefixes-spigot/build.gradle.kts deleted file mode 100644 index fba2df7..0000000 --- a/prefixes-spigot/build.gradle.kts +++ /dev/null @@ -1,5 +0,0 @@ -dependencies { - api(project(":prefixes-shared")) - compileOnly("org.spigotmc:spigot-api:1.20.2-R0.1-SNAPSHOT") - implementation("net.kyori:adventure-text-serializer-legacy:4.14.0") -} \ No newline at end of file diff --git a/prefixes-spigot/src/main/java/app/simplecloud/plugin/prefixes/spigot/LegacyComponentSerializerImpl.kt b/prefixes-spigot/src/main/java/app/simplecloud/plugin/prefixes/spigot/LegacyComponentSerializerImpl.kt deleted file mode 100644 index 3a2e22c..0000000 --- a/prefixes-spigot/src/main/java/app/simplecloud/plugin/prefixes/spigot/LegacyComponentSerializerImpl.kt +++ /dev/null @@ -1,20 +0,0 @@ -package app.simplecloud.plugin.prefixes.spigot - -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer - -class LegacyComponentSerializerImpl { - companion object { - private val impl = - LegacyComponentSerializer.builder().hexColors().useUnusualXRepeatedCharacterHexFormat().character('§') - .hexCharacter('x').build() - - fun deserialize(text: String): Component { - return impl.deserialize(text) - } - - fun serialize(component: Component): String { - return impl.serialize(component) - } - } -} \ No newline at end of file diff --git a/prefixes-spigot/src/main/java/app/simplecloud/plugin/prefixes/spigot/PrefixesActorSpigotImpl.kt b/prefixes-spigot/src/main/java/app/simplecloud/plugin/prefixes/spigot/PrefixesActorSpigotImpl.kt deleted file mode 100644 index bdf5145..0000000 --- a/prefixes-spigot/src/main/java/app/simplecloud/plugin/prefixes/spigot/PrefixesActorSpigotImpl.kt +++ /dev/null @@ -1,66 +0,0 @@ -package app.simplecloud.plugin.prefixes.spigot - -import app.simplecloud.plugin.prefixes.api.PrefixesActor -import app.simplecloud.plugin.prefixes.api.PrefixesGroup -import app.simplecloud.plugin.prefixes.shared.MiniMessageImpl -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver -import org.bukkit.Bukkit -import org.bukkit.ChatColor -import org.bukkit.entity.Player -import org.bukkit.scoreboard.Team -import java.util.* - -class PrefixesActorSpigotImpl(private var scoreboard: PrefixesScoreboardSpigotImpl) : PrefixesActor { - override fun applyGroup( - target: UUID, - group: PrefixesGroup - ) { - val player: Player = Bukkit.getPlayer(target) ?: return - scoreboard.update( - target, - LegacyComponentSerializerImpl.serialize(group.getPrefix()), - LegacyComponentSerializerImpl.serialize(group.getSuffix()) - ) - setColor(target, group.getColor()) - scoreboard.apply(target, player.name) - } - - override fun remove(target: UUID) { - val player: Player = Bukkit.getPlayer(target) ?: return - scoreboard.remove(player.name) - } - - override fun setPrefix(target: UUID, prefix: Component) { - scoreboard.updatePrefix(target, LegacyComponentSerializerImpl.serialize(prefix)) - } - - override fun setSuffix(target: UUID, suffix: Component) { - scoreboard.updatePrefix(target, LegacyComponentSerializerImpl.serialize(suffix)) - } - - override fun formatMessage(target: UUID, format: String, message: Component): Component { - val team: Team? = scoreboard.getTeam(target) - val tags = mutableListOf() - if (team != null) { - tags.add(Placeholder.component("prefix", LegacyComponentSerializerImpl.deserialize(team.prefix))) - tags.add(Placeholder.component("suffix", LegacyComponentSerializerImpl.deserialize(team.suffix))) - tags.add( - Placeholder.component( - "name_colored", - LegacyComponentSerializerImpl.deserialize(team.color.toString() + Bukkit.getPlayer(target)!!.name) - ) - ) - tags.add(Placeholder.component("name", Component.text(Bukkit.getPlayer(target)!!.name))) - } else { - tags.add(Placeholder.unparsed("name", "%s")) - } - tags.add(Placeholder.component("message", message)) - return MiniMessageImpl.parse(format, tags) - } - - override fun setColor(target: UUID, color: String) { - scoreboard.updateColor(target, ChatColor.valueOf(color)) - } -} \ No newline at end of file diff --git a/prefixes-spigot/src/main/java/app/simplecloud/plugin/prefixes/spigot/PrefixesPlugin.kt b/prefixes-spigot/src/main/java/app/simplecloud/plugin/prefixes/spigot/PrefixesPlugin.kt deleted file mode 100644 index 0175fe2..0000000 --- a/prefixes-spigot/src/main/java/app/simplecloud/plugin/prefixes/spigot/PrefixesPlugin.kt +++ /dev/null @@ -1,66 +0,0 @@ -package app.simplecloud.plugin.prefixes.spigot - -import app.simplecloud.plugin.prefixes.api.PrefixesApi -import app.simplecloud.plugin.prefixes.api.PrefixesGroup -import app.simplecloud.plugin.prefixes.api.impl.PrefixesConfigImpl -import app.simplecloud.plugin.prefixes.shared.MiniMessageImpl -import app.simplecloud.plugin.prefixes.shared.PrefixesApiLuckPermsImpl -import app.simplecloud.plugin.prefixes.shared.PrefixesConfigParser -import net.luckperms.api.LuckPerms -import org.bukkit.Bukkit -import org.bukkit.event.EventHandler -import org.bukkit.event.EventPriority -import org.bukkit.event.Listener -import org.bukkit.event.player.AsyncPlayerChatEvent -import org.bukkit.event.player.PlayerJoinEvent -import org.bukkit.plugin.RegisteredServiceProvider -import org.bukkit.plugin.ServicePriority -import org.bukkit.plugin.java.JavaPlugin -import java.io.File -import java.util.* - -class PrefixesPlugin : JavaPlugin(), Listener { - - private lateinit var prefixesApi: PrefixesApiLuckPermsImpl - private val scoreboard: PrefixesScoreboardSpigotImpl = PrefixesScoreboardSpigotImpl() - private val prefixesApiActor: PrefixesActorSpigotImpl = PrefixesActorSpigotImpl(scoreboard) - - override fun onEnable() { - val luckPermsProvider: RegisteredServiceProvider = - Bukkit.getServicesManager().getRegistration(LuckPerms::class.java) ?: return - val luckPerms: LuckPerms = luckPermsProvider.provider - prefixesApi = PrefixesApiLuckPermsImpl(luckPerms) - prefixesApi.setActor(prefixesApiActor) - prefixesApi.setConfig( - PrefixesConfigParser(File(dataFolder, "config.json")).parse( - PrefixesConfigImpl::class.java, - PrefixesConfigImpl() - ) - ) - saveResource("config.json", false) - prefixesApi.indexGroups() - Bukkit.getPluginManager().registerEvents(this, this) - Bukkit.getServicesManager().register(PrefixesApi::class.java, prefixesApi, this, ServicePriority.Normal) - } - - @EventHandler - fun onJoin(event: PlayerJoinEvent) { - scoreboard.initScoreboard(Bukkit.getScoreboardManager()!!.mainScoreboard) - val uniqueId: UUID = event.player.uniqueId - val playerGroup: PrefixesGroup = prefixesApi.getHighestGroup(uniqueId) - prefixesApi.setWholeName(uniqueId, playerGroup) - } - - @EventHandler(priority = EventPriority.LOWEST) - fun onChat(event: AsyncPlayerChatEvent) { - event.format = LegacyComponentSerializerImpl.serialize( - prefixesApi.formatChatMessage( - event.player.uniqueId, - prefixesApi.getConfig().getChatFormat(), - MiniMessageImpl.parse(event.message) - ) - ) - } - - -} \ No newline at end of file diff --git a/prefixes-spigot/src/main/java/app/simplecloud/plugin/prefixes/spigot/PrefixesScoreboardSpigotImpl.kt b/prefixes-spigot/src/main/java/app/simplecloud/plugin/prefixes/spigot/PrefixesScoreboardSpigotImpl.kt deleted file mode 100644 index 063ae5a..0000000 --- a/prefixes-spigot/src/main/java/app/simplecloud/plugin/prefixes/spigot/PrefixesScoreboardSpigotImpl.kt +++ /dev/null @@ -1,72 +0,0 @@ -package app.simplecloud.plugin.prefixes.spigot - -import app.simplecloud.plugin.prefixes.api.PrefixesScoreboard -import org.bukkit.Bukkit -import org.bukkit.ChatColor -import org.bukkit.scoreboard.Scoreboard -import org.bukkit.scoreboard.Team -import java.util.* - -class PrefixesScoreboardSpigotImpl : PrefixesScoreboard { - - private lateinit var scoreboard: Scoreboard - - fun initScoreboard(scoreboard: Scoreboard) { - if (!this::scoreboard.isInitialized) - this.scoreboard = scoreboard - } - - override fun createTeam(uniqueId: UUID) { - createTeamReturning(uniqueId) - } - - fun getTeam(uniqueId: UUID): Team? { - return scoreboard.getEntryTeam(Bukkit.getPlayer(uniqueId)!!.name) - } - - override fun remove(player: String) { - val team: Team = scoreboard.getEntryTeam(player) ?: return - team.removeEntry(player) - } - - override fun apply(uniqueId: UUID, player: String) { - val team: Team = scoreboard.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.addEntry(player) - } - - private fun createTeamReturning(uniqueId: UUID): Team? { - if (scoreboard.getTeam(uniqueId.toString()) == null) - return scoreboard.registerNewTeam(uniqueId.toString()) - return null - } - - override fun update(uniqueId: UUID, prefix: String, suffix: String) { - val team: Team = scoreboard.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.prefix = prefix - team.suffix = suffix - } - - fun update(uniqueId: UUID, prefix: String, suffix: String, color: ChatColor) { - val team: Team = scoreboard.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.prefix = prefix - team.suffix = suffix - team.color = color - } - - override fun updateSuffix(uniqueId: UUID, suffix: String) { - val team: Team = scoreboard.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.suffix = suffix - } - - override fun updatePrefix(uniqueId: UUID, prefix: String) { - val team: Team = scoreboard.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.prefix = prefix - } - - - fun updateColor(uniqueId: UUID, color: ChatColor) { - val team: Team = scoreboard.getTeam(uniqueId.toString()) ?: createTeamReturning(uniqueId) ?: return - team.color = color - } - -} \ No newline at end of file diff --git a/prefixes-spigot/src/main/resources/config.json b/prefixes-spigot/src/main/resources/config.json deleted file mode 100644 index efe10ef..0000000 --- a/prefixes-spigot/src/main/resources/config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "chatFormat": ": " -} \ No newline at end of file diff --git a/prefixes-spigot/src/main/resources/plugin.yml b/prefixes-spigot/src/main/resources/plugin.yml deleted file mode 100644 index 77c4ab5..0000000 --- a/prefixes-spigot/src/main/resources/plugin.yml +++ /dev/null @@ -1,5 +0,0 @@ -name: PrefixesApi -version: 1.0 -main: app.simplecloud.plugin.prefixes.spigot.PrefixesPlugin -authors: - - dayyeeet \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index fe67f78..f032d0b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,13 +2,14 @@ pluginManagement { repositories { mavenCentral() gradlePluginPortal() + maven("https://repo.papermc.io/repository/maven-public/") } } plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0" + id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } -include("prefixes-api", "prefixes-minestom", "prefixes-paper", "prefixes-shared", "prefixes-spigot") +include("prefixes-api", "prefixes-minestom", "prefixes-paper", "prefixes-shared") rootProject.name = "prefixes-plugin" \ No newline at end of file