diff --git a/.gitignore b/.gitignore index 1d7e09c..45c3c94 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,4 @@ /build/ /run/ /devbox.lock -/.idea/ -/lib/ \ No newline at end of file +/.idea/ \ No newline at end of file diff --git a/build.gradle b/build.gradle index bd2faa3..dd369c4 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,6 @@ ext { minecraftVersion = project.findProperty('minecraftVersion') ?: '1.20.4' javaVersion = JavaVersion.toVersion(project.findProperty('javaVersion') ?: '21') pluginVersion = project.findProperty('pluginVersion') ?: '1.0.0' - donationApiVersion = project.findProperty('donationApiVersion') ?: '1.0.2' } repositories { @@ -28,7 +27,7 @@ repositories { } maven { // FoliaLib - url = 'https://nexuslite.gcnt.net/repos/other/' + url = 'https://repo.tcoded.com/releases/' content { includeGroup 'com.tcoded' } @@ -50,7 +49,7 @@ dependencies { // Folia API // https://jd.papermc.io/folia/1.20/ - //compileOnly group: 'dev.folia', name: 'folia-api', version: "${project.minecraft_version}-R0.1-SNAPSHOT" + compileOnly group: 'dev.folia', name: 'folia-api', version: "${project.minecraftVersion}-R0.1-SNAPSHOT" // https://www.jetbrains.com/help/idea/annotating-source-code.html compileOnly group: 'org.jetbrains', name: 'annotations', version: "26.0.1" @@ -59,10 +58,10 @@ dependencies { shadow group: 'com.jcabi', name: 'jcabi-aspects', version: '0.25.1' // https://github.com/TechnicallyCoded/FoliaLib - shadow group: 'com.tcoded', name: 'FoliaLib', version: "0.4.2" + shadow group: 'com.tcoded', name: 'FoliaLib', version: "0.5.1" - // DonationAPI (from GitHub releases, downloaded at build time) - compileOnly files("$rootDir/lib/DonationAPI-${donationApiVersion}.jar") + // DonationAPI (vendored jar) + compileOnly files("$rootDir/lib/DonationAPI-1.0.3.jar") } java { @@ -116,18 +115,5 @@ tasks { } } -tasks.register('downloadDonationApi') { - doLast { - def libDir = file("$rootDir/lib") - if (!libDir.exists()) libDir.mkdirs() - def jar = file("$rootDir/lib/DonationAPI-${donationApiVersion}.jar") - if (!jar.exists()) { - println "Downloading DonationAPI-${donationApiVersion}.jar..." - def url = "https://github.com/zeroBzeroT/DonationAPI/releases/download/${donationApiVersion}/DonationAPI-${donationApiVersion}.jar" - ant.get(src: url, dest: jar, verbose: true) - } - } -} - -//tasks.named('compileJava').configure { dependsOn(downloadDonationApi) } -//tasks.named('compileTestJava').configure { dependsOn(downloadDonationApi) } \ No newline at end of file +// DonationAPI jar vendored under lib/. Bump the version below and replace the file +// when updating. See https://github.com/zeroBzeroT/DonationAPI for upstream. \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 59c0c5d..e6a6504 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,11 +1,8 @@ # Plugin version -pluginVersion=1.0.3 +pluginVersion=1.0.4 # Java version javaVersion=21 # Minecraft version -minecraftVersion=1.20.4 - -# DonationAPI version -donationApiVersion=1.0.2 \ No newline at end of file +minecraftVersion=1.20.4 \ No newline at end of file diff --git a/lib/DonationAPI-1.0.3.jar b/lib/DonationAPI-1.0.3.jar new file mode 100644 index 0000000..b21cdc7 Binary files /dev/null and b/lib/DonationAPI-1.0.3.jar differ diff --git a/src/main/java/org/crayne/ptjdnc/NameColorPlugin.java b/src/main/java/org/crayne/ptjdnc/NameColorPlugin.java index 3413d35..ff2e6e5 100644 --- a/src/main/java/org/crayne/ptjdnc/NameColorPlugin.java +++ b/src/main/java/org/crayne/ptjdnc/NameColorPlugin.java @@ -93,16 +93,18 @@ private void registerCommands() { } private void registerPlayerOpEventTimerTask() { - // probably not the best solution for a player op event, but atleast it works? spigot or paper, please add an op event :sob: + // poll op status and dispatch per-player work to the players region thread for the actual profile update foliaLib.getScheduler().runTimerAsync(() -> { final Map difference = getUuidBooleanMap(); - difference.forEach((uuid, wasOp) -> { final Player player = Bukkit.getPlayer(uuid); if (player == null) return; - - final PlayerOpStatusChangeEvent opStatusChangeEvent = new PlayerOpStatusChangeEvent(player, wasOp, player.isOp(), true); - Bukkit.getPluginManager().callEvent(opStatusChangeEvent); + // folia: forceUpdate / callEvent must run on the player's region + foliaLib.getScheduler().runAtEntity(player, task -> { + if (!player.isOnline()) return; + final PlayerOpStatusChangeEvent opStatusChangeEvent = new PlayerOpStatusChangeEvent(player, wasOp, player.isOp(), true); + Bukkit.getPluginManager().callEvent(opStatusChangeEvent); + }); }); }, 20L, 20L); } diff --git a/src/main/java/org/crayne/ptjdnc/command/ItemColorCommand.java b/src/main/java/org/crayne/ptjdnc/command/ItemColorCommand.java index 46f96c7..ab6ad02 100644 --- a/src/main/java/org/crayne/ptjdnc/command/ItemColorCommand.java +++ b/src/main/java/org/crayne/ptjdnc/command/ItemColorCommand.java @@ -3,12 +3,15 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.Material; +import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; import org.crayne.ptjdnc.NameColorPlugin; import org.crayne.ptjdnc.api.NameStyle; import org.jetbrains.annotations.NotNull; @@ -40,7 +43,7 @@ public boolean onCommand(@NotNull final CommandSender commandSender, @NotNull fi } final PlainTextComponentSerializer plainText = PlainTextComponentSerializer.plainText(); final ItemMeta meta = mainhandItem.getItemMeta(); - final Component defaultDisplayComponent = Component.translatable(mainhandItem.translationKey()); + final Component defaultDisplayComponent = defaultDisplayFor(mainhandItem, meta); final Component displayName = Optional.ofNullable(meta.displayName()).orElse(defaultDisplayComponent); final String defaultDisplayName = plainText.serialize(defaultDisplayComponent); @@ -66,4 +69,17 @@ public boolean onCommand(@NotNull final CommandSender commandSender, @NotNull fi p.sendMessage(deserialize("ic_success", s -> s)); return true; } + + private static Component defaultDisplayFor(@NotNull final ItemStack item, @NotNull final ItemMeta meta) { + if (meta instanceof SkullMeta skull) { + final OfflinePlayer owner = skull.getOwningPlayer(); + if (owner != null && owner.getName() != null) { + return Component.text(owner.getName() + "'s Head"); + } + } + if (meta instanceof BookMeta book && book.getTitle() != null) { + return Component.text(book.getTitle()); + } + return Component.translatable(item.translationKey()); + } }