From a11d7c77dcd2695a7d4d88ab4b03f037a271668a Mon Sep 17 00:00:00 2001 From: Semih Kaiser Date: Fri, 13 Feb 2026 21:21:15 +0100 Subject: [PATCH] Item Send function --- .gitignore | 39 ++++++++ pom.xml | 61 ++++++++++++ .../de/oryfox/plugins/InventoryTools.java | 20 ++++ .../plugins/event/SendItemCommandEvent.java | 92 +++++++++++++++++++ .../de/oryfox/plugins/helpers/HeadItem.java | 45 +++++++++ .../de/oryfox/plugins/helpers/NullHelper.java | 7 ++ .../oryfox/plugins/menu/PlayerSelectMenu.java | 4 + src/main/resources/paper-plugin.yml | 4 + 8 files changed, 272 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/de/oryfox/plugins/InventoryTools.java create mode 100644 src/main/java/de/oryfox/plugins/event/SendItemCommandEvent.java create mode 100644 src/main/java/de/oryfox/plugins/helpers/HeadItem.java create mode 100644 src/main/java/de/oryfox/plugins/helpers/NullHelper.java create mode 100644 src/main/java/de/oryfox/plugins/menu/PlayerSelectMenu.java create mode 100644 src/main/resources/paper-plugin.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..480bdf5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ +.kotlin + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..76f1358 --- /dev/null +++ b/pom.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + + de.oryfox.plugins + inventory-tools + 1.0-SNAPSHOT + + + 25 + 25 + UTF-8 + + + + + papermc + https://repo.papermc.io/repository/maven-public/ + + + + + + io.papermc.paper + paper-api + 1.21.11-R0.1-SNAPSHOT + provided + + + dev.triumphteam + triumph-gui + 3.1.13 + + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.1 + + + package + + shade + + + false + ${project.artifactId} + + + + + + + + \ No newline at end of file diff --git a/src/main/java/de/oryfox/plugins/InventoryTools.java b/src/main/java/de/oryfox/plugins/InventoryTools.java new file mode 100644 index 0000000..aa725bd --- /dev/null +++ b/src/main/java/de/oryfox/plugins/InventoryTools.java @@ -0,0 +1,20 @@ +package de.oryfox.plugins; + +import de.oryfox.plugins.event.SendItemCommandEvent; +import io.papermc.paper.command.brigadier.Commands; +import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents; +import org.bukkit.plugin.java.JavaPlugin; + +public class InventoryTools extends JavaPlugin { + @Override + public void onEnable() { + super.onEnable(); + this.getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, commands -> { + commands.registrar().register( + Commands + .literal("sendItem") + .executes(SendItemCommandEvent::openPlayerSelectionMenu) + .build()); + }); + } +} diff --git a/src/main/java/de/oryfox/plugins/event/SendItemCommandEvent.java b/src/main/java/de/oryfox/plugins/event/SendItemCommandEvent.java new file mode 100644 index 0000000..2634a22 --- /dev/null +++ b/src/main/java/de/oryfox/plugins/event/SendItemCommandEvent.java @@ -0,0 +1,92 @@ +package de.oryfox.plugins.event; + +import com.mojang.brigadier.context.CommandContext; +import de.oryfox.plugins.helpers.HeadItem; +import dev.triumphteam.gui.builder.item.ItemBuilder; +import dev.triumphteam.gui.guis.Gui; +import dev.triumphteam.gui.guis.GuiItem; +import dev.triumphteam.gui.guis.ScrollingGui; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; + +public class SendItemCommandEvent { + public static int openPlayerSelectionMenu(CommandContext ctx) { + if (ctx.getSource().getExecutor() == null) { + throw new IllegalStateException("Command can only be executed by a player"); + } + if (Bukkit.getOnlinePlayers().size() <= 1) { + ctx.getSource().getSender().sendMessage(Component.text("No other players online")); + return 0; + } + if (ctx.getSource().getExecutor() instanceof Player player) { + ScrollingGui gui = Gui.scrolling() + .title(Component.text("Select recipient!")) + .rows(3) + .pageSize(18) + .create(); + + Bukkit.getOnlinePlayers() + .stream() + .filter(p -> !p.getUniqueId().equals(player.getUniqueId())) + .forEach(p -> gui.addItem(new HeadItem(p.getPlayerProfile(), event -> { + event.getClickedInventory().close(); + openItemSelectionMenu(player, p); + }))); + + gui.setDefaultClickAction(event -> event.setCancelled(true)); + gui.setItem(3, 3, new HeadItem(HeadItem.ARROW_UP, _ -> gui.previous())); + gui.setItem(3, 7, new HeadItem(HeadItem.ARROW_DOWN, _ -> gui.next())); + gui.getFiller().fillBottom(ItemBuilder.from(Material.BLACK_STAINED_GLASS_PANE).asGuiItem()); + + gui.open(player); + + return 0; + } else { + throw new IllegalStateException("Command can only be executed by a player"); + } + } + + public static void openItemSelectionMenu(Player player, Player recipient) { + Gui gui = Gui.gui() + .title(Component.text("Select items to send to " + recipient.getName())) + .rows(6) + .create(); + + gui.setItem(6, 1, ItemBuilder.from(Material.RED_STAINED_GLASS_PANE).name(Component.text("Cancel")).asGuiItem(event -> cancelSend(event, gui, player))); + gui.setItem(6, 9, ItemBuilder.from(Material.GREEN_STAINED_GLASS_PANE).name(Component.text("Send Items")).asGuiItem(event -> sendItems(event, gui, player, recipient))); + gui.getFiller().fillBottom(new GuiItem(Material.BLACK_STAINED_GLASS_PANE)); + + gui.open(player); + } + + public static void sendItems(InventoryClickEvent event, Gui gui, Player player, Player recipient) { + event.setCancelled(true); + gui.close(player); + if (recipient.isOnline()) { + dropAtPlayer(recipient, gui.getInventory().getStorageContents()); + player.sendMessage(Component.text("Sent items to " + recipient.getName())); + } else { + dropAtPlayer(player, gui.getInventory().getStorageContents()); + player.sendMessage(Component.text("Recipient is no longer online, so we dropped your items at your location")); + } + } + + private static void dropAtPlayer(Player player, ItemStack[] stacks) { + var location = player.getLocation(); + for (ItemStack stack : stacks) { + location.getWorld().dropItem(location, stack); + } + } + + private static void cancelSend(InventoryClickEvent event, Gui gui, Player player) { + event.setCancelled(true); + gui.close(player); + dropAtPlayer(player, gui.getInventory().getStorageContents()); + player.sendPlainMessage("Cancelled sending items to " + player.getName()); + } +} diff --git a/src/main/java/de/oryfox/plugins/helpers/HeadItem.java b/src/main/java/de/oryfox/plugins/helpers/HeadItem.java new file mode 100644 index 0000000..f724f4f --- /dev/null +++ b/src/main/java/de/oryfox/plugins/helpers/HeadItem.java @@ -0,0 +1,45 @@ +package de.oryfox.plugins.helpers; + +import com.destroystokyo.paper.profile.PlayerProfile; +import dev.triumphteam.gui.components.GuiAction; +import dev.triumphteam.gui.guis.GuiItem; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; + +import java.net.MalformedURLException; +import java.net.URI; +import java.util.UUID; + +public class HeadItem extends GuiItem { + + public static final PlayerProfile ARROW_UP = profile("https://textures.minecraft.net/texture/ac5c7e53695d88f4d31f52f43fac609ad9e62bc97d49fc504174dfdb84150c39", "Previous"); + public static final PlayerProfile ARROW_DOWN = profile("https://textures.minecraft.net/texture/8c89aa29cb50359c9ac573e86c8eb0721197796cfab43ff5ce173385b9df2ed1", "Next"); + + public static PlayerProfile profile(String url, String displayName) { + var profile = Bukkit.createProfile(UUID.randomUUID(), displayName); + var textures = profile.getTextures(); + try { + textures.setSkin(URI.create(url).toURL()); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + profile.setTextures(textures); + return profile; + } + + public HeadItem(PlayerProfile profile, GuiAction action) { + var itemStack = new ItemStack(Material.PLAYER_HEAD); + itemStack.editMeta((meta) -> { + if (meta instanceof SkullMeta skullMeta) { + skullMeta.setPlayerProfile(profile); + skullMeta.displayName(Component.text(NullHelper.or(profile.getName(), "Unknown Player"))); + } + }); + super(itemStack); + setAction(action); + } +} diff --git a/src/main/java/de/oryfox/plugins/helpers/NullHelper.java b/src/main/java/de/oryfox/plugins/helpers/NullHelper.java new file mode 100644 index 0000000..9878974 --- /dev/null +++ b/src/main/java/de/oryfox/plugins/helpers/NullHelper.java @@ -0,0 +1,7 @@ +package de.oryfox.plugins.helpers; + +public class NullHelper { + public static String or(String value, String defaultValue) { + return value == null ? defaultValue : value; + } +} diff --git a/src/main/java/de/oryfox/plugins/menu/PlayerSelectMenu.java b/src/main/java/de/oryfox/plugins/menu/PlayerSelectMenu.java new file mode 100644 index 0000000..a79b0fc --- /dev/null +++ b/src/main/java/de/oryfox/plugins/menu/PlayerSelectMenu.java @@ -0,0 +1,4 @@ +package de.oryfox.plugins.menu; + +public class PlayerSelectMenu { +} diff --git a/src/main/resources/paper-plugin.yml b/src/main/resources/paper-plugin.yml new file mode 100644 index 0000000..38b0432 --- /dev/null +++ b/src/main/resources/paper-plugin.yml @@ -0,0 +1,4 @@ +name: Inventory-Tools +version: 1.0.0 +main: de.oryfox.plugins.InventoryTools +api-version: '1.21' \ No newline at end of file