diff --git a/pom.xml b/pom.xml index aebeacf..4855333 100644 --- a/pom.xml +++ b/pom.xml @@ -51,6 +51,11 @@ DemonTeam 1.2.0 + + com.yaohun.playermanage + PlayerManage + 1.0.1 + \ No newline at end of file diff --git a/src/main/java/me/Demon/DemonLevels/LevelExpansion.java b/src/main/java/me/Demon/DemonLevels/LevelExpansion.java new file mode 100644 index 0000000..06a2151 --- /dev/null +++ b/src/main/java/me/Demon/DemonLevels/LevelExpansion.java @@ -0,0 +1,102 @@ +package me.Demon.DemonLevels; + +import me.Demon.DemonLevels.api.DLevelAPI; +import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.RoundingMode; +import java.text.DecimalFormat; + +public class LevelExpansion extends PlaceholderExpansion { + private Plugin plugin; + + public LevelExpansion(Plugin plugin) { + this.plugin = plugin; + } + + @Override + public boolean persist() { + return true; + } + + @Override + public boolean canRegister() { + return true; + } + + @Override + public String getAuthor() { + return plugin.getDescription().getAuthors().toString(); + } + + @Override + public String getIdentifier() { + return "dlevel"; + } + + @Override + public String getVersion() { + return plugin.getDescription().getVersion(); + } + + @Override + public String onPlaceholderRequest(Player player, String indentifier) { + if (indentifier.equalsIgnoreCase("expbl")) { + if(Main.serverManage.getExpMultiplicity() <= 1.0){ + return "0.00%"; + } + return (Main.serverManage.getExpMultiplicity() * 100)+"%"; + }else if (indentifier.equalsIgnoreCase("level")) { + return ""+DLevelAPI.getPlayerLevel(player); + }else if(indentifier.equalsIgnoreCase("exp")){ + return ""+DLevelAPI.getPlayerExp(player); + }else if(indentifier.equalsIgnoreCase("exptolevel")){ + return ""+DLevelAPI.getPlayerExpToLevel(player); + }else if(indentifier.equalsIgnoreCase("totalexp")){ + return ""+DLevelAPI.getPlayerTotalExp(player); + }else if(indentifier.equalsIgnoreCase("upexp")){ + BigInteger exp = DLevelAPI.getPlayerExp(player); + BigInteger upExp = DLevelAPI.getPlayerExpToLevel(player); + // 将 BigInteger 转换为 BigDecimal 以支持浮点运算 + BigDecimal expDecimal = new BigDecimal(exp); + BigDecimal upExpDecimal = new BigDecimal(upExp); + // 计算经验百分比 + BigDecimal percentage = expDecimal.divide(upExpDecimal, 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)); + return String.format("%.1f", percentage); + }else if (indentifier.equalsIgnoreCase("baifenbi")) { + BigInteger exp = DLevelAPI.getPlayerExp(player); + BigInteger upExp = DLevelAPI.getPlayerExpToLevel(player); + // 将 BigInteger 转换为 BigDecimal 以支持浮点运算 + BigDecimal expDecimal = new BigDecimal(exp); + BigDecimal upExpDecimal = new BigDecimal(upExp); + // 计算经验百分比 + BigDecimal percentage = expDecimal.divide(upExpDecimal, 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)); + return String.format("%.3f", percentage); + }else + if (indentifier.equalsIgnoreCase("up")) { + int level = DLevelAPI.getPlayerLevel(player); + BigInteger upexp = DLevelAPI.getLevelNeedExp(level); + BigInteger playerExp = DLevelAPI.getPlayerExp(player); + // 计算所需的剩余经验 + BigInteger remainingExp = upexp.subtract(playerExp); + // 将 BigInteger 转换为 int,以便进行比较和格式化 + int exp = remainingExp.intValue(); + // 格式化剩余经验,根据其大小选择合适的单位 + if (exp >= 10000000) { // 如果剩余经验大于等于 10,000,000 + // 将经验转换为百万单位,并格式化为 "x.xx m" + exp = exp / 1000000; + return new DecimalFormat(",###.#").format(exp) + "m"; + } else if (exp >= 1000000) { // 如果剩余经验大于等于 1,000,000 + // 将经验转换为万单位,并格式化为 "x.xx w" + exp = exp / 10000; + return new DecimalFormat(",###.#").format(exp) + "w"; + } + // 如果剩余经验小于 1,000,000,直接格式化为 "x.xxx" + return new DecimalFormat(",###.##").format(remainingExp); + } + return ""; + } +} diff --git a/src/main/java/me/Demon/DemonLevels/Main.java b/src/main/java/me/Demon/DemonLevels/Main.java index c90fdb1..b5095f5 100644 --- a/src/main/java/me/Demon/DemonLevels/Main.java +++ b/src/main/java/me/Demon/DemonLevels/Main.java @@ -1,12 +1,15 @@ package me.Demon.DemonLevels; import me.Demon.DemonLevels.listener.MobDeath; -import me.Demon.DemonLevels.listener.QuitEvent; -import me.Demon.DemonLevels.manage.MobsManage; +import me.Demon.DemonLevels.listener.JoinEvent; +import me.Demon.DemonLevels.listener.UpgradePrompt; import me.Demon.DemonLevels.manage.ServerManage; import me.Demon.DemonLevels.util.ConfigYml; +import me.Demon.DemonPlugin.DemonAPI; +import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import java.io.File; @@ -24,15 +27,42 @@ public class Main extends JavaPlugin { @Override public void onEnable() { plugin = this; + DemonAPI.sendConsoleMessage("§f[§6!§f] §aAuRechargeData ("+plugin.getServer().getVersion()+") §f开始加载"); loadConfigData(); serverManage = new ServerManage(getConfig()); getServer().getPluginManager().registerEvents(new MobDeath(),this); - getServer().getPluginManager().registerEvents(new QuitEvent(),this); + getServer().getPluginManager().registerEvents(new JoinEvent(),this); + getServer().getPluginManager().registerEvents(new UpgradePrompt(),this); + if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { + new LevelExpansion(this).register(); + DemonAPI.sendConsoleMessage("§f[§a!§f] §fPlaceholderAPI §8> §6完成"); + } + DemonAPI.sendConsoleMessage("§f[§6!§f] §aDemonLevels §f加载完成,祝你使用愉快!"); + DemonAPI.sendConsoleMessage("§f[§6!§f] §b极光像素工作室出品"); + } + + @Override + public void onDisable() { + for (String uuid : serverManage.getDataHashMap().keySet()){ + serverManage.getDataHashMap().get(uuid).savePlayerData(); + } + serverManage.getDataHashMap().clear(); + DemonAPI.sendConsoleMessage("§f[§c!§f] §aDemonLevels §f卸载完成,欢迎下次使用!"); } public void loadConfigData(){ File file = new File(getDataFolder(),"Data.yml"); FileConfiguration yml = YamlConfiguration.loadConfiguration(file); - configYml = new ConfigYml(yml); + configYml = new ConfigYml(file,yml); + } + + public void reloadLoadData(){ + loadConfigData(); + plugin.reloadConfig(); + serverManage = new ServerManage(getConfig()); + for (Player onlineP : Bukkit.getOnlinePlayers()){ + String uuid = onlineP.getUniqueId().toString(); + Main.serverManage.getPlayerData(uuid); + } } } diff --git a/src/main/java/me/Demon/DemonLevels/api/DLevelAPI.java b/src/main/java/me/Demon/DemonLevels/api/DLevelAPI.java index 0cb9442..8b25d6d 100644 --- a/src/main/java/me/Demon/DemonLevels/api/DLevelAPI.java +++ b/src/main/java/me/Demon/DemonLevels/api/DLevelAPI.java @@ -1,4 +1,278 @@ package me.Demon.DemonLevels.api; +import com.yaohun.playermanage.PlayerManage; +import me.Demon.DemonLevels.Main; +import me.Demon.DemonLevels.data.ChangExpEvant; +import me.Demon.DemonLevels.data.PlayerData; +import me.Demon.DemonLevels.event.UpLevelEvant; +import me.Demon.DemonLevels.listener.MobDeath; +import me.Demon.DemonLevels.util.ScriptEngineAPI; +import me.Demon.DemonPlugin.DemonAPI; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; +import org.serverct.ersha.jd.AttributeAPI; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + public abstract class DLevelAPI { + + /* + * 获取离线玩家的等级 + * */ + public static double getOffPlayer_Level(String playName){ + // 通过玩家名字获取玩家的UUID + String uuid = PlayerManage.getNameToUuid(playName); + // 检查UUID的长度,如果长度小于等于16,则认为UUID无效,返回0 + if (uuid.length() <= 16) { + return 0; + } + // 根据UUID获取玩家的数据 + PlayerData playerData = Main.serverManage.getPlayerData(uuid); + // 返回玩家的等级 + return playerData.getLevel(); + } + /* + * 获取玩家当前经验值 + * */ + public static BigInteger getPlayerExp(Player p){ + if(p == null){ + return new BigInteger("0"); + } + String uuid = p.getUniqueId().toString(); + PlayerData playerData = Main.serverManage.getPlayerData(uuid); + return playerData.getExp(); + } + + /* + * 获取玩家总计经验 + * */ + public static BigInteger getPlayerTotalExp(Player p){ + if(p == null){ + return new BigInteger("0"); + } + String uuid = p.getUniqueId().toString(); + PlayerData playerData = Main.serverManage.getPlayerData(uuid); + return playerData.getTotalExp(); + } + + /* + * 获取玩家当前等级 + * */ + public static int getPlayerLevel(Player p){ + if(p == null){ + return -1; + } + String uuid = p.getUniqueId().toString(); + PlayerData playerData = Main.serverManage.getPlayerData(uuid); + return playerData.getLevel(); + } + + /* + * 获取玩家当前等级所需经验 + * */ + public static BigInteger getLevelNeedExp(int level){ + if(level < 0){ + return new BigInteger("99999999"); + } + BigInteger defaultExp = new BigInteger("1000"); // 默认所需经验 1000 + List> list = Main.configYml.getLevelNeedExpFormat(); + for (int i = 0; i < list.size(); i++) { + int levelKey = list.get(i).getValue(); + if(level >= levelKey) { + String expFormat = list.get(i).getKey(); + expFormat = expFormat.replace("%level%", String.valueOf(level)); + System.out.println("[调试 - 等级] 所需经验等级公式: "+expFormat); + return ScriptEngineAPI.getExpFormat(expFormat); + } + } + return defaultExp; + } + + /* + * 获取玩家当前升级所需经验 + * */ + public static BigInteger getPlayerExpToLevel(Player p){ + if(p == null){ + return new BigInteger("99999999"); + } + String uuid = p.getUniqueId().toString(); + PlayerData playerData = Main.serverManage.getPlayerData(uuid); + return getLevelNeedExp(playerData.getLevel()); + } + + /* + * 伪装击杀暴徒获得经验 + * */ + public static void disguiseKillsExp(Player p,int exp){ + // 获取服务器当前经验倍率 + double serverDouble = Main.serverManage.getExpMultiplicity(); + // 获取玩家经验加成属性 + double att_expAddition = 1; + if(AttributeAPI.getAttrData(p) != null) { + if (AttributeAPI.getAttrData(p).getAttributeValue().get("经验加成") != null) { + att_expAddition = 1 + (AttributeAPI.getAttrData(p).getAttributeValue().get("经验加成") / 100); + } + } + exp = (int) (exp * serverDouble * att_expAddition); + double magnificationDisplay = (serverDouble + att_expAddition) - 2; // 获取玩家当前倍率 + int magnificationDisplayString = (int) (magnificationDisplay * 100); + // 给予玩家经验 + addExp(p,exp); + MobDeath.experienceGainTips(p,exp,magnificationDisplayString); + } + + /* + * 给予玩家经验值 + * */ + public static void addExp(Player p,int exp){ + if(p == null){return;} + if(exp <= 0){return;} + //监听器-经验增加 + ChangExpEvant event = new ChangExpEvant(p,exp); + Bukkit.getPluginManager().callEvent(event); + // 获取玩家的PlayerData + String uuid = p.getUniqueId().toString(); + PlayerData playerData = Main.serverManage.getPlayerData(uuid); + BigInteger addExp = new BigInteger(String.valueOf(exp)); + playerData.setTotalExp(playerData.getTotalExp().add(addExp)); // 增加玩家总经验 + int level = playerData.getLevel(); // 获取玩家当前等级 + BigInteger needExp = DLevelAPI.getLevelNeedExp(level); // 获取玩家升级所需经验 + playerData.setExp(playerData.getExp().add(addExp)); // 增加玩家当前经验 + // 循环检查是否有足够的经验来升级 + while (addExp.compareTo(needExp) >= 0) { + // 检查level是否小于0,如果是则退出循环 + if (level < 0) { + break; + } + // 从addExp中减去升级所需经验 + addExp = addExp.subtract(needExp); + // 增加玩家等级 + level++; + // 更新所需经验值以升级到下一级 + needExp = DLevelAPI.getLevelNeedExp(level); + // 保存玩家数据 + playerData.savePlayerData(); + // 监听事件 - 升级等级 + UpLevelEvant upLevelEvant = new UpLevelEvant(p,level); + Bukkit.getPluginManager().callEvent(upLevelEvant); + } + playerData.setExp(addExp); + playerData.setLevel(level); + updateThePlayerExperienceBar(p,playerData); + } + + /* + * 扣除玩家的经验 + * */ + public static void takeExp(Player p,int exp){ + if(p == null){return;} + if(exp <= 0){return;} + // 获取玩家的PlayerData + String uuid = p.getUniqueId().toString(); + PlayerData playerData = Main.serverManage.getPlayerData(uuid); + BigInteger takeExp = new BigInteger(String.valueOf(exp)); + BigInteger currentExp = playerData.getTotalExp(); + if (currentExp.compareTo(takeExp) < 0) { + // 如果当前总经验少于要移除的经验,将总经验设置为0 + playerData.setTotalExp(BigInteger.ZERO); + takeExp = currentExp; + } else { + // 否则减少玩家总经验 + playerData.setTotalExp(currentExp.subtract(takeExp)); + } + int level = playerData.getLevel(); + BigInteger needExp = DLevelAPI.getLevelNeedExp(level); + BigInteger currentLevelExp = playerData.getExp(); + while (takeExp.compareTo(BigInteger.ZERO) > 0 && level >= 0) { + if (currentLevelExp.compareTo(takeExp) >= 0) { + // 当前等级的经验足够减少 + currentLevelExp = currentLevelExp.subtract(takeExp); + takeExp = BigInteger.ZERO; + } else { + // 当前等级的经验不足以完全减少,需要降级 + takeExp = takeExp.subtract(currentLevelExp); + level--; + if (level >= 0) { + needExp = DLevelAPI.getLevelNeedExp(level); + currentLevelExp = needExp.subtract(BigInteger.ONE); // 假设刚刚升级所剩经验为 needExp - 1 + } else { + currentLevelExp = BigInteger.ZERO; + break; + } + } + } + playerData.setExp(currentLevelExp); + playerData.setLevel(level); + playerData.savePlayerData(); + updateThePlayerExperienceBar(p,playerData); + } + + public static void setTotalExp(Player p,BigInteger exp){ + if(p == null){return;} + // 获取玩家的PlayerData + String uuid = p.getUniqueId().toString(); + PlayerData playerData = Main.serverManage.getPlayerData(uuid); + BigInteger totalExp = new BigInteger(String.valueOf(exp)); + playerData.setTotalExp(totalExp); + int level = 1; + // 获取当前等级1所需的经验 + BigInteger needExp = DLevelAPI.getLevelNeedExp(level); + // 循环检查总经验是否足够升级 + while (totalExp.compareTo(needExp) >= 0) { + // 从总经验中减去当前等级所需的经验 + totalExp = totalExp.subtract(needExp); + // 升级玩家等级 + level++; + // 获取下一个等级所需的经验 + needExp = DLevelAPI.getLevelNeedExp(level); + // 如果等级小于0,退出循环(虽然在实际中等级通常不会小于0) + if (level < 0) { + break; + } + } + // 更新玩家的数据 + playerData.setExp(totalExp); + playerData.setLevel(level); + updateThePlayerExperienceBar(p,playerData); + playerData.savePlayerData(); + } + + public static void setPlayerLevel(Player p,int level){ + if(p == null){return;} + if(level <= 0){return;} + // 获取玩家的PlayerData + String uuid = p.getUniqueId().toString(); + PlayerData playerData = Main.serverManage.getPlayerData(uuid); + playerData.setLevel(level); + // 初始化经验值 + BigInteger defaultExp = BigInteger.ZERO; + // 循环计算到当前等级所需的经验 + for (int i = 1; i < level; i++) { + // 获取当前等级所需经验 + BigInteger currentLevelNeedExp = DLevelAPI.getLevelNeedExp(i); + defaultExp = defaultExp.add(currentLevelNeedExp); + } + // 计算并设置玩家的经验值 + // 由于经验值是从上一级到当前级别的剩余经验 + BigInteger totalExp = defaultExp; + // 设置玩家的总经验 + setTotalExp(p,totalExp); + } + + public static void updateThePlayerExperienceBar(Player p,PlayerData playerData){ + new BukkitRunnable() { + public void run() { + int pLevel = playerData.getLevel(); + p.setLevel(pLevel); + BigInteger playerExp = playerData.getExp(); + BigInteger needLevelExp = DLevelAPI.getLevelNeedExp(pLevel); + float finalExp = playerExp.floatValue() / needLevelExp.floatValue(); + p.setExp((finalExp > 1.0F) ? 1.0F : (Math.max(finalExp, 0.0F))); + cancel(); + } + }.runTaskLater(Main.plugin, 2L); + } } diff --git a/src/main/java/me/Demon/DemonLevels/command/MainCmd.java b/src/main/java/me/Demon/DemonLevels/command/MainCmd.java new file mode 100644 index 0000000..baab0c1 --- /dev/null +++ b/src/main/java/me/Demon/DemonLevels/command/MainCmd.java @@ -0,0 +1,166 @@ +package me.Demon.DemonLevels.command; + +import com.yaohun.playermanage.PlayerManage; +import me.Demon.DemonLevels.Main; +import me.Demon.DemonLevels.api.DLevelAPI; +import me.Demon.DemonLevels.data.PlayerData; +import me.Demon.DemonLevels.util.GameUtil; +import me.Demon.DemonPlugin.DemonAPI; +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.command.*; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; + +import java.math.BigInteger; +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class MainCmd implements CommandExecutor , TabCompleter { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!sender.isOp()) { + return true; + } + if(args.length == 0){ + sender.sendMessage("§r"); + sender.sendMessage("§e------- ======= §6斗魂学院等级系统 §e======= -------"); + sender.sendMessage("§2/dlevel dexp §e[倍率] §f- §2设置经验倍率"); + sender.sendMessage("§2/dlevel dexp §e[倍率] §2 §f- §2设置经验倍率"); + sender.sendMessage("§2/dlevel look §e[玩家名] §f- §2查看等级信息"); + sender.sendMessage("§2/dlevel give §e[玩家名] §2<数值> §f- §2给予游戏经验"); + sender.sendMessage("§2/dlevel take §e[玩家名] §2<数值> §f- §2扣除游戏经验"); + sender.sendMessage("§2/dlevel setlevel §e[玩家名] §2<数值> §f- §2设置游戏等级"); + sender.sendMessage("§2/dlevel settotal §e[玩家名] §2<数值> §f- §2设置游戏总经验"); + sender.sendMessage("§2/dlevel kmob §e[怪物代号] §2 §f- §2设置怪物经验"); + sender.sendMessage("§e------- ======= §6斗魂学院等级系统 §e======= -------"); + sender.sendMessage("§r"); + return true; + } + if(args.length == 3){ + String name = args[1]; + String uuid = PlayerManage.getNameToUuid(name); + if(uuid.equalsIgnoreCase("无数据")){ + DemonAPI.sendMessage(sender,"未查询到该玩家的UUID."); + return true; + } + Player player = Bukkit.getPlayer(name); + int value = GameUtil.convertInt(args[2]); + if(value <= 1){ + DemonAPI.sendMessage(sender,"操作数值最低不得 §d低于1"); + return true; + } + if(player == null) { + DemonAPI.sendMessage(sender,"目标玩家不在线."); + return true; + } + if(args[0].equalsIgnoreCase("give")){ + DLevelAPI.addExp(player,value); + DemonAPI.sendMessage(sender,"给予 §6"+name+" §a经验: §d+"+value); + }else if(args[0].equalsIgnoreCase("take")){ + DLevelAPI.takeExp(player,value); + DemonAPI.sendMessage(sender,"扣除 §6"+name+" §a经验: §d-"+value); + }else if(args[0].equalsIgnoreCase("setlevel")){ + DLevelAPI.setPlayerLevel(player,value); + DemonAPI.sendMessage(sender,"设置 §6"+name+" §a等级: §dLv."+value); + }else if(args[0].equalsIgnoreCase("settotal")){ + BigInteger bigInteger = new BigInteger(args[2]); + DLevelAPI.setTotalExp(player,bigInteger); + DemonAPI.sendMessage(sender,"设置 §6"+name+" §a总经验: §d"+value); + } + return true; + } + if(args.length == 2 && args[0].equalsIgnoreCase("look")){ + String playerName = args[1]; + String uuid = PlayerManage.getNameToUuid(playerName); + if(uuid.equalsIgnoreCase("无数据")){ + DemonAPI.sendMessage(sender,"未查询到该玩家的UUID."); + return true; + } + Player player = Bukkit.getPlayer(playerName); + if(player == null) { + PlayerData data = new PlayerData(uuid); + DemonAPI.sendMessage(sender,"玩家 §e"+playerName+" §a的等级信息:"); + int playerLevel = data.getLevel(); + sender.sendMessage("§f- §a等级: §dLv."+playerLevel); + sender.sendMessage("§f- §a经验: §d"+data.getExp().toString()+"§a/§d"+ DLevelAPI.getLevelNeedExp(playerLevel)); + sender.sendMessage("§f- §a等级: §dLv."+data.getTotalExp().toString()); + }else{ + PlayerData data = Main.serverManage.getPlayerData(uuid); + DemonAPI.sendMessage(sender,"玩家 §e"+playerName+" §a的等级信息:"); + int playerLevel = data.getLevel(); + sender.sendMessage("§f- §a等级: §dLv."+playerLevel); + sender.sendMessage("§f- §a经验: §d"+data.getExp().toString()+"§a/§d"+ DLevelAPI.getLevelNeedExp(playerLevel)); + sender.sendMessage("§f- §a等级: §dLv."+data.getTotalExp().toString()); + } + return true; + } + if(args[0].equalsIgnoreCase("dexp")){ + if(args.length >= 2){ + double doubleExp = GameUtil.convertDouble(args[1]); + long defaultTime = 7 * 24 * 60 * 60 * 1000L; // 默认开启经验倍率时间7天 + if(args.length == 3){ + defaultTime = GameUtil.convertInt(args[2]) * 60 * 60 * 1000L; + } + long expMultipleTime = System.currentTimeMillis() + defaultTime; // 本次经验倍率持续时间 + if(doubleExp >= 1.1) { + // 将时间戳转换为 LocalDateTime + LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(expMultipleTime), ZoneId.systemDefault()); + // 定义日期时间格式化模式 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM月dd日HH时mm分"); + // 格式化日期时间 + String formattedDate = dateTime.format(formatter); + for (Player p : Bukkit.getOnlinePlayers()) { + DemonAPI.sendMessage(p, "当前经验获取倍率为: §e§l"+doubleExp*100+"%"); + p.sendTitle("§d§l"+doubleExp*100+"%","§f持续时间: §a"+formattedDate); + p.playSound(p.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1); + } + } + } + return true; + } + if(args[0].equalsIgnoreCase("kmob")){ + if(args.length >= 3){ + String mobKey = args[1]; + int min = GameUtil.convertInt(args[2]); + int max = min; + if(args.length == 4){ + max = GameUtil.convertInt(args[3]); + Main.configYml.setKillsExp(mobKey,min,max); + DemonAPI.sendMessage(sender,"成功设置 §6"+mobKey+" §a经验掉落为: §d"+min+"§a~§d"+max); + }else{ + Main.configYml.setKillsExp(mobKey,max); + DemonAPI.sendMessage(sender,"成功设置 §6"+mobKey+" §a经验掉落为: §d"+max); + } + } + return true; + } + + return false; + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { + List completions = new ArrayList<>(); + if(args.length == 1){ + completions.add("dexp"); + completions.add("look"); + completions.add("give"); + completions.add("take"); + completions.add("set"); + completions.add("settotal"); + completions.add("kmob"); + }else if(args.length == 3){ + completions.add("单位小时"); + completions.add("经验"); + completions.add("最小经验"); + }else if(args.length == 4){ + completions.add("最小经验"); + completions.add("最大经验"); + } + return completions; + } +} diff --git a/src/main/java/me/Demon/DemonLevels/data/ChangExpEvant.java b/src/main/java/me/Demon/DemonLevels/data/ChangExpEvant.java new file mode 100644 index 0000000..b4380c2 --- /dev/null +++ b/src/main/java/me/Demon/DemonLevels/data/ChangExpEvant.java @@ -0,0 +1,36 @@ +package me.Demon.DemonLevels.data; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class ChangExpEvant extends Event { + + private static HandlerList handlers = new HandlerList(); + private final Player player; + private final int exp; + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + public ChangExpEvant(Player player, int exp) { + this.player = player; + this.exp = exp; + } + + + public Player getPlayer() { + return player; + } + + public int getExp() { + return exp; + } + +} + diff --git a/src/main/java/me/Demon/DemonLevels/data/PlayerData.java b/src/main/java/me/Demon/DemonLevels/data/PlayerData.java index 1667bc8..4debdc1 100644 --- a/src/main/java/me/Demon/DemonLevels/data/PlayerData.java +++ b/src/main/java/me/Demon/DemonLevels/data/PlayerData.java @@ -1,6 +1,7 @@ package me.Demon.DemonLevels.data; import me.Demon.DemonLevels.Main; +import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; @@ -11,18 +12,15 @@ import java.math.BigInteger; import java.util.UUID; public class PlayerData { - - private Player player; - private UUID uuid; + private String uuid; private int level; private BigInteger exp; private BigInteger totalExp; private File file; private FileConfiguration fileConfiguration; - public PlayerData(Player player){ - this.player = player; - this.uuid = player.getUniqueId(); + public PlayerData(String uuid){ + this.uuid = uuid; createPlayerData(); // 若没有这个玩家的数据则会创建一个默认文件 this.level = fileConfiguration.getInt("level"); String expString = fileConfiguration.getString("exp"); @@ -31,11 +29,7 @@ public class PlayerData { this.totalExp = new BigInteger(totalExpString); } - public Player getPlayer() { - return player; - } - - public UUID getUuid() { + public String getUuid() { return uuid; } @@ -80,7 +74,7 @@ public class PlayerData { } public void createPlayerData(){ - File file = new File(Main.plugin.getDataFolder()+"/PlayerData",uuid.toString()+".yml"); + File file = new File(Main.plugin.getDataFolder()+"/PlayerData",uuid+".yml"); // 如果文件不存在,则创建新的文件 if (!file.exists()) { try { @@ -91,15 +85,18 @@ public class PlayerData { } // 加载文件配置 FileConfiguration yml = YamlConfiguration.loadConfiguration(file); - yml.set("name",player.getName()); - yml.set("uuid",player.getUniqueId().toString()); + yml.set("uuid",uuid); + Player player = Bukkit.getPlayer(UUID.fromString(uuid)); + if(player != null) { + System.out.println("[日志 - 等级] 玩家 " + player.getName() + " 已创建档案数据."); + yml.set("name",player.getName()); + } yml.set("level",1); yml.set("exp",0); yml.set("totalExp",1); this.file = file; this.fileConfiguration = yml; saveFile(); - System.out.println("[日志 - 等级] 玩家 "+player.getName()+" 已创建档案数据."); }else{ FileConfiguration yml = YamlConfiguration.loadConfiguration(file); this.file = file; diff --git a/src/main/java/me/Demon/DemonLevels/event/ChangExpEvant.java b/src/main/java/me/Demon/DemonLevels/event/ChangExpEvant.java new file mode 100644 index 0000000..8548345 --- /dev/null +++ b/src/main/java/me/Demon/DemonLevels/event/ChangExpEvant.java @@ -0,0 +1,36 @@ +package me.Demon.DemonLevels.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class ChangExpEvant extends Event { + + private static HandlerList handlers = new HandlerList(); + private final Player player; + private final int exp; + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + public ChangExpEvant(Player player, int exp) { + this.player = player; + this.exp = exp; + } + + + public Player getPlayer() { + return player; + } + + public int getExp() { + return exp; + } + +} + diff --git a/src/main/java/me/Demon/DemonLevels/event/UpLevelEvant.java b/src/main/java/me/Demon/DemonLevels/event/UpLevelEvant.java new file mode 100644 index 0000000..3ed1dd0 --- /dev/null +++ b/src/main/java/me/Demon/DemonLevels/event/UpLevelEvant.java @@ -0,0 +1,35 @@ +package me.Demon.DemonLevels.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class UpLevelEvant extends Event { + + private static HandlerList handlers = new HandlerList(); + private final Player player; + private final int level; + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + public UpLevelEvant(Player player, int level) { + this.player = player; + this.level = level; + } + + + public Player getPlayer() { + return player; + } + + public int getLevel() { + return level; + } +} + diff --git a/src/main/java/me/Demon/DemonLevels/listener/JoinEvent.java b/src/main/java/me/Demon/DemonLevels/listener/JoinEvent.java new file mode 100644 index 0000000..5600204 --- /dev/null +++ b/src/main/java/me/Demon/DemonLevels/listener/JoinEvent.java @@ -0,0 +1,28 @@ +package me.Demon.DemonLevels.listener; + +import me.Demon.DemonLevels.Main; +import me.Demon.DemonLevels.data.PlayerData; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +public class JoinEvent implements Listener { + + @EventHandler + public void onJoin(PlayerJoinEvent e){ + Player p = e.getPlayer(); + String uuid = p.getUniqueId().toString(); + Main.serverManage.getPlayerData(uuid); // 读取玩家的等级数据 + } + + @EventHandler + public void onQuit(PlayerQuitEvent e){ + // 当玩家离开服务器时保存等级数据 + Player p = e.getPlayer(); + String uuid = p.getUniqueId().toString(); + PlayerData playerData = Main.serverManage.getPlayerData(uuid); // 读取玩家的等级数据 + playerData.savePlayerData(); + } +} diff --git a/src/main/java/me/Demon/DemonLevels/listener/MobDeath.java b/src/main/java/me/Demon/DemonLevels/listener/MobDeath.java index 4a124ee..051caa6 100644 --- a/src/main/java/me/Demon/DemonLevels/listener/MobDeath.java +++ b/src/main/java/me/Demon/DemonLevels/listener/MobDeath.java @@ -2,8 +2,11 @@ package me.Demon.DemonLevels.listener; import io.lumine.xikage.mythicmobs.api.bukkit.events.MythicMobDeathEvent; import me.Demon.DemonLevels.Main; +import me.Demon.DemonLevels.api.DLevelAPI; +import me.Demon.DemonLevels.data.PlayerData; import me.Demon.DemonLevels.event.ShareExpEvent; import me.Demon.DemonLevels.manage.MobsManage; +import me.Demon.DemonPlugin.DemonAPI; import me.Demon.DemonTeam.DTeamAPI; import me.Demon.DemonTeam.TeamData; import me.Demon.DemonVipSystem.DvipAPI; @@ -18,6 +21,7 @@ import org.bukkit.event.Listener; import org.serverct.ersha.jd.AttributeAPI; import org.serverct.ersha.jd.Ha; +import java.math.BigInteger; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -34,6 +38,15 @@ public class MobDeath implements Listener { MobsManage mobsManage = Main.configYml.getMobsManage(mmKey); // 获取服务器当前经验倍率 double serverDouble = Main.serverManage.getExpMultiplicity(); + // 检测服务器经验倍率时间是否关闭 + if(Main.serverManage.isExpMultipleTime()){ + Main.serverManage.setExpMultiplicity(1.0); + serverDouble = 1.0; + for (Player p :Bukkit.getOnlinePlayers()) { + DemonAPI.sendMessage(p,"经验倍率加成已结束!已经恢复默认倍率。"); + p.playSound(p.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP,1,1); + } + } // 获取玩家经验加成属性 double att_expAddition = 1; Player p = ((Player) killer).getPlayer(); @@ -64,6 +77,7 @@ public class MobDeath implements Listener { if(!isTeamExit){ int magnificationDisplayString = (int) (magnificationDisplay * 100); // 给予玩家经验值 + DLevelAPI.addExp(p,exp); experienceGainTips(p,exp,magnificationDisplayString); if(magnificationDisplayString >= 1) { p.sendMessage("§f[§e提示§f] §7你的经验增加了§6" + exp + "§7! [§a+" + magnificationDisplayString + "%§7]"); @@ -122,6 +136,7 @@ public class MobDeath implements Listener { if(player == null){continue;} int shareExperience = (int) (teamExp / playerList.size()); // 给予玩家经验值 + DLevelAPI.addExp(p,shareExperience); experienceGainTips(player,shareExperience,magnificationDisplayString); if(magnificationDisplayString >= 1){ player.sendMessage("§f[§e提示§f] §7队伍经验分享你获得了§6" + shareExperience + "§7! [§a+" + magnificationDisplayString + "%§7]"); diff --git a/src/main/java/me/Demon/DemonLevels/listener/QuitEvent.java b/src/main/java/me/Demon/DemonLevels/listener/QuitEvent.java deleted file mode 100644 index c6efab1..0000000 --- a/src/main/java/me/Demon/DemonLevels/listener/QuitEvent.java +++ /dev/null @@ -1,16 +0,0 @@ -package me.Demon.DemonLevels.listener; - -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerQuitEvent; - -public class QuitEvent implements Listener { - - @EventHandler - public void onQuit(PlayerQuitEvent e){ - // 当玩家离开服务器时保存等级数据 - Player p = e.getPlayer(); - - } -} diff --git a/src/main/java/me/Demon/DemonLevels/listener/UpgradePrompt.java b/src/main/java/me/Demon/DemonLevels/listener/UpgradePrompt.java new file mode 100644 index 0000000..19716aa --- /dev/null +++ b/src/main/java/me/Demon/DemonLevels/listener/UpgradePrompt.java @@ -0,0 +1,34 @@ +package me.Demon.DemonLevels.listener; + +import me.Demon.DemonLevels.Main; +import me.Demon.DemonLevels.event.UpLevelEvant; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class UpgradePrompt implements Listener { + + @EventHandler + public void onUpLevel(UpLevelEvant e){ + // 获取触发事件的玩家 + Player p = e.getPlayer(); + // 获取玩家名称 + String name = p.getName(); + // 获取玩家的新等级 + int level = e.getLevel(); + // 从配置中获取当前等级对应的前缀 + String prefix = Main.configYml.getRankTitle(level); + // 广播消息,通知所有玩家该玩家达到新的境界 + Bukkit.broadcastMessage("§f[§c§l公告§f] §a玩家§e" + name + "§a境界成功达到了 §7[" + prefix + "§7]"); + // 检查玩家的等级是否是5的倍数 + if (level%5 == 0) { + // 获取玩家对象 + Player player = Bukkit.getPlayer(name); + if(player == null){return;} + // 发送消息到玩家,提示他们可以去找觉醒台 + player.sendMessage("§f[§c提示§f] §a您可以前往§e[学院]§a找到觉醒台进行武魂觉醒."); + } + } + +} diff --git a/src/main/java/me/Demon/DemonLevels/manage/MobsManage.java b/src/main/java/me/Demon/DemonLevels/manage/MobsManage.java index ae94859..db5b92c 100644 --- a/src/main/java/me/Demon/DemonLevels/manage/MobsManage.java +++ b/src/main/java/me/Demon/DemonLevels/manage/MobsManage.java @@ -1,6 +1,7 @@ package me.Demon.DemonLevels.manage; import me.Demon.DemonLevels.Main; +import me.Demon.DemonLevels.util.GameUtil; import me.Demon.DemonLevels.util.RandomUtil; import org.bukkit.configuration.file.FileConfiguration; @@ -15,15 +16,15 @@ public class MobsManage { String expString = yml.getString("MobKillExp."+mmKey); if(expString.contains("~")){ String[] strings = expString.split("~"); - minExp = convertInt(strings[0]); - maxExp = convertInt(strings[1]); + minExp = GameUtil.convertInt(strings[0]); + maxExp = GameUtil.convertInt(strings[1]); randomModel = true; }else{ - minExp = convertInt(expString); - maxExp = convertInt(expString); + minExp = GameUtil.convertInt(expString); + maxExp = GameUtil.convertInt(expString); } if(Main.Debug){ - System.out.println("[调试 - 输出] MM生物: "+mmKey+" Min: "+this.minExp+" Max: "+this.maxExp); + System.out.println("[调试 - 等级] MM生物: "+mmKey+" Min: "+this.minExp+" Max: "+this.maxExp); } } @@ -37,12 +38,4 @@ public class MobsManage { } return maxExp; } - - private int convertInt(String string){ - try { - return Integer.parseInt(string); - } catch (NumberFormatException e) { - return 1; - } - } } diff --git a/src/main/java/me/Demon/DemonLevels/manage/ServerManage.java b/src/main/java/me/Demon/DemonLevels/manage/ServerManage.java index aa788aa..d690ef7 100644 --- a/src/main/java/me/Demon/DemonLevels/manage/ServerManage.java +++ b/src/main/java/me/Demon/DemonLevels/manage/ServerManage.java @@ -1,41 +1,72 @@ package me.Demon.DemonLevels.manage; +import me.Demon.DemonLevels.Main; import me.Demon.DemonLevels.data.PlayerData; +import me.Demon.DemonPlugin.DemonAPI; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; +import org.serverct.ersha.jd.Ha; import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.UUID; public class ServerManage { - private HashMap dataHashMap = new HashMap<>(); + private HashMap dataHashMap = new HashMap<>(); private double expMultiplicity; // 当前经验倍率 + private long expMultipleTime; private boolean LinkDemonVipSystem = false; // 是否已关联 贵族系统 public ServerManage(FileConfiguration yml){ + expMultipleTime = yml.getLong("ExpMultipleTime"); + if(expMultipleTime <= 0){ + expMultipleTime = System.currentTimeMillis() + (1000 * 60); + } expMultiplicity = yml.getDouble("DoubleExp",1.0); + DemonAPI.sendConsoleMessage("§f[§a!§f] §f全服经验倍率 §8> §6"+(expMultiplicity*100)+"%"); if(Bukkit.getPluginManager().getPlugin("DemonVipSystem") != null){ LinkDemonVipSystem = true; + DemonAPI.sendConsoleMessage("§f[§a!§f] §fDemonVipSystem §8> §6完成"); } } + public long getExpMultipleTime() { + return expMultipleTime; + } + + public boolean isExpMultipleTime(){ + if(System.currentTimeMillis() >= getExpMultipleTime()){ + return true; + } + return false; + } + public double getExpMultiplicity() { return expMultiplicity; } + public void setExpMultiplicity(double expMultiplicity) { + this.expMultiplicity = expMultiplicity; + FileConfiguration yml = Main.plugin.getConfig(); + yml.set("ExpMultipleTime",this.expMultipleTime); + yml.set("DoubleExp",this.expMultiplicity); + Main.plugin.saveConfig(); + } + public boolean isLinkDemonVipSystem() { return LinkDemonVipSystem; } - public PlayerData getPlayerData(Player player){ - if(dataHashMap.get(player) == null){ - dataHashMap.put(player,new PlayerData(player)); + public PlayerData getPlayerData(String uuid){ + if(dataHashMap.get(uuid) == null){ + dataHashMap.put(uuid,new PlayerData(uuid)); } - return dataHashMap.get(player); + return dataHashMap.get(uuid); } - public HashMap getDataHashMap() { + public HashMap getDataHashMap() { return dataHashMap; } } diff --git a/src/main/java/me/Demon/DemonLevels/util/ConfigYml.java b/src/main/java/me/Demon/DemonLevels/util/ConfigYml.java index f00022f..26c4eeb 100644 --- a/src/main/java/me/Demon/DemonLevels/util/ConfigYml.java +++ b/src/main/java/me/Demon/DemonLevels/util/ConfigYml.java @@ -1,21 +1,29 @@ package me.Demon.DemonLevels.util; import me.Demon.DemonLevels.manage.MobsManage; +import me.Demon.DemonPlugin.DemonAPI; +import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; -import java.util.HashMap; -import java.util.Map; -import java.util.TreeMap; +import java.io.File; +import java.io.IOException; +import java.util.*; public class ConfigYml { + private File file; + private FileConfiguration configuration; private TreeMap rankTitleMap = new TreeMap<>(); private HashMap manageHashMap = new HashMap<>(); + private List> levelNeedExpFormat = new ArrayList<>(); - public ConfigYml(FileConfiguration yml){ + public ConfigYml(File file,FileConfiguration yml){ + this.file = file; + this.configuration = yml; loadRankTitle(yml); loadMobExperienceManagement(yml); + loadNeedExpFormat(yml); } public void loadMobExperienceManagement(FileConfiguration yml){ @@ -27,6 +35,18 @@ public class ConfigYml { for (String mmKey : section.getKeys(false)){ manageHashMap.put(mmKey,new MobsManage(mmKey,yml)); } + DemonAPI.sendConsoleMessage("§f[§a!§f] §fMm怪经验 §8> §6"+manageHashMap.size()+"个"); + } + + public void setKillsExp(String mmKey,int max){ + configuration.set("MobKillExp."+mmKey,max); + saveFile(); + manageHashMap.put(mmKey,new MobsManage(mmKey,configuration)); + } + public void setKillsExp(String mmKey,int min,int max){ + configuration.set("MobKillExp."+mmKey,min+"~"+max); + saveFile(); + manageHashMap.put(mmKey,new MobsManage(mmKey,configuration)); } public MobsManage getMobsManage(String mmKey){ @@ -49,9 +69,10 @@ public class ConfigYml { rankTitleMap.put(level,title); } } + DemonAPI.sendConsoleMessage("§f[§a!§f] §f境界称号 §8> §6"+rankTitleMap.size()+"个"); } - private String getRankTitle(int level) { + public String getRankTitle(int level) { Map.Entry entry = rankTitleMap.floorEntry(level); if (entry != null) { return entry.getValue(); @@ -59,4 +80,34 @@ public class ConfigYml { return "§7器士"; } + + public void loadNeedExpFormat(FileConfiguration yml){ + ConfigurationSection section = yml.getConfigurationSection("NeelUpExp"); + if(section == null){ + System.out.println("[错误报告] NeelUpExp 配置不存在."); + return; + } + HashMap stringHashMap = new HashMap<>(); + for (String levelKey : section.getKeys(false)){ + int level = Integer.parseInt(levelKey); + String expFormat = section.getString(levelKey).replace(" ",""); + stringHashMap.put(expFormat,level); + } + List> entryArrayList = new ArrayList<>(stringHashMap.entrySet()); + entryArrayList.sort((o1, o2) -> o2.getValue().compareTo(o1.getValue())); + this.levelNeedExpFormat = entryArrayList; + DemonAPI.sendConsoleMessage("§f[§a!§f] §f自定义经验 §8> §6"+levelNeedExpFormat.size()+"条"); + } + + public List> getLevelNeedExpFormat() { + return levelNeedExpFormat; + } + + public void saveFile(){ + try { + this.configuration.save(this.file); + } catch (IOException e) { + e.printStackTrace(); + } + } } diff --git a/src/main/java/me/Demon/DemonLevels/util/GameUtil.java b/src/main/java/me/Demon/DemonLevels/util/GameUtil.java new file mode 100644 index 0000000..46e8da2 --- /dev/null +++ b/src/main/java/me/Demon/DemonLevels/util/GameUtil.java @@ -0,0 +1,20 @@ +package me.Demon.DemonLevels.util; + +public abstract class GameUtil { + + public static int convertInt(String string){ + try { + return Integer.parseInt(string); + } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) { + return 1; + } + } + + public static double convertDouble(String string){ + try { + return Double.parseDouble(string); + } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) { + return 1.0; + } + } +} diff --git a/src/main/java/me/Demon/DemonLevels/util/ScriptEngineAPI.java b/src/main/java/me/Demon/DemonLevels/util/ScriptEngineAPI.java new file mode 100644 index 0000000..a6066c6 --- /dev/null +++ b/src/main/java/me/Demon/DemonLevels/util/ScriptEngineAPI.java @@ -0,0 +1,33 @@ +package me.Demon.DemonLevels.util; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import java.math.BigInteger; + +public class ScriptEngineAPI { + + public static BigInteger getExpFormat(String ExpFormat) { + // 检查表达式是否包含无效字符 + if (isValidExpression(ExpFormat)) { + try { + // 创建一个脚本引擎管理器 + ScriptEngineManager manager = new ScriptEngineManager(); + // 获取一个 JavaScript 引擎实例 + ScriptEngine engine = manager.getEngineByName("JavaScript"); + // 执行表达式并获取结果 + Object result = engine.eval(ExpFormat); + // 输出结果 + return new BigInteger(result.toString()); + } catch (ScriptException e) { + e.printStackTrace(); + } + } + return new BigInteger("0"); + } + + private static boolean isValidExpression(String expression) { + return expression.matches("[0-9\\s+\\-*/()]+"); + } + +}