This commit is contained in:
yaohunya 2025-07-19 01:15:49 +08:00
parent b7ca9df2c9
commit 687cc9aace
13 changed files with 616 additions and 2 deletions

26
src/README.md Normal file
View File

@ -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
### 插件首次发布

View File

@ -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;
}

View File

@ -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<String, OrderData> 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<String,Integer> 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<String,Integer> 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沒有查詢到與你相關的商品訂單.");
}
}
}

View File

@ -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<OrderContent> 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<String> stringList = section.getStringList(key + ".command");
orderContentList.add(new OrderContent(key, tw, cn, stringList));
}
Bukkit.getConsoleSender().sendMessage("§b[订单管理] §7载入订单组: §f"+orderContentList.size()+"");
}
public static List<OrderContent> getOrderContentList() {
return orderContentList;
}
public static OrderContent getOrderContent(String key) {
for (OrderContent orderContent : orderContentList) {
if (orderContent.getKey().equals(key)) {
return orderContent;
}
}
return null;
}
}

View File

@ -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<String> stringList;
public OrderContent(String key, int tw, int cn, List<String> 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));
}
}
}

View File

@ -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;
}
}

View File

@ -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<String, OrderData> 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<String> 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);
}
}
}
}

View File

@ -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();
}
}

View File

@ -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<String, OrderData> 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<String, OrderData> 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);
}
}

View File

@ -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<String, Integer> allocateOrdersTW(List<OrderContent> orders, int totalTW) {
orders.sort((a, b) -> Integer.compare(b.twPreic, a.twPreic)); // 从大到小
Map<String, Integer> 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<String, Integer> allocateOrdersCN(List<OrderContent> orders, int totalTW) {
orders.sort((a, b) -> Integer.compare(b.cnPrice, a.cnPrice)); // 从大到小
Map<String, Integer> 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<OrderContent> 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<String, Integer> allocation = allocateOrdersCN(orders, totalTW);
allocation.forEach((k, v) -> System.out.println(k + " x " + v));
}
}

View File

View File

@ -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

View File

@ -4,4 +4,5 @@ version: 1.0.0
depend:
- DemonAPI
commands:
dorder:
dorder:
wys: