This commit is contained in:
yaohunya 2025-07-12 01:03:33 +08:00
parent a6a377857a
commit dc8c47c164
13 changed files with 466 additions and 35 deletions

10
pom.xml
View File

@ -32,5 +32,15 @@
<artifactId>spigot-api</artifactId>
<version>1.12.2</version>
</dependency>
<dependency>
<groupId>com.yaohun.storyline</groupId>
<artifactId>QuestStoryline</artifactId>
<version>1.3.8</version>
</dependency>
<dependency>
<groupId>com.yaohun.aurechargedata</groupId>
<artifactId>AuRechargeData</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>
</project>

View File

@ -7,67 +7,117 @@ import com.yaohun.levelreward.manage.PlayerManager;
import com.yaohun.levelreward.util.ToolsUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
/**
* LevelReward 插件类继承自 JavaPlugin
* 该类主要用于处理玩家等级奖励的相关功能包括插件的初始化命令处理等
*/
public class LevelReward extends JavaPlugin {
// LevelReward 插件的单例实例
private static LevelReward instance;
// 玩家管理器用于管理玩家数据
private static PlayerManager playerManager;
/**
* 插件启用时调用的方法
* 用于初始化配置文件玩家管理器以及注册事件监听器
*/
@Override
public void onEnable() {
instance = this;
saveDefaultConfig();
Config.reloadConfig(this);
playerManager = new PlayerManager();
getServer().getPluginManager().registerEvents(new RewardGui(), this);
}
@Override
public void onDisable() {
}
/**
* 处理插件命令的方法
* 根据不同的命令参数执行相应的操作如打开奖励界面重载配置文件等
*
* @param sender 命令发送者
* @param cmd 被执行的命令对象
* @param label 命令别名
* @param args 命令参数数组
* @return true 如果命令被成功处理否则返回 false
*/
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if("open".equalsIgnoreCase(args[0])){
// 处理 "open" 命令打开奖励界面
if(args.length == 1 && "open".equalsIgnoreCase(args[0])){
RewardGui.OpenGui((Player) sender);
return true;
}
// 检查发送者是否是管理员
if(!sender.isOp()) {
return true;
}
// 显示帮助信息
if (args.length == 0) {
sender.sendMessage("");
sender.sendMessage("§e------- ======= §6等级成长礼包 §e======= -------");
sender.sendMessage("§2/"+label+" open §f- §2打开界面");
sender.sendMessage("§2/"+label+" skull §f- §2查看头颅码");
sender.sendMessage("§2/"+label+" reload §f- §2重载配置文件");
sender.sendMessage("§2/"+label+" convert §f- §c转换旧版数据");
sender.sendMessage("§e------- ======= §6等级成长礼包 §e======= -------");
sender.sendMessage("");
return true;
}
// 处理 "skull" 命令查看头颅码
if("skull".equalsIgnoreCase(args[0])){
Player player = (Player) sender;
ItemStack stack = player.getInventory().getItemInMainHand();
sender.sendMessage("[查询头颅] Base64ID: "+ToolsUtil.getHandSkullBase64(stack));
return true;
}
// 处理 "reload" 命令重载配置文件
if("reload".equalsIgnoreCase(args[0])){
Config.reloadConfig(this);
sender.sendMessage("[等级礼包] 配置文件已重载.");
return true;
}
// 处理 "convert" 命令转换旧版数据
if("convert".equalsIgnoreCase(args[0])){
ConfigurationSection section = getConfig().getConfigurationSection("ExpUpData");
if(section == null) {
return true;
}
int count = 0;
for (String playerName : section.getKeys(false)){
PlayerData playerData = new PlayerData(playerName);
playerData.setRewardList(section.getStringList(playerName));
playerData.savePlayerData();
count++;
}
sender.sendMessage("[等级礼包] 数据转换 "+count+"");
return true;
}
return false;
}
/**
* 获取 LevelReward 插件的单例实例
*
* @return LevelReward 插件的实例
*/
public static LevelReward inst() {
return instance;
}
/**
* 获取玩家管理器
*
* @return 玩家管理器实例
*/
public static PlayerManager getPlayerManager() {
return playerManager;
}
}

View File

@ -13,58 +13,112 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Config类用于管理配置数据包括语言配置界面物品数据和奖励设置
*/
public class Config {
// 存储语言配置数据
public static LangData langData;
// 存储界面物品数据的映射表
private static HashMap<String, GuiItemData> guiItemDataMap = new HashMap<>();
// 存储奖励设置的列表
private static List<RewardData> rewardDataList = new ArrayList<>();
/**
* 重新加载配置文件
* 此方法应由LevelReward插件调用以初始化或更新配置数据
* @param plugin LevelReward插件实例用于访问插件的配置文件
*/
public static void reloadConfig(LevelReward plugin) {
// 调用了DemonAPI中的LangData
// 需要在AuLangs目录中创建一个 LevelReward.yml 文件存语言配置
langData = DemonAPI.getLangData("LevelReward");
// 重新加载和保存插件的配置文件
plugin.reloadConfig();
plugin.saveConfig();
FileConfiguration config = plugin.getConfig();
// 加载界面物品数据和奖励设置
loadGuiItemData(config);
loadRewardSettings(config);
}
/**
* 从配置文件中加载奖励设置
* 此方法清除现有的奖励数据列表并从配置文件的"RewardSettings"部分重新加载
* @param config 插件的配置文件
*/
private static void loadRewardSettings(FileConfiguration config){
// 清除现有的奖励数据列表
rewardDataList.clear();
// 获取"RewardSettings"配置部分
ConfigurationSection section = config.getConfigurationSection("RewardSettings");
// 如果该部分不存在则直接返回
if(section == null) {return;}
// 遍历"RewardSettings"部分的所有键并创建新的RewardData对象添加到列表中
for (String rewardKey : section.getKeys(false)){
rewardDataList.add(new RewardData(rewardKey,section));
}
}
/**
* 从配置文件中加载界面物品数据
* 此方法清除现有的界面物品数据映射表并从配置文件的"GuiItemData"部分重新加载
* @param configuration 插件的配置文件
*/
private static void loadGuiItemData(FileConfiguration configuration){
// 清除现有的界面物品数据映射表
guiItemDataMap.clear();
// 获取"GuiItemData"配置部分
ConfigurationSection section = configuration.getConfigurationSection("GuiItemData");
// 如果该部分不存在则直接返回
if(section == null){return;}
// 遍历"GuiItemData"部分的所有键并创建新的GuiItemData对象添加到映射表中
for (String itemKey : section.getKeys(false)){
guiItemDataMap.put(itemKey,new GuiItemData(itemKey,section));
}
}
/**
* 根据物品键获取对应的ItemStack对象
* 如果指定的物品键存在于映射表中则返回对应的ItemStack对象的克隆否则返回错误物品
* @param itemKey 物品键
* @return 对应的ItemStack对象的克隆或错误物品
*/
public static ItemStack getItemStack(String itemKey) {
// 检查物品键是否存在于映射表中
if(guiItemDataMap.containsKey(itemKey)){
// 返回对应的ItemStack对象的克隆
return guiItemDataMap.get(itemKey).getItemStack().clone();
}
// 如果物品键不存在则返回错误物品
return DemonAPI.getErrItems();
}
/**
* 获取奖励数据列表
* @return 奖励数据列表
*/
public static List<RewardData> getRewardDataList() {
return rewardDataList;
}
/**
* 根据奖励键获取对应的奖励数据
* 如果找到匹配的奖励键则返回对应的奖励数据否则返回null
* @param rewardKey 奖励键
* @return 对应的奖励数据或null
*/
public static RewardData getRewardData(String rewardKey) {
// 遍历奖励数据列表
for (RewardData rewardData : rewardDataList){
// 如果找到匹配的奖励键则返回对应的奖励数据
if(rewardData.getRewardKey().equals(rewardKey)){
return rewardData;
}
}
// 如果没有找到匹配的奖励键则返回null
return null;
}
}

View File

@ -91,4 +91,9 @@ public class PlayerData {
return rewardList;
}
public void setRewardList(List<String> rewardList) {
this.rewardList.clear();
this.rewardList.addAll(rewardList);
}
}

View File

@ -1,62 +1,131 @@
package com.yaohun.levelreward.data;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import java.util.List;
/**
* 奖励数据类用于存储和管理奖励相关信息
*/
public class RewardData {
// 奖励的唯一标识key
private String rewardKey;
// 奖励在GUI中的槽位位置
private int slot;
// 奖励图标的Base64编码用于自定义头颅外观
private String base64;
// 解锁奖励所需的最低等级
private int needLevel;
// 奖励物品列表显示给玩家的奖励内容
private List<String> rewardList;
// 领取奖励时需要执行的命令列表
private List<String> commandList;
/**
* 构造函数从配置中初始化奖励数据
*
* @param rewardKey 奖励的唯一key用于在配置中查找对应数据
* @param section 配置节点包含该奖励的所有配置信息
*/
public RewardData(String rewardKey, ConfigurationSection section){
this.rewardKey = rewardKey;
// 从配置中获取奖励所在的槽位
this.slot = section.getInt(rewardKey+".slot");
// 从配置中获取解锁奖励所需的等级
this.needLevel = section.getInt(rewardKey+".level");
// 从配置中获取Base64图标数据默认为"default"
this.base64 = section.getString(rewardKey+".base64","default");
// 从配置中获取奖励物品列表
this.rewardList = section.getStringList(rewardKey+".reward");
// 从配置中获取需要执行的命令列表
this.commandList = section.getStringList(rewardKey+".commands");
}
/**
* 获取奖励的唯一标识key
*
* @return 奖励的key
*/
public String getRewardKey() {
return rewardKey;
}
/**
* 获取奖励在GUI中的槽位
*
* @return 槽位索引
*/
public int getSlot() {
return slot;
}
/**
* 获取奖励图标的Base64编码
*
* @return Base64字符串
*/
public String getBase64() {
return base64;
}
/**
* 获取奖励物品列表
*
* @return 奖励描述文本列表
*/
public List<String> getRewardList() {
return rewardList;
}
/**
* 获取解锁奖励所需等级
*
* @return 所需等级
*/
public int getNeedLevel() {
return needLevel;
}
/**
* 执行奖励对应的命令
* 如果是消息命令"msg:"开头则向玩家发送消息
* 否则替换占位符后执行命令
*
* @param player 要执行命令的目标玩家
*/
public void carryOutCommands(Player player){
String playerName = player.getName();
// 遍历所有命令并执行
for(String command : commandList) {
if (command.contains("msg:")) {
player.sendMessage(command.replace("msg:", ""));
} else {
// 如果是消息命令去掉前缀后发送消息
player.sendMessage(command.replace("msg:", "").replace("&", "§"));
continue;
}
// 替换命令中的玩家名称占位符%p%为真实名称
command = command.replace("%p%", playerName);
// 执行命令
player.performCommand(command);
}
// 记录日志
Bukkit.getLogger().info("[等级奖励 - 发放] " + player.getName() + " 已执行奖励命令: " + rewardKey);
}
}
}

View File

@ -1,19 +1,46 @@
package com.yaohun.levelreward.gui;
import com.yaohun.aurechargedata.api.RechargeAPI;
import com.yaohun.aurechargedata.util.TimeType;
import com.yaohun.levelreward.LevelReward;
import com.yaohun.levelreward.config.Config;
import com.yaohun.levelreward.data.PlayerData;
import com.yaohun.levelreward.data.RewardData;
import com.yaohun.levelreward.hook.QuestStoryHook;
import com.yaohun.levelreward.manage.PlayerManager;
import com.yaohun.levelreward.util.MessageUtil;
import com.yaohun.levelreward.util.StackUtil;
import me.Demon.DemonLevelReward.Event.LevelRewardReceiveEvent;
import me.Demon.DemonPlugin.DemonAPI;
import me.Demon.DemonPlugin.Util.AreaType;
import me.Demon.DemonPlugin.data.NbtItem;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
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;
public class RewardGui {
import java.util.UUID;
/**
* RewardGui类用于处理奖励界面的展示和玩家的点击事件
* 它实现了Listener接口以监听玩家在GUI界面的点击行为
*/
public class RewardGui implements Listener{
// 定义库存标题
private static String invTitle = Config.langData.getMessage("invTitle");
/**
* 检查玩家是否在服务器首次登录超过60天
*
* @param player 要检查的玩家对象
* @return 如果玩家首次登录超过60天返回true否则返回false
*/
public static boolean isTimeOut60Day(Player player){
long firstPlayed = player.getFirstPlayed();
if(firstPlayed == 0){
@ -26,6 +53,17 @@ public class RewardGui {
}
return true;
}
/**
* 打开奖励界面
*
* 该方法负责创建并展示奖励界面包括
* 1. 检查玩家是否满足时间条件
* 2. 创建和填充界面库存
* 3. 根据配置添加奖励物品
*
* @param player 要打开界面的玩家对象
*/
public static void OpenGui(Player player) {
// 获取玩家入服时间 并判断是否已超过60天
if(isTimeOut60Day(player)){
@ -33,9 +71,106 @@ public class RewardGui {
return;
}
Inventory inv = Bukkit.createInventory(null,27, invTitle);
ItemStack glass = DemonAPI.glass(15, "§8#欢迎加入");
if(DemonAPI.getAreaType() == AreaType.TaiWan){
glass = DemonAPI.glass(15, "§8#歡迎加入");
}
int[] slot = {0, 8, 9, 17, 18, 26};
for (int i : slot) {
inv.setItem(i, glass);
}
for (RewardData rewardData : Config.getRewardDataList()){
inv.setItem(rewardData.getSlot(), StackUtil.getGiftPack(player, rewardData));
}
player.openInventory(inv);
}
/**
* 处理玩家在GUI界面中的点击事件
*
* 该事件处理器用于处理玩家在特定GUI(标题匹配invTitle)中的点击行为
* 主要实现以下功能
* 1. 验证点击的槽位和物品有效性
* 2. 检查玩家是否满足领取奖励的条件
* 3. 发放奖励并触发相关事件
*
* @param e InventoryClickEvent 库存点击事件对象包含点击相关信息
*/
@EventHandler
private void onClick(InventoryClickEvent e) {
int rawSlot = e.getRawSlot();
Player player = (Player) e.getWhoClicked();
String playerName = player.getName();
// 只处理指定标题的GUI点击事件
if(e.getView().getTitle().equalsIgnoreCase(invTitle)) {
e.setCancelled(true); // 取消所有点击事件的默认行为
// 检查点击槽位是否在有效范围内(0-26)
if(rawSlot < 0 || rawSlot > 26) {
return;
}
// 验证被点击的物品是否有效
ItemStack stack = e.getCurrentItem();
if(stack == null || DemonAPI.itemIsNull(stack) || DemonAPI.itemIsLore(stack)) {
return;
}
// 检查物品是否包含奖励标识
NbtItem nbtItem = new NbtItem(stack);
if(!nbtItem.hasKey("rewardKey")) {
return;
}
// 获取奖励配置数据
String rewardKey = nbtItem.getString("rewardKey");
RewardData rewardData = Config.getRewardData(rewardKey);
if(rewardData == null) {
return;
}
// 检查玩家等级是否满足要求
int needLevel = rewardData.getNeedLevel();
if(player.getLevel() < needLevel) {
MessageUtil.sendMessageKey(player, "noLevelRequest", Sound.ENTITY_VILLAGER_NO);
return;
}
if(needLevel == 15){
if(!QuestStoryHook.isCompleteQuest(player)){
player.closeInventory();
MessageUtil.sendMessageKey(player, "questStoryChecking", Sound.ENTITY_VILLAGER_NO);
return;
}
}
if(rewardKey.contains("kejin")){
int needRecharge = 1288;
int recharge = RechargeAPI.getRechargeData(playerName, TimeType.ANNUAL);
if (recharge < needRecharge) {
player.closeInventory();
String message = Config.langData.getMessage("inadequateRecharge");
message = message.replace("{coins}",String.valueOf((needRecharge - recharge)));
MessageUtil.sendMessage(player, message, Sound.ENTITY_VILLAGER_NO);
return;
}
}
// 检查玩家是否已领取过该奖励
PlayerManager playerManager = LevelReward.getPlayerManager();
PlayerData playerData = playerManager.getPlayerData(playerName);
if(playerData.isHasReward(rewardKey)) {
MessageUtil.sendMessageKey(player, "alreadyReceived", Sound.ENTITY_VILLAGER_NO);
return;
}
player.closeInventory();
// 发放奖励并触发相关事件
playerData.addReward(rewardKey);
playerData.savePlayerData();
rewardData.carryOutCommands(player);
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1.0f, 1.2f);
LevelRewardReceiveEvent event = new LevelRewardReceiveEvent(player, rewardKey, needLevel);
Bukkit.getPluginManager().callEvent(event);
}
}
}

View File

@ -0,0 +1,42 @@
package com.yaohun.levelreward.hook;
import com.yaohun.storyline.Storyline;
import com.yaohun.storyline.data.PlayerData;
import com.yaohun.storyline.manage.PlayerManager;
import org.bukkit.entity.Player;
/**
* 任务故事线挂钩类
* 用于检查玩家是否完成特定任务
*/
public class QuestStoryHook {
/**
* 检查玩家是否完成指定任务线
* @param player 要检查的玩家对象
* @return true表示已完成任务(当前任务ID>=17)false表示未完成或玩家数据不存在
*/
public static boolean isCompleteQuest(Player player){
// 获取玩家名称用于查询数据
String playerName = player.getName();
// 从故事线系统获取玩家管理器
PlayerManager playerManager = Storyline.getPlayerManager();
// 获取玩家的任务数据
PlayerData playerData = playerManager.getPlayerData(playerName);
// 如果玩家数据不存在返回未完成
if(playerData == null){
return false;
}
// 检查当前任务ID是否达到完成标准(17)
if(playerData.getCurrentQuest() >= 17){
return true;
}
// 不满足条件返回false
return false;
}
}

View File

@ -6,27 +6,39 @@ import org.bukkit.entity.Player;
import java.util.HashMap;
// 玩家数据管理类用于存储和管理玩家的数据
public class PlayerManager {
// 存储玩家数据的哈希映射键为玩家名称值为玩家数据对象
private final HashMap<String, PlayerData> playerDataMap = new HashMap<>();
/**
* 构造函数初始化在线玩家的数据
*/
public PlayerManager() {
// 遍历当前在线的所有玩家
for (Player player : Bukkit.getOnlinePlayers()) {
// 获取玩家名称
String playerName = player.getName();
// 创建并存储玩家数据对象
playerDataMap.put(playerName,new PlayerData(playerName));
}
}
public void saveAllPlayerData() {
for (PlayerData playerData : playerDataMap.values()) {
playerData.savePlayerData();
}
}
/**
* 获取或创建玩家的数据
* 如果玩家数据不存在则创建新的玩家数据对象
*
* @param playerName 玩家名称
* @return 玩家数据对象
*/
public PlayerData getPlayerData(String playerName) {
// 检查玩家数据是否存在
if (!playerDataMap.containsKey(playerName)) {
// 如果不存在创建并存储新的玩家数据对象
playerDataMap.put(playerName,new PlayerData(playerName));
}
// 返回玩家数据对象
return playerDataMap.get(playerName);
}
}

View File

@ -5,8 +5,20 @@ import org.bukkit.Sound;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
/**
* 消息工具类用于向命令发送者发送消息
* 提供了向Minecraft服务器中的玩家或其他命令发送者发送消息的功能
*/
public class MessageUtil {
/**
* 向指定的命令发送者发送消息
* 如果发送者是玩家使用玩家对象的sendMessage方法发送
* 否则直接使用命令发送者的sendMessage方法
*
* @param sender 命令发送者对象可以是玩家或控制台
* @param message 要发送的消息内容
*/
public static void sendMessage(CommandSender sender, String message) {
if(sender instanceof Player){
Player player = (Player) sender;
@ -16,7 +28,16 @@ public class MessageUtil {
}
}
/**
* 向指定的命令发送者发送消息并播放音效
* 如果发送者是玩家则还会播放指定的音效
*
* @param sender 命令发送者可以是玩家或控制台等
* @param message 要发送的消息文本
* @param sound 要播放的音效
*/
public static void sendMessage(CommandSender sender, String message, Sound sound) {
// 判断发送者是否为玩家以便播放音效
if(sender instanceof Player){
Player player = (Player) sender;
player.sendMessage(message);
@ -26,8 +47,18 @@ public class MessageUtil {
}
}
/**
* 根据语言键向指定的命令发送者发送消息并播放音效
* 首先从配置文件中获取对应语言键的消息文本然后发送给发送者
* 如果发送者是玩家则还会播放指定的音效
*
* @param sender 命令发送者可以是玩家或控制台等
* @param langKey 语言键用于从配置文件中获取消息文本
* @param sound 要播放的音效
*/
public static void sendMessageKey(CommandSender sender, String langKey, Sound sound) {
String message = Config.langData.getMessage(langKey);
// 判断发送者是否为玩家以便播放音效
if(sender instanceof Player){
Player player = (Player) sender;
player.sendMessage(message);
@ -37,5 +68,4 @@ public class MessageUtil {
}
}
}

View File

@ -2,9 +2,12 @@ package com.yaohun.levelreward.util;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import com.yaohun.aurechargedata.api.RechargeAPI;
import com.yaohun.aurechargedata.util.TimeType;
import com.yaohun.levelreward.config.Config;
import com.yaohun.levelreward.data.PlayerData;
import com.yaohun.levelreward.data.RewardData;
import me.Demon.DemonPlugin.data.NbtItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@ -16,15 +19,27 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* 根据玩家和奖励数据获取礼物包ItemStack
* 此方法用于根据玩家的特定条件动态生成不同的礼物包每个礼物包都有一个独特的外观和属性
*
* @param player 玩家对象用于获取玩家信息如名称和等级
* @param rewardData 奖励数据对象包含奖励所需等级和奖励具体内容等信息
* @return 返回一个根据玩家和奖励数据定制的ItemStack对象
*/
public class StackUtil {
public static ItemStack getGiftPack(Player player, RewardData rewardData){
// 获取基础礼物包配置
ItemStack stack = Config.getItemStack("LevelGiftPack");
// 如果奖励包含kejin则使用付费礼物包配置
if(rewardData.getRewardKey().contains("kejin")){
stack = Config.getItemStack("PayGiftPack");
}
// 设置物品类型和耐久值
stack.setType(Material.SKULL_ITEM);
stack.setDurability((short) 3);
// 获取并设置物品的SkullMeta元数据
SkullMeta meta = (SkullMeta) stack.getItemMeta();
GameProfile profile = new GameProfile(UUID.randomUUID(), null);
String base64 = rewardData.getBase64();
@ -36,12 +51,16 @@ public class StackUtil {
} catch (Exception e) {
e.printStackTrace();
}
// 更新物品名称用实际需要的等级替换占位符
String itemName = meta.getDisplayName();
meta.setDisplayName(itemName.replace("{level}",String.valueOf(rewardData.getNeedLevel())));
// 更新物品的附带信息根据不同的占位符替换相应的玩家和奖励信息
List<String> lore = meta.getLore();
List<String> newLore = new ArrayList<>();
for (String line : lore) {
if (line.contains("{name}")) {
if (line.contains("{coins}")) {
newLore.add(line.replace("{coins}", String.valueOf(RechargeAPI.getRechargeData(player.getName(), TimeType.ANNUAL))));
} else if (line.contains("{name}")) {
newLore.add(line.replace("{name}", player.getName()));
} else if (line.contains("{player_level}")) {
newLore.add(line.replace("{player_level}", String.valueOf(player.getLevel())));
@ -53,6 +72,11 @@ public class StackUtil {
}
meta.setLore(newLore);
stack.setItemMeta(meta);
return stack;
// 使用NBT技术存储额外的奖励信息到物品中
NbtItem nbtItem = new NbtItem(stack);
nbtItem.setString("rewardKey", rewardData.getRewardKey());
nbtItem.setInteger("needLevel", rewardData.getNeedLevel());
return nbtItem.getItem();
}
}

View File

@ -28,7 +28,7 @@ RewardSettings:
expup_15:
slot: 10
level: 15
base64: xxxxxxxxxxxxxxxxxxxxxxxxx
base64: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzFhOTEyZTMzMmZjMDAxMGJlYmQwZjkzYTE0ZDhlM2VhNjVkMTMwMTEwMGNlYTNmYzVhZTcxOTkwZDk4NTgwNyJ9fX0=
reward:
- §71. §7§l★§71 §65000金币
- §72. §7§l★§75 §e百年灵环
@ -50,7 +50,7 @@ RewardSettings:
expup_25:
slot: 11
level: 25
base64: xxxxxxxxxxxxxxxxxxxxxxxxx
base64: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzFhOTEyZTMzMmZjMDAxMGJlYmQwZjkzYTE0ZDhlM2VhNjVkMTMwMTEwMGNlYTNmYzVhZTcxOTkwZDk4NTgwNyJ9fX0=
reward:
- §71. §7§l★§71 §610000金币
- §72. §7§l★§74 §d千年灵环
@ -76,7 +76,7 @@ RewardSettings:
expup_35:
slot: 12
level: 35
base64: xxxxxxxxxxxxxxxxxxxxxxxxx
base64: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMjRiOTUzYjJjMGU5NTI1NzRmMWVkMjljODFlODJlNTNiY2RiMWJhNjgzMjU5YzIwZGFlZWY3ZDU1NGEyYTc5OCJ9fX0=
reward:
- §71. §7§l★§71 §615800金币
- §72. §7§l★§76 §d千年灵环
@ -102,7 +102,7 @@ RewardSettings:
expup_45:
slot: 13
level: 45
base64: xxxxxxxxxxxxxxxxxxxxxxxxx
base64: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMjRiOTUzYjJjMGU5NTI1NzRmMWVkMjljODFlODJlNTNiY2RiMWJhNjgzMjU5YzIwZGFlZWY3ZDU1NGEyYTc5OCJ9fX0=
reward:
- §71. §7§l★§71 §620800金币
- §72. §7§l★§78 §d千年灵环
@ -130,7 +130,7 @@ RewardSettings:
expup_55:
slot: 14
level: 55
base64: xxxxxxxxxxxxxxxxxxxxxxxxx
base64: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzM3Yjk2YTQ1YThmMGM2ZmQ3ZGZhYjJhODVlMWEzODRkYWNhNGI4MDZlYjg5MmE4N2UyN2Y1MmE5ZjkxYzA4NCJ9fX0=
reward:
- §71. §7§l★§71 §625800金币
- §72. §7§l★§78 §d千年灵环
@ -158,7 +158,7 @@ RewardSettings:
expup_65:
slot: 15
level: 65
base64: xxxxxxxxxxxxxxxxxxxxxxxxx
base64: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzM3Yjk2YTQ1YThmMGM2ZmQ3ZGZhYjJhODVlMWEzODRkYWNhNGI4MDZlYjg5MmE4N2UyN2Y1MmE5ZjkxYzA4NCJ9fX0=
reward:
- §71. §7§l★§71 §629800金币
- §72. §7§l★§712 §d千年灵环
@ -188,7 +188,7 @@ RewardSettings:
expup_75:
slot: 16
level: 75
base64: xxxxxxxxxxxxxxxxxxxxxxxxx
base64: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNDE3NmMxYWU3MTMwN2U4NTQ3MDA2OTI3ZTk3MWU1MzBkYzBjMzQ4YmRhYjZkYjc0YWJlYWQ3MDFhNDBiMWIwIn19fQ==
reward:
- §71. §7§l★§71 §636800金币
- §72. §7§l★§71 §d40点券
@ -218,7 +218,7 @@ RewardSettings:
expup_80:
slot: 20
level: 80
base64: xxxxxxxxxxxxxxxxxxxxxxxxx
base64: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODQ0NDk4YTBmZTI3ODk1NmUzZDA0MTM1ZWY0YjEzNDNkMDU0OGE3ZTIwOGM2MWIxZmI2ZjNiNGRiYzI0MGRhOCJ9fX0=
reward:
- §71. §7§l★§71 §642800金币
- §72. §7§l★§71 §d80点券
@ -246,7 +246,7 @@ RewardSettings:
expup_85:
slot: 22
level: 85
base64: xxxxxxxxxxxxxxxxxxxxxxxxx
base64: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzFmN2NkZmVhMmQyMWNkNWY2ZWJiZjQ4NDgxNzYxYzZjYmRmMzZkMDBmZTY0MDgzNjg2ZTlhZWFhM2YxZjIxNyJ9fX0
reward:
- §71. §7§l★§71 §658800金币
- §72. §7§l★§71 §d100点券
@ -273,7 +273,7 @@ RewardSettings:
expup_90:
slot: 24
level: 90
base64: xxxxxxxxxxxxxxxxxxxxxxxxx
base64: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNGJhNTU2NzFmOTdmZjNiZmM1YmUzMzVhZTkyY2Q5NzQ5YWJkNjE5ZTdhZmMyYTY2NzM1OTdiODBiNzU1Yzc0MSJ9fX0=
reward:
- §71. §7§l★§71 §658800金币
- §72. §7§l★§71 §d120点券
@ -303,7 +303,7 @@ RewardSettings:
expup_kejin:
slot: 4
level: 80
base64: xxxxxxxxxxxxxxxxxxxxxxxxx
base64: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOWM5NmJlNzg4NmViN2RmNzU1MjVhMzYzZTVmNTQ5NjI2YzIxMzg4ZjBmZGE5ODhhNmU4YmY0ODdhNTMifX19
reward:
- §71. §7§l★§710 §e灵环抽奖钥匙
- §72. §7§l★§710 §e超级灵环抽奖钥匙

View File

@ -1,5 +1,5 @@
name: DemonLevelReward
main: com.yaohun.levelreward.LevelReward
version: 2.0.6
version: 2.0.9
commands:
levelreward: