瀏覽代碼

Bigger sums of money allowed, Sign Input, prettier confirmation menu

Jan 3 周之前
父節點
當前提交
55263191ff

+ 175 - 0
ReadMe.md

@@ -0,0 +1,175 @@
+# Bazaarflux
+
+**Bazaarflux** is a modular, performance‑oriented Minecraft server plugin designed to build a living player‑driven world. It combines clans, land control, trading, economy systems and automation into one coherent gameplay layer — without unnecessary bloat.
+
+Built for long‑term servers that value progression, cooperation, and strategic depth.
+
+---
+
+## ✨ Core Philosophy
+
+* **Player‑driven economy** – supply and demand emerge naturally
+* **Territorial gameplay** – land ownership actually matters
+* **Automation with limits** – power grows, but never unchecked
+* **Extensible design** – features are built to expand cleanly
+
+---
+
+## 🏰 Clans
+
+Clans are the social and strategic backbone of Bazaarflux.
+
+**Features:**
+
+* Create and manage clans
+* Clan roles with granular permissions
+* Shared clan storage and assets
+* Clan chat & internal coordination
+* Clan‑bound upgrades and systems
+
+Clans are deeply integrated into *claims, economy, trading and minions*.
+
+---
+
+## 🗺️ Claims (Land Control)
+
+Land is power. Bazaarflux introduces a structured claiming system that gives meaning to territory.
+
+**Features:**
+
+* Chunk‑based land claiming
+* Clan‑owned territory
+* Permission‑based interactions (containers, blocks, entities, etc.)
+* Protection against griefing
+* Visual claim borders & feedback
+
+Claims directly influence:
+
+* Minion placement
+* Resource safety
+* Future dungeon access
+
+---
+
+## 💱 Trading System
+
+Bazaarflux introduces a controlled yet flexible trading layer.
+
+**Features:**
+
+* Secure player‑to‑player trades
+* Trade UIs with confirmation stages
+* Item & currency support
+* Anti‑scam mechanisms
+* Fully event‑driven (extensible)
+
+Designed to scale into markets, NPC traders and global exchanges.
+
+---
+
+## 💰 Economy
+
+A lightweight but powerful economy foundation.
+
+**Features:**
+
+* Server currency with precise handling
+* Formatting support (k, M, B, etc.)
+* Economy hooks for all systems
+* Prepared for taxes, upkeep & sinks
+
+The economy is intentionally conservative to prevent inflation and abuse.
+
+---
+
+## 🤖 Minions (Automation)
+
+Minions are semi‑autonomous workers that operate within claimed land.
+
+**Features:**
+
+* Placeable minion entities
+* Owner & clan‑bound permissions
+* Task‑based behavior (gathering, processing, etc.)
+* Inventory & upgrade system
+* GUI‑driven control
+
+Minions are powerful — but limited by land, energy, and upgrades.
+
+---
+
+## 🧩 System Integration
+
+Bazaarflux is not a collection of isolated features.
+
+Every system is interconnected:
+
+* Claims restrict minions
+* Economy balances trading
+* Clans control territory & automation
+* Future content builds on existing foundations
+
+This ensures consistency and long‑term scalability.
+
+---
+
+## 🚀 Upcoming Features
+
+The roadmap is focused on **depth**, not feature spam.
+
+### 🏰 Dungeons & Instances
+
+* Procedurally generated dungeons
+* Instanced worlds per party or clan
+* Loot tied into the economy
+* Boss mechanics & progression
+
+### 🧱 Items & Progression
+
+* Custom items & materials
+* Tiered crafting paths
+* Rare resources from dangerous zones
+
+### 🌍 World Expansion
+
+* Special regions with unique rules
+* PvE & PvP risk‑reward zones
+* Claim‑restricted world events
+
+### 🧠 Advanced Systems
+
+* Clan upkeep & territory costs
+* Economy sinks & balancing mechanics
+* Minion specialization trees
+* Market data & analytics
+
+---
+
+## ⚙️ Technical Highlights
+
+* Optimized for performance
+* Clean, modular architecture
+* Thread‑safe critical systems
+* Designed for large servers
+* Easy to extend via events & APIs
+
+---
+
+## 📦 Status
+
+Bazaarflux is under **active development**.
+Core systems are stable, with new content being layered on top deliberately.
+
+Expect regular updates focused on quality, balance, and long‑term server health.
+
+---
+
+## 📜 License
+
+Private / Server‑bound usage.
+Details to be defined.
+
+---
+
+**Bazaarflux is not about short‑term fun.**
+It is about building a world players want to invest in.

+ 5 - 0
pom.xml

@@ -81,5 +81,10 @@
             <version>2.11.7</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>net.dmulloy2</groupId>
+            <artifactId>ProtocolLib</artifactId>
+            <version>5.4.0</version>
+        </dependency>
     </dependencies>
 </project>

+ 138 - 0
src/main/java/me/lethunderhawk/bazaarflux/util/gui/input/SignMenuFactory.java

@@ -0,0 +1,138 @@
+package me.lethunderhawk.bazaarflux.util.gui.input;
+
+import com.comphenix.protocol.PacketType;
+import com.comphenix.protocol.ProtocolLibrary;
+import com.comphenix.protocol.events.PacketAdapter;
+import com.comphenix.protocol.events.PacketContainer;
+import com.comphenix.protocol.events.PacketEvent;
+import com.comphenix.protocol.wrappers.BlockPosition;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.Plugin;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.BiPredicate;
+
+public final class SignMenuFactory {
+
+    private final Plugin plugin;
+
+    private final Map<Player, Menu> inputs;
+
+    public SignMenuFactory(Plugin plugin) {
+        this.plugin = plugin;
+        this.inputs = new ConcurrentHashMap<>();
+        this.listen();
+    }
+
+    public Menu newMenu(List<String> text) {
+        return new Menu(text);
+    }
+
+    private void listen() {
+        ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(this.plugin, PacketType.Play.Client.UPDATE_SIGN) {
+            @Override
+            public void onPacketReceiving(PacketEvent event) {
+                Player player = event.getPlayer();
+                Menu menu = inputs.remove(player);
+                if (menu == null) return;
+
+                event.setCancelled(true);
+
+                String[] lines = event.getPacket().getStringArrays().read(0);
+
+                Bukkit.getScheduler().runTask(plugin, () -> {
+                    boolean success = menu.response.test(player, lines);
+
+                    if (!success && menu.reopenIfFail && !menu.forceClose) {
+                        Bukkit.getScheduler().runTaskLater(plugin, () -> menu.open(player), 2L);
+                    }
+
+                    if (player.isOnline()) {
+                        player.sendBlockChange(
+                                menu.location,
+                                menu.location.getBlock().getBlockData()
+                        );
+                    }
+                });
+            }
+        });
+    }
+
+    public final class Menu {
+
+        private final List<String> text;
+
+        private BiPredicate<Player, String[]> response;
+        private boolean reopenIfFail;
+
+        private Location location;
+
+        private boolean forceClose;
+
+        Menu(List<String> text) {
+            this.text = text;
+        }
+
+        public Menu reopenIfFail(boolean value) {
+            this.reopenIfFail = value;
+            return this;
+        }
+
+        public Menu response(BiPredicate<Player, String[]> response) {
+            this.response = response;
+            return this;
+        }
+
+        public void open(Player player) {
+            Objects.requireNonNull(player, "player");
+            if (!player.isOnline()) {
+                return;
+            }
+            location = player.getLocation();
+            location.setY(location.getBlockY() - 4);
+
+            player.sendBlockChange(location, Material.OAK_SIGN.createBlockData());
+            player.sendSignChange(
+                    location,
+                    text.stream().map(this::color).toList().toArray(new String[4])
+            );
+
+            PacketContainer openSign = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.OPEN_SIGN_EDITOR);
+            BlockPosition position = new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ());
+            openSign.getBlockPositionModifier().write(0, position);
+            openSign.getBooleans().write(0, true); // ADDED
+            ProtocolLibrary.getProtocolManager().sendServerPacket(player, openSign);
+
+            inputs.put(player, this);
+        }
+
+        /**
+         * closes the menu. if force is true, the menu will close and will ignore the reopen
+         * functionality. false by default.
+         *
+         * @param player the player
+         * @param force  decides whether it will reopen if reopen is enabled
+         */
+        public void close(Player player, boolean force) {
+            this.forceClose = force;
+            if (player.isOnline()) {
+                player.closeInventory();
+            }
+        }
+
+        public void close(Player player) {
+            close(player, false);
+        }
+
+        private String color(String input) {
+            return ChatColor.translateAlternateColorCodes('&', input);
+        }
+    }
+}

+ 0 - 1
src/main/java/me/lethunderhawk/clans/command/ClanCommand.java

@@ -44,7 +44,6 @@ public class ClanCommand implements CommandExecutor, TabCompleter {
         registerCommand("members", "Show the members of your clan", this::handleShowMembers);
         registerCommand("save", "Save all clans and Claims", this::handleSave);
         registerCommand("menu", "Shows a GUI to handle your clan if you are the owner", this::handleGUI);
-
         CommandNode claimNode = registerCommand("claim", "Claim land for your clan", this::handleClaim);
         claimNode.registerSubCommand("info", "Get information about your claims", this::infoClaims);
         claimNode.registerSubCommand("removeAll", "Remove all current claims", this::removeAllClaims);

+ 1 - 1
src/main/java/me/lethunderhawk/clans/gui/AdminMenuGUI.java

@@ -4,7 +4,6 @@ import me.lethunderhawk.bazaarflux.util.gui.InventoryGUI;
 import org.bukkit.entity.Player;
 
 public class AdminMenuGUI extends InventoryGUI {
-
     private final Player player;
 
     public AdminMenuGUI(Player player) {
@@ -19,6 +18,7 @@ public class AdminMenuGUI extends InventoryGUI {
         setCloseButton(31);
     }
 
+
     @Override
     public void update() {
 

+ 1 - 0
src/main/java/me/lethunderhawk/clans/gui/ClaimSettingsGUI.java

@@ -45,6 +45,7 @@ public class ClaimSettingsGUI extends InventoryGUI {
                 }else if(type == ClickType.RIGHT || type == ClickType.SHIFT_RIGHT){
                     ConfirmationMenu confirmationMenu = new ConfirmationMenu("Delete Claim?", (pl) ->{
                         removeClaim(claim);
+                        this.update();
                     });
                     this.openNext(p, confirmationMenu);
                 }

+ 10 - 2
src/main/java/me/lethunderhawk/clans/gui/ConfirmationMenu.java

@@ -1,9 +1,13 @@
 package me.lethunderhawk.clans.gui;
 
 import me.lethunderhawk.bazaarflux.util.gui.InventoryGUI;
+import me.lethunderhawk.main.util.UnItalic;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
 import org.bukkit.Material;
 import org.bukkit.entity.Player;
 import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
 
 import java.util.function.Consumer;
 
@@ -21,14 +25,18 @@ public class ConfirmationMenu extends InventoryGUI {
         fillGlassPaneBackground();
 
         ItemStack IAmSure = new ItemStack(Material.LIME_STAINED_GLASS_PANE);
-
+        ItemMeta meta = IAmSure.getItemMeta();
+        meta.displayName(Component.text("Yes, i am sure", NamedTextColor.GREEN));
+        IAmSure.setItemMeta(UnItalic.removeItalicFromMeta(meta));
         setItemWithClickAction(11, IAmSure, (p, type)->{
             callback.accept(p);
             openPrevious(p);
         });
 
         ItemStack NoPleaseNot = new ItemStack(Material.BARRIER);
-
+        ItemMeta noMeta = NoPleaseNot.getItemMeta();
+        noMeta.displayName(Component.text("No, i changed my mind", NamedTextColor.RED));
+        NoPleaseNot.setItemMeta(UnItalic.removeItalicFromMeta(noMeta));
         setItemWithClickAction(15, NoPleaseNot, (p, type)->{
             openPrevious(p);
         });

+ 8 - 3
src/main/java/me/lethunderhawk/custom/item/CustomItemModule.java

@@ -31,9 +31,8 @@ public class CustomItemModule implements BazaarFluxModule {
     public void onEnable(){
         itemManager = new CustomItemManager(plugin);
         registerCustomItems();
-        CustomItemCommand customItemCommand = new CustomItemCommand(itemManager, this);
-        Main.getInstance().getCommand("customItem").setExecutor(customItemCommand);
-        Main.getInstance().getCommand("customItem").setTabCompleter(customItemCommand);
+        registerCommands();
+
 
         listener = new CustomItemListener(itemManager);
         plugin.getServer().getPluginManager().registerEvents(
@@ -42,6 +41,12 @@ public class CustomItemModule implements BazaarFluxModule {
         );
     }
 
+    private void registerCommands() {
+        CustomItemCommand customItemCommand = new CustomItemCommand(itemManager, this);
+        Main.getInstance().getCommand("customItem").setExecutor(customItemCommand);
+        Main.getInstance().getCommand("customItem").setTabCompleter(customItemCommand);
+    }
+
     @Override
     public void onDisable() {
         HandlerList.unregisterAll(listener);

+ 6 - 5
src/main/java/me/lethunderhawk/economy/api/EconomyAPI.java

@@ -12,23 +12,24 @@ public class EconomyAPI {
     public EconomyAPI(EconomyManager eco) {
         this.eco = eco;
     }
-    public void pay(UUID sender, UUID receiver, int amount){
+
+    public void pay(UUID sender, UUID receiver, long amount){
         eco.pay(sender, receiver, amount);
     }
 
-    public int getMoney(UUID uuid) {
+    public long getMoney(UUID uuid) {
         return eco.getMoney(uuid);
     }
 
-    public void setMoney(UUID uuid, int amount) {
+    public void setMoney(UUID uuid, long amount) {
         eco.setMoney(uuid, amount);
     }
 
-    public void addMoney(UUID uuid, int amount) {
+    public void addMoney(UUID uuid, long amount) {
         eco.addMoney(uuid, amount);
     }
 
-    public void removeMoney(UUID uuid, int amount) {
+    public void removeMoney(UUID uuid, long amount) {
         eco.removeMoney(uuid, amount);
     }
 

+ 2 - 2
src/main/java/me/lethunderhawk/economy/command/EcoCommand.java

@@ -90,7 +90,7 @@ public class EcoCommand implements CommandExecutor, TabCompleter {
         if (target == null) {
             EconomyModule.sendText(commandSender, Component.text("Spieler nicht gefunden.",  NamedTextColor.RED));
         }else{
-            getAPI().addMoney(target.getUniqueId(), Integer.parseInt(strings[1]));
+            getAPI().addMoney(target.getUniqueId(), Long.parseLong(strings[1]));
         }
     }
 
@@ -100,7 +100,7 @@ public class EcoCommand implements CommandExecutor, TabCompleter {
         if (target == null) {
             EconomyModule.sendText(commandSender, Component.text("Spieler nicht gefunden.",  NamedTextColor.RED));
         }else{
-            getAPI().setMoney(target.getUniqueId(), Integer.parseInt(strings[1]));
+            getAPI().setMoney(target.getUniqueId(), Long.parseLong(strings[1]));
         }
     }
     private EconomyAPI getAPI(){

+ 6 - 6
src/main/java/me/lethunderhawk/economy/currency/EconomyManager.java

@@ -15,20 +15,20 @@ public class EconomyManager {
         this.config = module.getPlugin().getConfig();
     }
 
-    public int getMoney(UUID uuid) {
-        return config.getInt("players." + uuid + ".money", 0);
+    public long getMoney(UUID uuid) {
+        return config.getLong("players." + uuid + ".money", 0);
     }
 
-    public void setMoney(UUID uuid, int amount) {
+    public void setMoney(UUID uuid, long amount) {
         config.set("players." + uuid + ".money", amount);
         module.getPlugin().saveConfig();
     }
 
-    public void addMoney(UUID uuid, int amount) {
+    public void addMoney(UUID uuid, long amount) {
         setMoney(uuid, getMoney(uuid) + amount);
     }
 
-    public void removeMoney(UUID uuid, int amount) {
+    public void removeMoney(UUID uuid, long amount) {
         setMoney(uuid, Math.max(0, getMoney(uuid) - amount));
     }
 
@@ -40,7 +40,7 @@ public class EconomyManager {
         return "Bummsbach";
     }
 
-    public void pay(UUID sender, UUID receiver, int amount) {
+    public void pay(UUID sender, UUID receiver, long amount) {
         if(amount > 0 && getMoney(sender) >= amount){
             removeMoney(sender, amount);
             addMoney(receiver, amount);

+ 65 - 0
src/main/java/me/lethunderhawk/economy/util/EconomyUtil.java

@@ -0,0 +1,65 @@
+package me.lethunderhawk.economy.util;
+
+public class EconomyUtil {
+    public static long longFromString(String s) {
+        if (s == null || s.isBlank()) {
+            throw new IllegalArgumentException("Input is null or empty");
+        }
+
+        s = s.trim().toLowerCase();
+
+        long multiplier = 1;
+
+        if (s.endsWith("bil")) {
+            multiplier = 1_000_000_000L;
+            s = s.substring(0, s.length() - 3);
+        } else if (s.endsWith("b")) {
+            multiplier = 1_000_000_000L;
+            s = s.substring(0, s.length() - 1);
+        } else if (s.endsWith("mil")) {
+            multiplier = 1_000_000L;
+            s = s.substring(0, s.length() - 3);
+        } else if (s.endsWith("m")) {
+            multiplier = 1_000_000L;
+            s = s.substring(0, s.length() - 1);
+        } else if (s.endsWith("k")) {
+            multiplier = 1_000L;
+            s = s.substring(0, s.length() - 1);
+        }
+
+        long base;
+        try {
+            base = Long.parseLong(s);
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException("Invalid number: " + s);
+        }
+
+        long result = base * multiplier;
+
+        if (result > Integer.MAX_VALUE) {
+            throw new ArithmeticException("Value exceeds int range");
+        }
+
+        return result;
+    }
+
+    public static String stringFromNumber(long value) {
+        if (value < 0) {
+            throw new IllegalArgumentException("Negative values not supported");
+        }
+
+        if (value % 1_000_000_000L == 0 && value >= 1_000_000_000L) {
+            return (value / 1_000_000_000L) + "b";
+        }
+
+        if (value % 1_000_000L == 0 && value >= 1_000_000L) {
+            return (value / 1_000_000L) + "m";
+        }
+
+        if (value % 1_000L == 0 && value >= 1_000L) {
+            return (value / 1_000L) + "k";
+        }
+
+        return Long.toString(value);
+    }
+}

+ 0 - 2
src/main/java/me/lethunderhawk/tradeplugin/input/player/SignInputGUI.java

@@ -1,2 +0,0 @@
-package me.lethunderhawk.tradeplugin.input.player;
-

+ 0 - 93
src/main/java/me/lethunderhawk/tradeplugin/input/player/SignInputManager.java

@@ -1,93 +0,0 @@
-package me.lethunderhawk.tradeplugin.input.player;
-
-import net.kyori.adventure.text.Component;
-import org.bukkit.Bukkit;
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.block.Block;
-import org.bukkit.block.BlockState;
-import org.bukkit.block.Sign;
-import org.bukkit.block.data.BlockData;
-import org.bukkit.block.sign.Side;
-import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.block.SignChangeEvent;
-import org.bukkit.plugin.Plugin;
-
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.BiConsumer;
-
-public class SignInputManager implements Listener {
-
-    private final Plugin plugin;
-
-    private record Session(
-            Location location,
-            BiConsumer<Player, String> callback,
-            Material oldType,
-            BlockData oldData
-    ) {}
-
-    private final Map<UUID, Session> sessions = new ConcurrentHashMap<>();
-
-    public SignInputManager(Plugin plugin) {
-        this.plugin = plugin;
-        Bukkit.getPluginManager().registerEvents(this, plugin);
-    }
-
-    public void openSignInput(Player player, BiConsumer<Player, String> callback) {
-        Location loc = getSignLocation(player);
-        Block block = loc.getBlock();
-
-        Material oldType = block.getType();
-        BlockData oldData = block.getBlockData();
-
-        block.setBlockData(Bukkit.createBlockData(Material.OAK_SIGN), false);
-
-        BlockState state = block.getState();
-        if (!(state instanceof Sign sign)) {
-            restoreBlock(block, oldType, oldData);
-            return;
-        }
-
-        // preset lines (optional)
-        sign.getSide(Side.FRONT).line(0, Component.text(""));
-        sign.getSide(Side.FRONT).line(1, Component.text("^^^^^^^^^^"));
-        sign.getSide(Side.FRONT).line(2, Component.text("Wieviel Flux"));
-        sign.getSide(Side.FRONT).line(3, Component.text("willst du traden?"));
-        sign.update(true, false);
-
-        sessions.put(player.getUniqueId(),
-                new Session(loc, callback, oldType, oldData));
-
-        player.openSign(sign, Side.FRONT);
-
-    }
-
-    private Location getSignLocation(Player player) {
-        // high up so nobody sees it and no entities collide
-        return player.getWorld().getHighestBlockAt(player.getLocation()).getLocation().add(0,30,0);
-    }
-
-    @EventHandler
-    public void onSignChange(SignChangeEvent event) {
-        Player player = event.getPlayer();
-        Session session = sessions.remove(player.getUniqueId());
-        if (session == null) return;
-
-        // collect input
-        String input = event.getLine(0);
-
-        Block block = session.location().getBlock();
-        restoreBlock(block, session.oldType(), session.oldData());
-        session.callback().accept(player, input);
-    }
-
-    private void restoreBlock(Block block, Material type, BlockData data) {
-        block.setType(type, false);
-        block.setBlockData(data, false);
-    }
-}

+ 36 - 45
src/main/java/me/lethunderhawk/tradeplugin/listener/InventoryListener.java

@@ -1,9 +1,10 @@
 package me.lethunderhawk.tradeplugin.listener;
 
+import me.lethunderhawk.bazaarflux.util.gui.input.SignMenuFactory;
 import me.lethunderhawk.economy.EconomyModule;
+import me.lethunderhawk.economy.util.EconomyUtil;
 import me.lethunderhawk.main.Main;
 import me.lethunderhawk.tradeplugin.TradeModule;
-import me.lethunderhawk.tradeplugin.input.player.NumberInputGUI;
 import me.lethunderhawk.tradeplugin.trade.TradeInventory;
 import me.lethunderhawk.tradeplugin.trade.TradeManager;
 import me.lethunderhawk.tradeplugin.trade.TradeSession;
@@ -16,11 +17,12 @@ import org.bukkit.event.EventHandler;
 import org.bukkit.event.Listener;
 import org.bukkit.event.inventory.InventoryClickEvent;
 import org.bukkit.event.inventory.InventoryCloseEvent;
-import org.bukkit.event.inventory.InventoryType;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.meta.ItemMeta;
 import org.bukkit.persistence.PersistentDataType;
 
+import java.util.List;
+
 import static me.lethunderhawk.tradeplugin.trade.TradeSession.getFluxKey;
 import static me.lethunderhawk.tradeplugin.trade.TradeSession.getValueKey;
 
@@ -38,9 +40,6 @@ public class InventoryListener implements Listener {
         if (!(e.getWhoClicked() instanceof Player p)) return;
         TradeSession session = manager.getSession(p);
         if (session == null) return;
-        if(e.getInventory().getType() == InventoryType.ANVIL) return;
-
-
         int slot = e.getRawSlot();
         if (!session.getTradeInventory().isValidInventoryClick(slot)) {
             e.setCancelled(true);
@@ -48,19 +47,17 @@ public class InventoryListener implements Listener {
         }else if (session.getTradeInventory().isInsideOwnTradeMenu(slot)) {
             ItemStack item = e.getCurrentItem();
             e.setCancelled(true);
-
             if (item == null) return;
-
             ItemMeta meta = item.getItemMeta();
             if (meta != null && meta.getPersistentDataContainer()
                     .has(getFluxKey(), PersistentDataType.INTEGER)) {
 
                 // ---- Flux item clicked ----
-                Integer value = meta.getPersistentDataContainer()
-                        .get(getValueKey(), PersistentDataType.INTEGER);
+                Long value = meta.getPersistentDataContainer()
+                        .get(getValueKey(), PersistentDataType.LONG);
 
                 if (value != null) {
-                    session.removeFlux(p, value);     // update numbers
+                    session.removeFlux(p, value);
                 }
 
                 // Remove the display item from trade UI
@@ -78,12 +75,9 @@ public class InventoryListener implements Listener {
 
         if (slot == TradeInventory.ACCEPT_SLOT) {
             e.setCancelled(true);
-
             if(session.accept(p)) {
                 session.undoAccept(p);
             }
-
-
             if (session.getTradeState() == TradeState.COMPLETED) {
                 manager.endTrade(session, true);
                 return;
@@ -93,36 +87,7 @@ public class InventoryListener implements Listener {
 
         if (slot == TradeInventory.FLUX_SLOT) {
             e.setCancelled(true);
-            new NumberInputGUI(
-                    Main.getInstance(),
-                    p,
-                    "§6Zahleneingabe",
-                    0,
-                    EconomyModule.getInstance().getEconomyAPI().getMoney(p.getUniqueId()) - manager.getSession(p).getMoneyFor(p),
-                    0,
-                    (player, value) -> {
-                        TradeSession originalSession = manager.getSession(player);
-                        if (value != null && value > 0) {
-                            if(EconomyModule.getInstance().getEconomyAPI().getMoney(player.getUniqueId()) >= value){
-                                if(originalSession.addFluxValue(player, value)){
-                                    TradeModule.sendText(player, Component.text("Added " + value + " Flux to the trade"));
-                                }else{
-                                    TradeModule.sendText(player, Component.text("No free space in menu!"));
-                                }
-                            }else{
-                                TradeModule.sendText(player,Component.text("You don't have enough money!", NamedTextColor.RED));
-                            }
-                        } else {
-                            TradeModule.sendText(player,Component.text("!", NamedTextColor.RED));
-                        }
-                        player.openInventory(originalSession.getTradeInventory().getInventoryFor(player));
-                    }
-            ).open();
-//            SignInputManager signInput = new SignInputManager(Main.getInstance());
-//            signInput.openSignInput(p, (player, text) -> {
-//                player.sendMessage("Du hast eingegeben: " + text);
-//                // parse ints, handle input …
-//            });
+            openSignMenu(p);
             return;
         }
         if(slot >= TradeInventory.TRADE_INV_SIZE){
@@ -136,11 +101,38 @@ public class InventoryListener implements Listener {
                     e.setCancelled(true);
                 }
             }
-            return;
         }
 
     }
 
+    private void openSignMenu(Player p) {
+        SignMenuFactory.Menu signInput = new SignMenuFactory(Main.getInstance()).newMenu(List.of("", "^^^^^^^^^^^^", "Input the amount", "to trade"))
+                .reopenIfFail(true)
+                .response((player, input) -> {
+                    long value = EconomyUtil.longFromString(input[0]);
+                    TradeSession originalSession = manager.getSession(player);
+                    if (value > 0) {
+                        if(EconomyModule.getInstance().getEconomyAPI().getMoney(player.getUniqueId()) >= originalSession.getMoneyFor(p) + value){
+                            if(originalSession.addFluxValue(player, value)){
+                                player.openInventory(originalSession.getTradeInventory().getInventoryFor(player));
+                            }else{
+                                TradeModule.sendText(player, Component.text("No free space in menu!"));
+                                return false;
+                            }
+                        }else{
+                            TradeModule.sendText(player,Component.text("You don't have enough money!", NamedTextColor.RED));
+                            return false;
+                        }
+                    } else {
+                        TradeModule.sendText(player,Component.text("You cant pay negative amounts!!", NamedTextColor.RED));
+                        return false;
+                    }
+                    player.openInventory(originalSession.getTradeInventory().getInventoryFor(player));
+                    return true;
+                });
+        signInput.open(p);
+    }
+
     @EventHandler
     public void onInventoryClose(InventoryCloseEvent e) {
         Player p = (Player) e.getPlayer();
@@ -150,6 +142,5 @@ public class InventoryListener implements Listener {
                 && e.getReason() != InventoryCloseEvent.Reason.OPEN_NEW) {
             manager.endTrade(session, false);
         }
-//        p.sendMessage("Reason: " + e.getReason() + ", Type: " + e.getInventory().getType());
     }
 }

+ 17 - 15
src/main/java/me/lethunderhawk/tradeplugin/trade/TradeSession.java

@@ -1,5 +1,6 @@
 package me.lethunderhawk.tradeplugin.trade;
 
+import me.clip.placeholderapi.PlaceholderAPI;
 import me.lethunderhawk.economy.EconomyModule;
 import me.lethunderhawk.main.Main;
 import me.lethunderhawk.main.util.UnItalic;
@@ -35,7 +36,7 @@ public class TradeSession {
             new NamespacedKey(Main.getInstance(), "flux_value");
 
     private TradeState state = TradeState.WAITING;
-    private int p1Flux = 0, p2Flux = 0;
+    private long p1Flux = 0, p2Flux = 0;
 
     private final TradeInventory inventory;
 
@@ -167,7 +168,7 @@ public class TradeSession {
         }
     }
 
-    private void sendFluxTransfer(int flux, Audience giver, Audience receiver) {
+    private void sendFluxTransfer(long flux, Audience giver, Audience receiver) {
         if (flux <= 0) return;
 
         Component fluxComp = Component.text(flux)
@@ -212,6 +213,7 @@ public class TradeSession {
 
     public void removeItem(Player p, ItemStack item, int mySlot) {
         if(item == null) return;
+
         if (p.equals(p1)) {
             if(inventory.removeItem(p1, item, mySlot)){
                 p1Items.remove(item);
@@ -227,20 +229,19 @@ public class TradeSession {
         this.state = state;
     }
 
-    public int getMoneyFor(Player p) {
+    public long getMoneyFor(Player p) {
         if(p1.getUniqueId().equals(p.getUniqueId())){
             return p1Flux;
         }
         if(p2.getUniqueId().equals(p.getUniqueId())){
-          return p2Flux;
+            return p2Flux;
         }
         return 0;
     }
 
-    public boolean addFluxValue(Player player, int value) {
+    public boolean addFluxValue(Player player, long value) {
 
         if(p1.getUniqueId().equals(player.getUniqueId())){
-
             if(addCosmeticItem(p1, getCosmeticFlux(p1, value))){
                 p1Flux += value;
                 refreshAllFlux();
@@ -258,7 +259,7 @@ public class TradeSession {
     }
 
 
-    public ItemStack getCosmeticFlux(Player owner, int value) {
+    public ItemStack getCosmeticFlux(Player owner, long value) {
         ItemStack item = TradeInventory.getFluxItemStack();
         SkullMeta meta = (SkullMeta) item.getItemMeta();
 
@@ -266,17 +267,18 @@ public class TradeSession {
 
         meta.getPersistentDataContainer().set(FLUX_KEY, PersistentDataType.INTEGER, 1);
         meta.getPersistentDataContainer().set(OWNER_KEY, PersistentDataType.STRING, owner.getUniqueId().toString());
-        meta.getPersistentDataContainer().set(VALUE_KEY, PersistentDataType.INTEGER, value);
+        meta.getPersistentDataContainer().set(VALUE_KEY, PersistentDataType.LONG, value);
 
-        int total = TradeModule.getTradeManager()
-                .getSession(owner)
-                .getMoneyFor(owner);
+        String totalFlux = PlaceholderAPI.setPlaceholders(
+                owner,
+                "%trade_flux_total%"
+        );
 
         meta.lore(List.of(
                 UnItalic.removeItalic(Component.text("Lup-sum amount", NamedTextColor.GRAY)),
                 UnItalic.removeItalic(Component.text("", NamedTextColor.GRAY)),
                 UnItalic.removeItalic(Component.text("Total Flux Offered: ", NamedTextColor.GOLD)),
-                UnItalic.removeItalic(Component.text(String.valueOf(total), NamedTextColor.GRAY))
+                UnItalic.removeItalic(Component.text(totalFlux, NamedTextColor.GRAY))
         ));
 
         item.setItemMeta(meta);
@@ -295,7 +297,7 @@ public class TradeSession {
             if (!pdc.has(FLUX_KEY, PersistentDataType.INTEGER)) continue;
 
             UUID ownerId = UUID.fromString(pdc.get(OWNER_KEY, PersistentDataType.STRING));
-            int value = pdc.get(VALUE_KEY, PersistentDataType.INTEGER);
+            long value = pdc.get(VALUE_KEY, PersistentDataType.LONG);
 
             Player owner = ownerId.equals(getP1().getUniqueId())
                     ? getP1()
@@ -328,7 +330,7 @@ public class TradeSession {
         return VALUE_KEY;
     }
 
-    public void removeFlux(Player p, int value) {
+    public void removeFlux(Player p, long value) {
         if (p.equals(p1)) {
             p1Flux -= value;
             if (p1Flux < 0) p1Flux = 0;
@@ -345,4 +347,4 @@ public class TradeSession {
     public boolean isP1(Player p) {
         return p1.equals(p);
     }
-}
+}

+ 7 - 1
src/main/resources/config.yml

@@ -1,2 +1,8 @@
+bazaarflux:
+  clans: enabled
+  eco: enabled
+  trading: enabled
+  minions: enabled
+
 claims:
-  max-blocks: 25000
+  max-blocks: 25000