diff --git a/src/README.md b/src/README.md new file mode 100644 index 0000000..11f4805 --- /dev/null +++ b/src/README.md @@ -0,0 +1,26 @@ +# DemonOrder +一款量身为斗魂帝国打造的订单插件 + +## 快速开始 +1.将插件放入`/plugins`目录下 + +2.使用命令`/plugman load DemonOrder` 载入插件 + +3.插件会自动生成config.yml配置文件,根据参考进行配置 + +4.管理员命令 `/dorder` 输入后查看指令帮助 + +5.使用命令 `/wys` 玩家可打开订单签收界面 + + +## 其他说明 +- 前置插件 `DemonAPI` +- 支持自动分配台币、人民币订单 +- 支持发送`DemonGroupShop`等自定义命令的礼包订单 +- 玩家进入时自动提醒玩家签收订单 + +————————————————————————————————————— +# 更新日志 + +## [1.0.0] - 2025-07-19 +### 插件首次发布 \ No newline at end of file diff --git a/src/main/java/com/yaohun/order/OrderMain.java b/src/main/java/com/yaohun/order/OrderMain.java index fd89c36..b48f68d 100644 --- a/src/main/java/com/yaohun/order/OrderMain.java +++ b/src/main/java/com/yaohun/order/OrderMain.java @@ -1,7 +1,13 @@ package com.yaohun.order; +import com.yaohun.order.api.OrderAPI; +import com.yaohun.order.config.Config; +import com.yaohun.order.gui.ReceiveGui; +import com.yaohun.order.listener.PlayerListener; +import com.yaohun.order.manage.OrderManager; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; public class OrderMain extends JavaPlugin { @@ -12,13 +18,67 @@ public class OrderMain extends JavaPlugin { @Override public void onEnable() { instance = this; + saveDefaultConfig(); + Config.reloadConfig(this); + OrderManager.initOrderManager(); + getServer().getPluginManager().registerEvents(new ReceiveGui(),this); + getServer().getPluginManager().registerEvents(new PlayerListener(),this); + } + + @Override + public void onDisable() { + OrderManager.saveOrderManager(); } @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if(!sender.isOp()) { + if("wys".equalsIgnoreCase(label)){ + if(sender instanceof Player){ + ReceiveGui.OpenGui((Player) sender); + } return true; } + if("dorder".equalsIgnoreCase(label)) { + if (!sender.isOp()) { + return true; + } + if (args.length == 0) { + sender.sendMessage(""); + sender.sendMessage("§e------- ======= §6赞助订单管理 §e======= -------"); + sender.sendMessage("§2/"+label+" §e[玩家] §2<金额> §f- §2创建订单"); + sender.sendMessage("§2/"+label+" §e[玩家] §2<金额> §btrue §f- §2创建大陆订单"); + sender.sendMessage("§2/"+label+" kit §e[玩家] §2<礼包> §f- §2创建礼包订单"); + sender.sendMessage("§2/"+label+" reload §f- §2重载配置"); + sender.sendMessage("§e------- ======= §6赞助订单管理 §e======= -------"); + sender.sendMessage(""); + return true; + } + if("reload".equalsIgnoreCase(args[0])){ + Config.reloadConfig(this); + sender.sendMessage("[订单管理] 配置文件已重载."); + return true; + } + if(args.length == 3 && "kit".equalsIgnoreCase(args[0])){ + String playerName = args[1]; + String kitName = args[2]; + if(Config.getOrderContent(kitName) == null){ + sender.sendMessage("[订单管理] 礼包 "+kitName+" 尚未创建.(需在config.yml中添加)"); + return true; + } + OrderAPI.createKitOrder(sender, playerName, kitName); + return true; + } + if(args.length >= 2){ + String playerName = args[0]; + int money = Integer.parseInt(args[1]); + if(args.length >= 3){ + OrderAPI.createOrder(sender, playerName, "CN", money); + } else { + OrderAPI.createOrder(sender, playerName, "TW", money); + } + return true; + } + } return false; } diff --git a/src/main/java/com/yaohun/order/api/OrderAPI.java b/src/main/java/com/yaohun/order/api/OrderAPI.java new file mode 100644 index 0000000..3cb8638 --- /dev/null +++ b/src/main/java/com/yaohun/order/api/OrderAPI.java @@ -0,0 +1,112 @@ +package com.yaohun.order.api; + +import com.yaohun.order.OrderMain; +import com.yaohun.order.config.Config; +import com.yaohun.order.data.OrderContent; +import com.yaohun.order.data.OrderData; +import com.yaohun.order.listener.PlayerListener; +import com.yaohun.order.manage.OrderManager; +import com.yaohun.order.util.OrderAllocator; +import me.Demon.DemonPlugin.DemonAPI; +import me.Demon.DemonPlugin.Util.RandomUtil; +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OrderAPI { + public static void createOrder(CommandSender sender,String playerName,String currencyType,int currency){ + String orderNumber = RandomUtil.getRandomInt(100000,800000)+""+RandomUtil.getRandomInt(100000,800000); + OrderData orderData = new OrderData(orderNumber, playerName,sender.getName(), currencyType, currency); + OrderManager.setOrderDataMap(orderData); + sender.sendMessage("[订单创建] 管理: "+sender.getName()+" 玩家: "+playerName+" 金额: "+currency+"&"+currencyType); + } + + public static void createKitOrder(CommandSender sender,String playerName,String kitType){ + String orderNumber = RandomUtil.getRandomInt(100000,800000)+""+RandomUtil.getRandomInt(100000,800000); + OrderData orderData = new OrderData(orderNumber, playerName,sender.getName(), "Kit#"+kitType, -1); + OrderManager.setOrderDataMap(orderData); + sender.sendMessage("[订单创建] 管理: "+sender.getName()+" 玩家: "+playerName+" 礼包: "+kitType); + } + + + public static void executeOrder(Player player){ + String playerName = player.getName(); + HashMap hashMap = new HashMap<>(OrderManager.getOrderDataMap()); + boolean d = false; + for (OrderData orderData : hashMap.values()){ + if(orderData.getPlayerName().equalsIgnoreCase(playerName)){ + d = true; + String orderNumber = orderData.getOrderNumber(); + String currencyType = orderData.getCurrencyType(); + if(currencyType.contains("Kit#")){ + String[] strings = currencyType.split("#"); + String kitName = strings[1]; + if(!DemonAPI.hasEmptyInventorySlots(player,15)) { + player.sendMessage("§7[§6官方商城§7] §c你需要為禮包預留<§b§l15個>§c背包空位,才能簽收."); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO,0.8f,1.2f); + return; + } + OrderContent orderContent = Config.getOrderContent(kitName); + if(orderContent == null){ + Bukkit.getConsoleSender().sendMessage("[订单管理] 玩家: "+playerName+" 礼包订单: "+kitName+" 尚未执行"); + continue; + } + orderContent.carryOut(playerName); + }else if("CN".equalsIgnoreCase(currencyType)){ + Map shopList = OrderAllocator.allocateOrdersCN(Config.getOrderContentList(), orderData.getMoney()); + for (String key : shopList.keySet()){ + int number = shopList.get(key); + if(key.contains("Coins_Custom")){ + Bukkit.dispatchCommand(Bukkit.getConsoleSender(),"dcoins give "+playerName+" "+number); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(),"kpay give "+playerName+" "+number); + } else { + OrderContent orderContent = Config.getOrderContent(key); + if(orderContent == null){ + Bukkit.getConsoleSender().sendMessage("[订单管理] 玩家: "+playerName+" 订单: "+key+" 尚未执行"); + continue; + } + for (int i = 0; i < number; i++) { + Bukkit.getScheduler().runTaskLater(OrderMain.inst(), () -> { + orderContent.carryOut(playerName); + },i*10L); + } + } + } + } else { + Map shopList = OrderAllocator.allocateOrdersTW(Config.getOrderContentList(), orderData.getMoney()); + for (String key : shopList.keySet()){ + int number = shopList.get(key); + if(key.contains("Coins_Custom")){ + Bukkit.dispatchCommand(Bukkit.getConsoleSender(),"dcoins give "+playerName+" "+number); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(),"kpay give "+playerName+" "+number); + } else { + OrderContent orderContent = Config.getOrderContent(key); + if(orderContent == null){ + Bukkit.getConsoleSender().sendMessage("[订单管理] 玩家: "+playerName+" 订单: "+key+" 尚未执行"); + continue; + } + for (int i = 0; i < number; i++) { + Bukkit.getScheduler().runTaskLater(OrderMain.inst(), () -> { + orderContent.carryOut(playerName); + },i*10L); + } + } + } + } + player.sendMessage("§7[§6官方商城§7] §f您的訂單: "+orderNumber+" 處理完成"); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO,0.8f,1.2f); + OrderManager.signUpOrderData(orderData); + break; + } + } + if(!d) { + player.sendMessage("§7[§6官方商城§7] §c沒有查詢到與你相關的商品訂單."); + } + } + +} diff --git a/src/main/java/com/yaohun/order/config/Config.java b/src/main/java/com/yaohun/order/config/Config.java new file mode 100644 index 0000000..1b15bab --- /dev/null +++ b/src/main/java/com/yaohun/order/config/Config.java @@ -0,0 +1,50 @@ +package com.yaohun.order.config; + +import com.yaohun.order.OrderMain; +import com.yaohun.order.data.OrderContent; +import org.bukkit.Bukkit; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class Config { + + private static List orderContentList = new ArrayList<>(); + + public static void reloadConfig(OrderMain plugin){ + plugin.reloadConfig(); + plugin.saveConfig(); + FileConfiguration config = plugin.getConfig(); + loadOrderData(config); + } + + private static void loadOrderData(FileConfiguration config){ + ConfigurationSection section = config.getConfigurationSection("OrderContent"); + if(section == null) { + return; + } + for (String key : section.getKeys(false)){ + int tw = section.getInt(key + ".tw"); + int cn = section.getInt(key + ".cn"); + List stringList = section.getStringList(key + ".command"); + orderContentList.add(new OrderContent(key, tw, cn, stringList)); + } + Bukkit.getConsoleSender().sendMessage("§b[订单管理] §7载入订单组: §f"+orderContentList.size()+"个"); + } + + public static List getOrderContentList() { + return orderContentList; + } + + public static OrderContent getOrderContent(String key) { + for (OrderContent orderContent : orderContentList) { + if (orderContent.getKey().equals(key)) { + return orderContent; + } + } + return null; + } +} diff --git a/src/main/java/com/yaohun/order/data/OrderContent.java b/src/main/java/com/yaohun/order/data/OrderContent.java new file mode 100644 index 0000000..65b9c57 --- /dev/null +++ b/src/main/java/com/yaohun/order/data/OrderContent.java @@ -0,0 +1,41 @@ +package com.yaohun.order.data; + +import org.bukkit.Bukkit; + +import java.util.List; + +public class OrderContent { + + private String key; + + public int twPreic; + + public int cnPrice; + + private List stringList; + + public OrderContent(String key, int tw, int cn, List stringList) { + this.key = key; + this.twPreic = tw; + this.cnPrice = cn; + this.stringList = stringList; + } + + public String getKey() { + return key; + } + + public int getCn() { + return cnPrice; + } + + public int getTw() { + return twPreic; + } + + public void carryOut(String playerName){ + for(String command : stringList){ + Bukkit.dispatchCommand(Bukkit.getConsoleSender(),command.replace("{player}", playerName)); + } + } +} diff --git a/src/main/java/com/yaohun/order/data/OrderData.java b/src/main/java/com/yaohun/order/data/OrderData.java new file mode 100644 index 0000000..61a37e8 --- /dev/null +++ b/src/main/java/com/yaohun/order/data/OrderData.java @@ -0,0 +1,41 @@ +package com.yaohun.order.data; + +public class OrderData { + + private String orderNumber; + private String playerName; + + private String createName; + + private String currencyType; + + private int money; + + public OrderData(String orderNumber, String playerName, String createName, String currencyType, int money) { + this.orderNumber = orderNumber; + this.playerName = playerName; + this.createName = createName; + this.currencyType = currencyType; + this.money = money; + } + + public String getOrderNumber() { + return orderNumber; + } + + public String getCreateName() { + return createName; + } + + public String getPlayerName() { + return playerName; + } + + public String getCurrencyType() { + return currencyType; + } + + public int getMoney() { + return money; + } +} diff --git a/src/main/java/com/yaohun/order/gui/ReceiveGui.java b/src/main/java/com/yaohun/order/gui/ReceiveGui.java new file mode 100644 index 0000000..0c4bc74 --- /dev/null +++ b/src/main/java/com/yaohun/order/gui/ReceiveGui.java @@ -0,0 +1,82 @@ +package com.yaohun.order.gui; + +import com.yaohun.order.api.OrderAPI; +import com.yaohun.order.data.OrderData; +import com.yaohun.order.manage.OrderManager; +import me.Demon.DemonPlugin.DemonAPI; +import me.Demon.DemonPlugin.Util.CDTimeAPI; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.*; + +public class ReceiveGui implements Listener { + + private static String invTitle = "斗魂帝國贊助訂單郵件箱"; + + public static void OpenGui(Player player){ + String playerName = player.getName(); + Inventory inv = Bukkit.createInventory(null,27,invTitle); + HashMap hashMap = OrderManager.getOrderDataMap(); + int size = 0; + for (OrderData orderData : hashMap.values()){ + if(orderData.getPlayerName().equalsIgnoreCase(playerName)){ + size++; + } + } + inv.setItem(13,signUpStack(playerName,size)); + ItemStack glass = DemonAPI.glass(15," "); + for (int slot : new int[]{0,1,7,8,9,17,18,19,25,26}){ + inv.setItem(slot,glass); + } + player.openInventory(inv); + } + + private static ItemStack signUpStack(String playerName,int size){ + ItemStack stack = new ItemStack(Material.NETHER_STAR); + ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName("§a§l確認簽收商品"); + List lore = new ArrayList<>(); + lore.add("§b===================="); + lore.add("§e簽收人ID: §4"+playerName); + lore.add("§d未簽收訂單: §f"+ size+"個"); + lore.add("§b===================="); + lore.add("§c請確認,是否是領取到該賬號"); + meta.setLore(lore); + stack.setItemMeta(meta); + return stack; + } + + + @EventHandler + public void onClick(InventoryClickEvent e){ + int rawSlot = e.getRawSlot(); + Player player = (Player) e.getWhoClicked(); + UUID uuid = player.getUniqueId(); + if(e.getView().getTitle().equalsIgnoreCase(invTitle)){ + e.setCancelled(true); + if(rawSlot == 13){ + String orderSigningKey = "orderSigningKey"; + if(CDTimeAPI.isCD(uuid, orderSigningKey)){ + player.closeInventory(); + player.sendMessage("§7[§6官方商城§7] §r請勿頻繁點擊此簽收按鈕."); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO,0.8f,1.0f); + return; + } + CDTimeAPI.setPlayerCD(uuid, orderSigningKey, 3000); + player.playSound(player.getLocation(), Sound.BLOCK_COMPARATOR_CLICK,0.8f,1.0f); + player.closeInventory(); + player.sendMessage("§7[§6官方商城§7] §r正在查詢您未簽收的訂單..."); + OrderAPI.executeOrder(player); + } + } + } +} diff --git a/src/main/java/com/yaohun/order/listener/PlayerListener.java b/src/main/java/com/yaohun/order/listener/PlayerListener.java new file mode 100644 index 0000000..2841c71 --- /dev/null +++ b/src/main/java/com/yaohun/order/listener/PlayerListener.java @@ -0,0 +1,15 @@ +package com.yaohun.order.listener; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; + +public class PlayerListener implements Listener { + + @EventHandler + public void onJoin(PlayerJoinEvent e){ + Player p = e.getPlayer(); + + } +} diff --git a/src/main/java/com/yaohun/order/manage/OrderManager.java b/src/main/java/com/yaohun/order/manage/OrderManager.java new file mode 100644 index 0000000..b9fa34b --- /dev/null +++ b/src/main/java/com/yaohun/order/manage/OrderManager.java @@ -0,0 +1,99 @@ +package com.yaohun.order.manage; + +import com.yaohun.order.OrderMain; +import com.yaohun.order.data.OrderData; +import me.Demon.DemonPlugin.DemonAPI; +import org.bukkit.Bukkit; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class OrderManager { + + private static File file; + + private static FileConfiguration config; + + private static HashMap orderDataMap = new HashMap<>(); + + public static void initOrderManager(){ + String time = DemonAPI.getTime("yyyy-MM"); + file = new File(OrderMain.inst().getDataFolder()+"/OrderData", time+".yml"); + if (file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + config = YamlConfiguration.loadConfiguration(file); + } else { + config = YamlConfiguration.loadConfiguration(file); + } + loadOrderData(); + } + + private static void loadOrderData(){ + File file = new File(OrderMain.inst().getDataFolder(), "orderData.yml"); + FileConfiguration config = YamlConfiguration.loadConfiguration(file); + ConfigurationSection section = config.getConfigurationSection("orderData"); + if(section == null){ + return; + } + for (String key : section.getKeys(false)){ + String create = section.getString(key+".create"); + String name = section.getString(key+".name"); + String currencyType = section.getString(key+".currencyType"); + int money = section.getInt(key+".currency"); + OrderData orderData = new OrderData(key, name, create, currencyType, money); + orderDataMap.put(key, orderData); + } + int size = orderDataMap.size(); + Bukkit.getConsoleSender().sendMessage("§b[订单管理] §7尚未签收订单: §f"+size+"个"); + } + + public static void saveOrderManager(){ + int size = orderDataMap.size(); + Bukkit.getConsoleSender().sendMessage("§b[订单管理] §7尚未签收订单: §f"+size+"个"); + File file = new File(OrderMain.inst().getDataFolder(), "orderData.yml"); + FileConfiguration config = YamlConfiguration.loadConfiguration(file); + config.set("orderData", null); + for (String key : orderDataMap.keySet()) { + OrderData orderData = orderDataMap.get(key); + config.set("orderData."+key+".create", orderData.getCreateName()); + config.set("orderData."+key+".name", orderData.getPlayerName()); + config.set("orderData."+key+".currencyType", orderData.getCurrencyType()); + config.set("orderData."+key+".currency", orderData.getMoney()); + } + try { + config.save(file); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static void setOrderDataMap(OrderData orderData) { + orderDataMap.put(orderData.getOrderNumber(), orderData); + } + + public static HashMap getOrderDataMap() { + return orderDataMap; + } + + + public static void signUpOrderData(OrderData orderData){ + String orderNumber = orderData.getOrderNumber(); + config.set(orderNumber+".创建人", orderData.getCreateName()); + config.set(orderNumber+".玩家名", orderData.getPlayerName()); + config.set(orderNumber+".类型", orderData.getCurrencyType()); + config.set(orderNumber+".金额", orderData.getMoney()); + config.set(orderNumber+".签收时间", DemonAPI.getTime("yyyy-MM-dd HH:mm:ss")); + try { + config.save(file); + } catch (IOException e) { + throw new RuntimeException(e); + } + orderDataMap.remove(orderNumber); + } +} diff --git a/src/main/java/com/yaohun/order/util/OrderAllocator.java b/src/main/java/com/yaohun/order/util/OrderAllocator.java new file mode 100644 index 0000000..3f2d1d5 --- /dev/null +++ b/src/main/java/com/yaohun/order/util/OrderAllocator.java @@ -0,0 +1,56 @@ +package com.yaohun.order.util; + +import com.yaohun.order.config.Config; +import com.yaohun.order.data.OrderContent; +import org.apache.logging.log4j.core.config.Order; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class OrderAllocator { + + public static Map allocateOrdersTW(List orders, int totalTW) { + orders.sort((a, b) -> Integer.compare(b.twPreic, a.twPreic)); // 从大到小 + Map result = new LinkedHashMap<>(); + for (OrderContent order : orders) { + int count = totalTW / order.twPreic; + if (count > 0) { + result.put(order.getKey(), count); + totalTW -= order.twPreic * count; + } + } + if(totalTW >= 5){ + result.put("Coins_Custom", totalTW / 5); + } + return result; + } + + public static Map allocateOrdersCN(List orders, int totalTW) { + orders.sort((a, b) -> Integer.compare(b.cnPrice, a.cnPrice)); // 从大到小 + Map result = new LinkedHashMap<>(); + for (OrderContent order : orders) { + int count = totalTW / order.cnPrice; + if (count > 0) { + result.put(order.getKey(), count); + totalTW -= order.cnPrice * count; + } + } + if(totalTW >= 1){ + result.put("Coins_Custom", totalTW); + } + return result; + } + + public static void main(String[] args) { + List orders = new ArrayList<>(); + orders.add(new OrderContent("Coins_100", 400, 100, new ArrayList<>())); + orders.add(new OrderContent("Coins_300", 1200, 300, new ArrayList<>())); + orders.add(new OrderContent("Coins_1000", 4000, 1000, new ArrayList<>())); + orders.add(new OrderContent("Coins_2000", 8000, 2000, new ArrayList<>())); + int totalTW = 1350; + Map allocation = allocateOrdersCN(orders, totalTW); + allocation.forEach((k, v) -> System.out.println(k + " x " + v)); + } +} diff --git a/src/main/resources/OrderData/2025-07.yml b/src/main/resources/OrderData/2025-07.yml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..9d061c5 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,31 @@ +OrderContent: + Coins_100: + tw: 400 + cn: 100 + command: + - 'dcoins give {player} 105' + - 'kpay give {player} 100' + Coins_300: + tw: 1200 + cn: 300 + command: + - 'dcoins give {player} 330' + - 'kpay give {player} 300' + Coins_1000: + tw: 4000 + cn: 1000 + command: + - 'dcoins give {player} 1150' + - 'kpay give {player} 1000' + Coins_2000: + tw: 8000 + cn: 2000 + command: + - 'dcoins give {player} 2400' + - 'kpay give {player} 2000' +OrderData: + '5421066555562283': + create: CONSOLE + name: 88441_owo + currencyType: TW + currency: 100 \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index f91cd64..bc62fa7 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -4,4 +4,5 @@ version: 1.0.0 depend: - DemonAPI commands: - dorder: \ No newline at end of file + dorder: + wys: \ No newline at end of file