From a53a4dac61a2d4083aa3d28b4a52cf98cbd20a1f Mon Sep 17 00:00:00 2001 From: cybsec Date: Wed, 4 Feb 2026 21:07:34 -0500 Subject: [PATCH] fix(dialog): fully integrate Paper Dialog API 1.21.11 via oyetickets reference --- .gitignore | 1 + build.gradle.kts | 2 +- .../cybsec/oyeshops/gui/SetupDialog.java | 224 ++++++++++-------- 3 files changed, 130 insertions(+), 97 deletions(-) diff --git a/.gitignore b/.gitignore index b20d3b3..1d14146 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ out/ # logs logs/ *.log +oyetickets/ diff --git a/build.gradle.kts b/build.gradle.kts index 9159cb9..6ea6757 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ repositories { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.8-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.11-R0.1-SNAPSHOT") implementation("org.xerial:sqlite-jdbc:3.47.1.0") } diff --git a/src/main/java/party/cybsec/oyeshops/gui/SetupDialog.java b/src/main/java/party/cybsec/oyeshops/gui/SetupDialog.java index 86b2200..ac2203d 100644 --- a/src/main/java/party/cybsec/oyeshops/gui/SetupDialog.java +++ b/src/main/java/party/cybsec/oyeshops/gui/SetupDialog.java @@ -1,112 +1,144 @@ package party.cybsec.oyeshops.gui; +import io.papermc.paper.dialog.Dialog; +import io.papermc.paper.registry.data.dialog.DialogBase; +import io.papermc.paper.registry.data.dialog.ActionButton; +import io.papermc.paper.registry.data.dialog.type.DialogType; +import io.papermc.paper.registry.data.dialog.action.DialogAction; +import io.papermc.paper.registry.data.dialog.input.DialogInput; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.ClickCallback; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextColor; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; import party.cybsec.oyeshops.OyeShopsPlugin; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; +import party.cybsec.oyeshops.model.PendingActivation; +import party.cybsec.oyeshops.model.Trade; -// import io.papermc.paper.dialog.Dialog; -// import io.papermc.paper.dialog.DialogBase; -// import io.papermc.paper.dialog.DialogType; -// import io.papermc.paper.dialog.action.ActionButton; -// import io.papermc.paper.dialog.action.DialogAction; -// import io.papermc.paper.dialog.component.DialogInput; -// import io.papermc.paper.dialog.event.DialogResponseView; +import java.util.List; /** * opens a setup wizard for creating shops using paper's dialog api - * - * TODO: Uncomment and fix imports once Paper 1.21.8 API is available */ public class SetupDialog { public static void open(Player player, Block signBlock, OyeShopsPlugin plugin) { - player.sendMessage(Component.text("setup wizard is coming soon (waiting for paper 1.21.8 update)", - NamedTextColor.YELLOW)); + Dialog dialog = Dialog.create(builder -> builder.empty() + .base(DialogBase.builder(Component.text("shop setup wizard", NamedTextColor.GOLD)) + .inputs(List.of( + // product (selling) + DialogInput.text("product_item", + Component.text("what are you selling? (e.g. diamond)", + NamedTextColor.YELLOW)) + .build(), + DialogInput.text("product_qty", + Component.text("how many per purchase? (e.g. 64)", + NamedTextColor.YELLOW)) + .initial("1") + .build(), - /* - * Dialog dialog = Dialog.create(builder -> builder.empty() - * .base(DialogBase.builder(Component.text("shop setup wizard", - * NamedTextColor.GOLD)) - * .inputs(List.of( - * // product (selling) - * DialogInput.text("product_item", - * Component.text("what are you selling? (item name)", NamedTextColor.YELLOW)) - * .placeholder(Component.text("e.g. diamond")) - * .build(), - * DialogInput.numberRange("product_qty", - * Component.text("how many per purchase?", NamedTextColor.YELLOW), 1, 64) - * .step(1) - * .initial(1) - * .build(), - * - * // price (buying) - * DialogInput.text("price_item", - * Component.text("what do you want? (payment item)", NamedTextColor.GREEN)) - * .placeholder(Component.text("e.g. gold ingot")) - * .build(), - * DialogInput.numberRange("price_qty", - * Component.text("how many?", NamedTextColor.GREEN), 1, 64) - * .step(1) - * .initial(1) - * .build())) - * .build()) - * .type(DialogType.confirmation( - * ActionButton.create( - * Component.text("create shop", TextColor.color(0xAEFFC1)), - * Component.text("click to confirm trade details"), - * 100, - * DialogAction.customClick( - * (view, audience) -> handleCallback(view, (Player) audience, signBlock, - * plugin), - * io.papermc.paper.dialog.action.ClickCallback.Options.builder().uses(1).build( - * ))), - * ActionButton.create( - * Component.text("cancel", TextColor.color(0xFFA0B1)), - * Component.text("discard changes"), - * 100, - * null // closes dialog - * )))); - * - * player.showDialog(dialog); - */ + // price (buying) + DialogInput.text("price_item", + Component.text("what do you want? (e.g. gold ingot)", + NamedTextColor.GREEN)) + .build(), + DialogInput.text("price_qty", + Component.text("how many? (e.g. 10)", + NamedTextColor.GREEN)) + .initial("1") + .build())) + .build()) + .type(DialogType.confirmation( + ActionButton.builder(Component.text("create shop", + TextColor.color(0xAEFFC1))) + .tooltip(Component + .text("click to confirm trade details")) + .action(DialogAction.customClick((view, audience) -> { + String productStr = view + .getText("product_item"); + String productQtyStr = view + .getText("product_qty"); + String priceStr = view.getText("price_item"); + String priceQtyStr = view.getText("price_qty"); + Player p = (Player) audience; + + // 1. parse quantities + int productQty; + int priceQty; + try { + productQty = Integer.parseInt( + productQtyStr); + priceQty = Integer + .parseInt(priceQtyStr); + } catch (NumberFormatException e) { + p.sendMessage(Component.text( + "invalid quantity provided", + NamedTextColor.RED)); + // reopen + open(p, signBlock, plugin); + return; + } + + if (productQty <= 0 || priceQty <= 0) { + p.sendMessage(Component.text( + "quantities must be positive", + NamedTextColor.RED)); + open(p, signBlock, plugin); + return; + } + + // 2. parse materials + Material productMat = plugin.getSignParser() + .parseMaterial(productStr); + if (productMat == null) { + p.sendMessage(Component.text( + "invalid product item: " + + productStr, + NamedTextColor.RED)); + open(p, signBlock, plugin); + return; + } + + Material priceMat = plugin.getSignParser() + .parseMaterial(priceStr); + if (priceMat == null) { + p.sendMessage(Component.text( + "invalid payment item: " + + priceStr, + NamedTextColor.RED)); + open(p, signBlock, plugin); + return; + } + + // 3. create trade & activation + Trade trade = new Trade(priceMat, priceQty, + productMat, productQty); + PendingActivation activation = new PendingActivation( + p.getUniqueId(), + signBlock.getLocation(), + trade, + System.currentTimeMillis()); + + // 4. finalize shop immediately + plugin.getServer().getScheduler() + .runTask(plugin, () -> { + plugin.getShopActivationListener() + .finalizeShop(p, activation); + }); + }, ClickCallback.Options.builder().uses(1).build())) + .build(), + ActionButton.builder( + Component.text("cancel", TextColor.color(0xFFA0B1))) + .tooltip(Component.text("discard changes")) + .action(DialogAction.customClick((view, audience) -> { + ((Player) audience).sendMessage(Component.text( + "setup cancelled", + NamedTextColor.YELLOW)); + }, ClickCallback.Options.builder().build())) + .build()))); + + player.showDialog(dialog); } - - /* - * private static void handleCallback(DialogResponseView view, Player player, - * Block signBlock, OyeShopsPlugin plugin) { - * String productStr = view.getString("product_item"); - * int productQty = view.getFloat("product_qty").intValue(); - * String priceStr = view.getString("price_item"); - * int priceQty = view.getFloat("price_qty").intValue(); - * - * // 1. parse materials - * Material productMat = plugin.getSignParser().parseMaterial(productStr); - * if (productMat == null) { - * player.sendMessage(Component.text("invalid product item: " + productStr, - * NamedTextColor.RED)); - * return; - * } - * - * Material priceMat = plugin.getSignParser().parseMaterial(priceStr); - * if (priceMat == null) { - * player.sendMessage(Component.text("invalid payment item: " + priceStr, - * NamedTextColor.RED)); - * return; - * } - * - * // 2. create trade & activation - * Trade trade = new Trade(priceMat, priceQty, productMat, productQty); - * PendingActivation activation = new PendingActivation( - * player.getUniqueId(), - * signBlock.getLocation(), - * trade, - * System.currentTimeMillis()); - * - * // 3. finalize shop immediately (skipping chat confirmation since dialog IS - * confirmation) - * plugin.getShopActivationListener().finalizeShop(player, activation); - * } - */ }