From 4d09482fb1847689a09455a7582806155d157d91 Mon Sep 17 00:00:00 2001 From: ch2012enyc Date: Sat, 25 Oct 2025 18:27:24 +0800 Subject: [PATCH] update 8 --- .../java/org/xgqy/survival/PlayerTags.java | 125 ++----- src/main/java/org/xgqy/survival/Survival.java | 342 ++++++++++++++++-- .../survival/command/HelpCommandExecutor.java | 1 + .../xgqy/survival/event/ChooseTagEvent.java | 6 +- .../org/xgqy/survival/event/JoinEvent.java | 6 + src/main/resources/plugin.yml | 21 ++ 6 files changed, 373 insertions(+), 128 deletions(-) diff --git a/src/main/java/org/xgqy/survival/PlayerTags.java b/src/main/java/org/xgqy/survival/PlayerTags.java index 0edd009..1d7f320 100644 --- a/src/main/java/org/xgqy/survival/PlayerTags.java +++ b/src/main/java/org/xgqy/survival/PlayerTags.java @@ -17,14 +17,10 @@ import java.util.UUID; public class PlayerTags { private final Survival plugin; private final File tagsFile; - // 原有:玩家-称号列表映射 private final Map> playerTags = new HashMap<>(); - // 新增:玩家-(称号-到期时间戳)映射(毫秒级,永久用Long.MAX_VALUE) private final Map> expireTimeMap = new HashMap<>(); - // 原有:玩家-选中称号索引映射 public Map playerselectTag = new HashMap<>(); - // 常量:7天的毫秒数(7*24*60*60*1000) private static final long SEVEN_DAYS_MS = 604800000L; public PlayerTags(Survival plugin) { @@ -32,36 +28,28 @@ public class PlayerTags { this.tagsFile = new File(plugin.getDataFolder(), "playertags.data"); } - /** - * 核心辅助:清理玩家的所有过期称号(所有方法调用前先执行) - */ public void cleanExpiredTags(Player player) { UUID uuid = player.getUniqueId(); List validTags = new ArrayList<>(); List allTags = playerTags.getOrDefault(uuid, new ArrayList<>()); Map tagExpires = expireTimeMap.getOrDefault(uuid, new HashMap<>()); - // 遍历所有称号,保留未过期的 for (String tag : allTags) { long expireTime = tagExpires.getOrDefault(tag, Long.MAX_VALUE); - // 未过期判断:永久(MAX)或当前时间 < 到期时间 if (expireTime == Long.MAX_VALUE || System.currentTimeMillis() < expireTime) { validTags.add(tag); } else { - // 过期:移除过期时间记录 tagExpires.remove(tag); } } - // 更新有效称号列表和过期时间映射 if (validTags.isEmpty()) { playerTags.remove(uuid); expireTimeMap.remove(uuid); - playerselectTag.put(uuid, -1); // 无有效称号,重置选中索引 + playerselectTag.put(uuid, -1); } else { playerTags.put(uuid, validTags); expireTimeMap.put(uuid, tagExpires); - // 检查选中的称号是否已过期:若过期/索引无效,重置索引 int currentIndex = playerselectTag.getOrDefault(uuid, -1); if (currentIndex == -1 || currentIndex >= validTags.size()) { playerselectTag.put(uuid, -1); @@ -69,11 +57,8 @@ public class PlayerTags { } } - /** - * 获取当前选中的称号索引(自动过滤过期) - */ public int getCurrentTag(Player player) { - cleanExpiredTags(player); // 先清理过期 + cleanExpiredTags(player); UUID uuid = player.getUniqueId(); Integer index = playerselectTag.get(uuid); if (index == null) { @@ -82,34 +67,29 @@ public class PlayerTags { List validTags = playerTags.getOrDefault(uuid, new ArrayList<>()); if (validTags.isEmpty() || index < 0 || index >= validTags.size()) { - playerselectTag.put(uuid, -1); // 索引无效,重置 + playerselectTag.put(uuid, -1); return -1; } return index; } - /** - * 设置玩家选择的标签索引(自动过滤过期) - */ public boolean setSelectedTag(Player player, int index) { - cleanExpiredTags(player); // 先清理过期 + cleanExpiredTags(player); UUID uuid = player.getUniqueId(); List validTags = playerTags.getOrDefault(uuid, new ArrayList<>()); - // 无有效称号或索引无效,返回失败 if (validTags.isEmpty() || index < 0 || index >= validTags.size()) { playerselectTag.put(uuid, -1); return false; } - // 设置选中索引,返回成功 playerselectTag.put(uuid, index); return true; } /** - * 加载称号数据:核心逻辑——识别旧数据并转为7天过期 + * 修复核心:正确读取新版本数据中的expireTimeMap,避免误判为旧数据 */ @SuppressWarnings("unchecked") public void loadTags() { @@ -118,17 +98,27 @@ public class PlayerTags { } try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(tagsFile))) { - // 读取第一个对象:判断是旧版本(List)还是新版本(含过期时间) + // 读取三个核心对象(新版本数据结构) Object firstObj = ois.readObject(); Object secondObj = ois.readObject(); - Object thirdObj = null; // 新版本的第三个对象:expireTimeMap + Object thirdObj = ois.readObject(); // 关键修复:读取第三个对象(expireTimeMap) - // 1. 识别旧版本数据(仅2个对象:playerTags + playerselectTag) - if (firstObj instanceof Map && secondObj instanceof Map && ois.available() == 0) { + // 1. 优先判断新版本数据(3个对象完整) + if (firstObj instanceof Map && secondObj instanceof Map && thirdObj instanceof Map) { + // 强制转换并加载数据 + playerTags.putAll((Map>) firstObj); + playerselectTag.putAll((Map) secondObj); + expireTimeMap.putAll((Map>) thirdObj); + plugin.getLogger().info("新版本称号数据加载完成!共加载 " + playerTags.size() + " 个玩家的称号"); + return; // 加载成功直接返回,避免进入旧数据处理 + } + + // 2. 处理旧版本数据(仅2个对象:无expireTimeMap) + if (firstObj instanceof Map && secondObj instanceof Map) { Map> oldPlayerTags = (Map>) firstObj; Map oldSelectTag = (Map) secondObj; - // 旧数据转换:为每个称号设置“当前时间+7天”的到期时间 + // 旧数据转换为7天过期 for (Map.Entry> entry : oldPlayerTags.entrySet()) { UUID uuid = entry.getKey(); List oldTags = entry.getValue(); @@ -136,34 +126,27 @@ public class PlayerTags { continue; } - // 为当前玩家创建“称号-到期时间”映射 Map tagExpires = new HashMap<>(); - long sevenDaysLater = System.currentTimeMillis() + SEVEN_DAYS_MS; // 7天后到期 + long sevenDaysLater = System.currentTimeMillis() + SEVEN_DAYS_MS; for (String tag : oldTags) { - tagExpires.put(tag, sevenDaysLater); // 每个旧称号都设为7天过期 + tagExpires.put(tag, sevenDaysLater); } - // 存入新结构 - playerTags.put(uuid, new ArrayList<>(oldTags)); // 复制旧称号列表 - expireTimeMap.put(uuid, tagExpires); // 存入7天过期时间 + playerTags.put(uuid, new ArrayList<>(oldTags)); + expireTimeMap.put(uuid, tagExpires); } - // 恢复选中索引 playerselectTag.putAll(oldSelectTag); plugin.getLogger().info("旧版本称号数据加载完成,已自动转为7日后到期!"); + return; + } - } - // 2. 识别新版本数据(3个对象:playerTags + playerselectTag + expireTimeMap) - else if (firstObj instanceof Map && secondObj instanceof Map && thirdObj instanceof Map) { - playerTags.putAll((Map>) firstObj); - playerselectTag.putAll((Map) secondObj); - expireTimeMap.putAll((Map>) thirdObj); - plugin.getLogger().info("新版本称号数据加载完成!"); - } + // 3. 数据格式错误 + plugin.getLogger().warning("称号数据格式错误,无法识别!"); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); - // 回退逻辑:仅加载称号列表,所有称号设为7天过期 + // 回退逻辑:仅加载称号列表,设为7天过期 try (ObjectInputStream fallback = new ObjectInputStream(new FileInputStream(tagsFile))) { Object obj = fallback.readObject(); if (obj instanceof Map oldPlayerTags) { @@ -176,7 +159,7 @@ public class PlayerTags { for (Object tagObj : (List) entry.getValue()) { if (tagObj instanceof String tag) { tags.add(tag); - tagExpires.put(tag, sevenDaysLater); // 回退时也设为7天过期 + tagExpires.put(tag, sevenDaysLater); } } @@ -193,16 +176,13 @@ public class PlayerTags { } } - /** - * 保存称号数据:同步保存playerTags、playerselectTag、expireTimeMap - */ public void saveTags() { if (!tagsFile.getParentFile().exists()) { tagsFile.getParentFile().mkdirs(); } try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(tagsFile))) { - // 按顺序写入3个核心结构(新版本) + // 按顺序写入三个核心结构(与加载时对应) oos.writeObject(playerTags); oos.writeObject(playerselectTag); oos.writeObject(expireTimeMap); @@ -211,71 +191,50 @@ public class PlayerTags { } } - /** - * 获取玩家的有效称号列表(自动过滤过期) - */ public List getTags(Player player) { cleanExpiredTags(player); return playerTags.getOrDefault(player.getUniqueId(), new ArrayList<>()); } - /** - * 新增称号:默认永久(可手动指定过期时间) - * - * @param player 目标玩家 - * @param tag 称号名称 - * @param isPermanent 是否永久(true=永久,false=7天过期) - */ public void addTag(Player player, String tag, boolean isPermanent) { - cleanExpiredTags(player); // 先清理过期 + cleanExpiredTags(player); UUID uuid = player.getUniqueId(); List tags = playerTags.computeIfAbsent(uuid, k -> new ArrayList<>()); Map tagExpires = expireTimeMap.computeIfAbsent(uuid, k -> new HashMap<>()); - // 避免重复添加相同称号 if (!tags.contains(tag)) { tags.add(tag); - // 设置过期时间:永久=Long.MAX_VALUE,临时=当前时间+7天 long expireTime = isPermanent ? Long.MAX_VALUE : System.currentTimeMillis() + SEVEN_DAYS_MS; tagExpires.put(tag, expireTime); } } - /** - * 重载原有addTag方法:默认添加永久称号(保持向下兼容) - */ public void addTag(Player player, String tag, int days) { - cleanExpiredTags(player); // 先清理过期 + cleanExpiredTags(player); UUID uuid = player.getUniqueId(); List tags = playerTags.computeIfAbsent(uuid, k -> new ArrayList<>()); Map tagExpires = expireTimeMap.computeIfAbsent(uuid, k -> new HashMap<>()); - // 避免重复添加相同称号 if (!tags.contains(tag)) { tags.add(tag); long expireTime; if (days == 999) { - expireTime = Long.MAX_VALUE; // 999天视为永久 + expireTime = Long.MAX_VALUE; } else if (days <= 0) { - expireTime = System.currentTimeMillis() - 1; // 天数≤0:立即过期(触发清理) + expireTime = System.currentTimeMillis() - 1; } else { - // 计算有效期:当前时间 + 天数×24×60×60×1000(转换为毫秒) expireTime = System.currentTimeMillis() + (long) days * 24 * 60 * 60 * 1000; } tagExpires.put(tag, expireTime); } } - /** - * 移除称号:同时删除过期时间记录 - */ public void removeTag(Player player, String tag) { cleanExpiredTags(player); UUID uuid = player.getUniqueId(); List tags = playerTags.get(uuid); Map tagExpires = expireTimeMap.get(uuid); - // 移除称号列表和过期时间映射中的对应条目 if (tags != null) { tags.remove(tag); if (tags.isEmpty()) { @@ -293,7 +252,6 @@ public class PlayerTags { } } - // 若移除的是当前选中称号,重置索引 int currentIndex = playerselectTag.getOrDefault(uuid, -1); List validTags = playerTags.getOrDefault(uuid, new ArrayList<>()); if (currentIndex != -1 && (currentIndex >= validTags.size() || !validTags.contains(tag))) { @@ -301,30 +259,20 @@ public class PlayerTags { } } - /** - * 新增:获取称号的到期时间(返回时间戳,单位毫秒) - * - * @return 永久返回-1,过期/不存在返回-2,有效返回到期时间戳 - */ public long getTagExpireTime(Player player, String tag) { cleanExpiredTags(player); UUID uuid = player.getUniqueId(); Map tagExpires = expireTimeMap.getOrDefault(uuid, new HashMap<>()); List validTags = playerTags.getOrDefault(uuid, new ArrayList<>()); - // 称号不存在或已过期,返回-2 if (!validTags.contains(tag)) { return -2; } long expireTime = tagExpires.getOrDefault(tag, Long.MAX_VALUE); - // 永久称号返回-1,否则返回时间戳 return expireTime == Long.MAX_VALUE ? -1 : expireTime; } - /** - * 新增:获取称号的剩余时间(返回字符串,如“2天3小时”) - */ public String getTagRemainingTime(Player player, String tag) { long expireTime = getTagExpireTime(player, tag); if (expireTime == -1) { @@ -334,18 +282,15 @@ public class PlayerTags { return "已过期/不存在"; } - // 计算剩余毫秒数(可能为负,需处理) long remainingMs = expireTime - System.currentTimeMillis(); if (remainingMs <= 0) { return "已过期"; } - // 转换为天、时、分 long days = remainingMs / (24 * 60 * 60 * 1000); long hours = (remainingMs % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000); long minutes = (remainingMs % (60 * 60 * 1000)) / (60 * 1000); - // 拼接剩余时间字符串 StringBuilder sb = new StringBuilder(); if (days > 0) sb.append(days).append("天"); if (hours > 0) sb.append(hours).append("小时"); diff --git a/src/main/java/org/xgqy/survival/Survival.java b/src/main/java/org/xgqy/survival/Survival.java index 6b330f8..fc9bea1 100644 --- a/src/main/java/org/xgqy/survival/Survival.java +++ b/src/main/java/org/xgqy/survival/Survival.java @@ -3,15 +3,23 @@ package org.xgqy.survival; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; import org.xgqy.survival.command.DqshopCommandExecutor; +import org.xgqy.survival.command.FriendCommandExecutor; import org.xgqy.survival.command.HandleCommandExecutor; import org.xgqy.survival.command.HelpCommandExecutor; import org.xgqy.survival.command.HubCommandExecutor; +import org.xgqy.survival.command.InventoryCommandExecutor; +import org.xgqy.survival.command.KillCommandExecutor; +import org.xgqy.survival.command.LandCommandExecutor; import org.xgqy.survival.command.LoginCommandExecutor; import org.xgqy.survival.command.PartyCommandExecutor; +import org.xgqy.survival.command.PcCommandExecutor; +import org.xgqy.survival.command.PointCommandExecutor; import org.xgqy.survival.command.PvpCommandExecutor; import org.xgqy.survival.command.RegCommandExecutor; import org.xgqy.survival.command.ReportCommandExecutor; @@ -20,25 +28,34 @@ import org.xgqy.survival.command.TagCommandExecutor; import org.xgqy.survival.command.TeleportCommandExecutor; import org.xgqy.survival.command.TpAccCommandExecutor; import org.xgqy.survival.command.TpFinCommandExecutor; +import org.xgqy.survival.command.msgCommandExecutor; import org.xgqy.survival.event.ChatEvent; import org.xgqy.survival.event.ChooseTagEvent; import org.xgqy.survival.event.JoinEvent; +import org.xgqy.survival.event.LandEvent; import org.xgqy.survival.event.LoginEvent; -import org.xgqy.survival.event.QuitEvent; +import java.io.File; +import java.io.IOException; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; public final class Survival extends JavaPlugin { private PlayerTags playerTags; - private AccountManager accountManager; // 新增账号管理器 + private AccountManager accountManager; public Map krt = new HashMap<>(); public Map banlist = new HashMap<>(); public Map banreason = new HashMap<>(); public Map> reportlist = new HashMap<>(); + // Teleport public Map teleport = new HashMap<>(); public Map Ateleport = new HashMap<>(); public Map teleportp = new HashMap<>(); @@ -50,95 +67,348 @@ public final class Survival extends JavaPlugin { party ---------------------------------------- */ - public Map party = new HashMap<>(); - public Map> partyp = new HashMap<>(); - public Map owner = new HashMap<>(); - public Map> ban = new HashMap<>(); + public Map party = new HashMap<>(); + public Map> partyp = new HashMap<>(); + public Map owner = new HashMap<>(); + public Map> ban = new HashMap<>(); /* ---------------------------------------- friend ---------------------------------------- */ - public Map> friends = new HashMap<>(); + public Map> friends = new ConcurrentHashMap<>(); + public Map> waiting = new ConcurrentHashMap<>(); /* ---------------------------------------- + 信用分 ---------------------------------------- */ + public Map ppoint = new HashMap<>(); private List msg = new ArrayList<>(); + public Map breason = new HashMap<>(); + /* + ---------------------------------------- + 领地 + ---------------------------------------- + */ + public static class Land{ + public Location start,end; + public List defaultperm; + public String owner; + public Map> perm; + public boolean boomb; + public Land(Location start,Location end,List defaultperm,String owner,Map> perm){ + this.start=start; + this.end=end; + this.defaultperm = defaultperm; + this.owner=owner; + this.perm=perm; + } + public Boolean getBoomb(){ + return boomb; + } + public void setBoomb(Boolean boomb){ + this.boomb=boomb; + } + public Location getStart(){ + return start; + } + public Location getEnd(){ + return end; + } + public List getDefaultperm(){ + return defaultperm; + } + public String getOwner(){ + return owner; + } + public List getPerm(Player player){ + return perm.getOrDefault(player,null); + } + public void setStart(Location start){ + this.start=start; + } + public void setEnd(Location end) { + this.end = end; + } + public void setDefaultperm(List defaultperm){ + this.defaultperm=defaultperm; + } + public void setOwner(String owner){ + this.owner=owner; + } + public void setPerm(Player player,List perm){ + this.perm.put(player.getName(),perm); + } + } + public List land =new ArrayList<>(); + + public Map inland=new HashMap<>(); + // 信用分数据文件相关 + private File ppointFile; + private FileConfiguration ppointConfig; @Override public void onEnable() { // 初始化账号管理器 accountManager = new AccountManager(this); - msg.add(ChatColor.GREEN+"可以用 /help 命令来查看命令列表"); - msg.add(ChatColor.GREEN+"如果遇到作弊玩家可以用 /report <玩家名> <原因> 来举报!管理员会很快处理的"); - msg.add(ChatColor.GREEN+"想传送到玩家怎么办? 用 /teleport <玩家名> 命令!"); - msg.add(ChatColor.GREEN+"更换IP但没有更换账号导致的封禁不能找管理员解决"); - msg.add(ChatColor.GREEN+"星阁钱语的名称其实叫星阁浅语"); - msg.add(ChatColor.RED+"作弊会导致账号封禁!请不要作弊"); - msg.add(ChatColor.RED+"在服务器内说不文明用语会导致账号被封禁,请不要这样做"); - msg.add(ChatColor.GREEN+"今天签到了吗?快输入 /qd 签到吧!"); - msg.add(ChatColor.GREEN+"其实可以输入 /pvp 来开启/关闭自己的pvp模式"); - msg.add(ChatColor.RED+"你不可以把别人的家毁掉!这样你将会受到处罚"); - msg.add(ChatColor.GOLD+"能给我捐点钱吗"); + // 初始化信用分数据文件 + initPpointFile(); + // 加载已在线玩家的信用分数据 + loadPpoint(); - new BukkitRunnable(){ + msg.add(ChatColor.GREEN + "可以用 /help 命令来查看命令列表"); + msg.add(ChatColor.GREEN + "如果遇到作弊玩家可以用 /report <玩家名> <原因> 来举报!管理员会很快处理的"); + msg.add(ChatColor.GREEN + "想传送到玩家怎么办? 用 /teleport <玩家名> 命令!"); + msg.add(ChatColor.GREEN + "更换IP但没有更换账号导致的封禁不能找管理员解决"); + msg.add(ChatColor.GREEN + "星阁钱语的名称其实叫星阁浅语"); + msg.add(ChatColor.RED + "作弊会导致账号封禁!请不要作弊"); + msg.add(ChatColor.RED + "在服务器内说不文明用语会导致账号被封禁,请不要这样做"); + msg.add(ChatColor.GREEN + "今天签到了吗?快输入 /qd 签到吧!"); + msg.add(ChatColor.GREEN + "其实可以输入 /pvp 来开启/关闭自己的pvp模式"); + msg.add(ChatColor.RED + "你不可以把别人的家毁掉!这样你将会受到处罚"); + msg.add(ChatColor.GREEN + "每日坚持签到可以获得信用分"); + msg.add(ChatColor.GREEN + "服务器官网: https://starpavilion.xyz"); + msg.add(ChatColor.GREEN + "赞助我们? https://starpavilion.xyz/sponsor.html"); + msg.add(ChatColor.RED+"封禁者会在此处公示: https://starpavilion.xyz/bans.html"); + msg.add(ChatColor.RED + "信用分过低将会导致你的账号受限甚至永久封禁!"); + msg.add(ChatColor.GREEN + "信用分被扣除会提醒,如果您的信用分被莫名扣除,请及时到QQ群 717903781 申诉。"); + + new BukkitRunnable() { @Override public void run() { - for(Player plr : Bukkit.getOnlinePlayers()){ + for (Player plr : Bukkit.getOnlinePlayers()) { // 只向已登录玩家发送提示 if (accountManager.isLoggedIn(plr)) { - plr.sendMessage(ChatColor.LIGHT_PURPLE+"小提示 "+ChatColor.WHITE+" | "+msg.get((int)(Math.random()*10000)%msg.size())); + plr.sendMessage(ChatColor.LIGHT_PURPLE + "小提示 " + ChatColor.WHITE + " | " + msg.get((int) (Math.random() * 10000) % msg.size())); } } } - }.runTaskLater(this,20*60); + }.runTaskLater(this, 20 * 60); - // Plugin startup logic + new BukkitRunnable() { + @Override + public void run() { + for (Player plr : Bukkit.getOnlinePlayers()) { + // 检查玩家是否有违规扣分记录 + if (plr.getScoreboard().getObjective("handled") != null && + plr.getScoreboard().getObjective("handled").getScore(plr).getScore() != 0) { + + ZonedDateTime beijingTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai")); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + String formattedTime = beijingTime.format(formatter); + + // 确保玩家信用分已初始化 + int currentPoint = ppoint.getOrDefault(plr, 100); + int deductPoint = plr.getScoreboard().getObjective("handled").getScore(plr).getScore(); + int newPoint = currentPoint - deductPoint; + //ppoint.put(plr, newPoint); + + // 发送扣分提示 + plr.sendMessage(ChatColor.RED + "警告" + ChatColor.WHITE + " | " + ChatColor.RED + "您的账号 " + ChatColor.YELLOW + plr.getName() + ChatColor.RED + " 在 " + ChatColor.WHITE + formattedTime + ChatColor.RED + " 有疑似违规行为,扣取信用分 " + ChatColor.YELLOW + deductPoint + ChatColor.RED + " 分。\n"); + plr.sendMessage(ChatColor.RED + "-----------警告单-----------"); + plr.sendMessage(ChatColor.RED + "|账号名: " + ChatColor.YELLOW + plr.getName()); + plr.sendMessage(ChatColor.RED + "|违规时间: " + ChatColor.YELLOW + formattedTime); + plr.sendMessage(ChatColor.RED + "|违规行为: " + ChatColor.YELLOW + breason.getOrDefault(plr, "管理员扣分")); + plr.sendMessage(ChatColor.RED + "|违规扣分: " + ChatColor.YELLOW + deductPoint + " 分"); + plr.sendMessage(ChatColor.RED + "|剩余信用分: " + ChatColor.YELLOW + newPoint); + + // 根据剩余信用分执行处罚 + if (newPoint > 80) { + plr.sendMessage(ChatColor.RED + "|采取处罚: " + ChatColor.YELLOW + "无"); + } else if (newPoint <= 0) { + plr.kickPlayer(ChatColor.RED + "您好! 您由于在 " + formattedTime + " 信用分小于 0 ,我们决定对你的账号 " + plr.getName() + " 采取\n" + ChatColor.RED + ChatColor.BOLD + "永久封禁\n" + ChatColor.RED + "措施,如果您想解封您的账号,请到QQ群 717903781 申诉\n\n" + ChatColor.RED + "如果您对本次处罚不满,请采取以下措施:\n" + ChatColor.YELLOW + "1.如果您对自己的行为" + ChatColor.BOLD + " 问心无愧 " + ChatColor.YELLOW + "请立即向QQ 2213866559 发送解封申请\n" + ChatColor.YELLOW + "2.如果您属实有违规行为,请" + ChatColor.BOLD + "手写" + ChatColor.YELLOW + "一篇 " + ChatColor.BOLD + "100字以上且AIGC合格" + ChatColor.YELLOW + " 的检讨发送到申诉QQ群,态度诚恳我们将会对你进行解封"); + } else if (newPoint <= 20) { + plr.sendMessage(ChatColor.RED + "|采取处罚: " + ChatColor.YELLOW + "限制行为及发言,列入监管名单,限制功能使用"); + } else if (newPoint <= 50) { + plr.sendMessage(ChatColor.RED + "|采取处罚: " + ChatColor.YELLOW + "限制行为及发言,限制功能使用"); + } else if (newPoint <= 80) { + plr.sendMessage(ChatColor.RED + "|采取处罚: " + ChatColor.YELLOW + "监管行为及发言,签到将奖励转换为信用分"); + } + plr.sendMessage(ChatColor.RED + "|为了维护游戏环境,请不要违规!"); + plr.sendMessage(ChatColor.RED + "----------------------------"); + + // 清理临时数据 + breason.remove(plr); + plr.getScoreboard().getObjective("handled").getScore(plr).setScore(0); + + // 实时保存扣分后的信用分数据 + savePpoint(); + } + } + } + }.runTaskTimer(this, 20 * 5, 20 * 5); + + // 初始化玩家标签 playerTags = new PlayerTags(this); playerTags.loadTags(); - // 注册事件监听器,包括新的登录事件 + // 注册事件监听器 Bukkit.getPluginManager().registerEvents(new JoinEvent(this), this); Bukkit.getPluginManager().registerEvents(new ChatEvent(this), this); Bukkit.getPluginManager().registerEvents(new ChooseTagEvent(this), this); - Bukkit.getPluginManager().registerEvents(new LoginEvent(this), this); // 新增登录事件监听器 - Bukkit.getPluginManager().registerEvents(new QuitEvent(this),this); - //Bukkit.getPluginManager().registerEvents(new AntiExploit(),this); - //Bukkit.getPluginManager().registerEvents(new AntiXray(this),this); + Bukkit.getPluginManager().registerEvents(new LoginEvent(this), this); + Bukkit.getPluginManager().registerEvents(new LandEvent(this),this); - // 注册命令执行器,包括新的注册和登录命令 + // 注册命令执行器 getCommand("report").setExecutor(new ReportCommandExecutor(this)); getCommand("handle").setExecutor(new HandleCommandExecutor(this)); getCommand("pvp").setExecutor(new PvpCommandExecutor(this)); getCommand("settag").setExecutor(new SetTagCommandExecutor(this)); getCommand("help").setExecutor(new HelpCommandExecutor(this)); - //getCommand("fly").setExecutor(new FlyCommandExecutor(this)); getCommand("tag").setExecutor(new TagCommandExecutor(this)); getCommand("hub").setExecutor(new HubCommandExecutor(this)); getCommand("teleport").setExecutor(new TeleportCommandExecutor(this)); getCommand("tpacc").setExecutor(new TpAccCommandExecutor(this)); getCommand("tpfin").setExecutor(new TpFinCommandExecutor(this)); getCommand("shop").setExecutor(new DqshopCommandExecutor(this)); - getCommand("reg").setExecutor(new RegCommandExecutor(this)); // 新增注册命令 - getCommand("login").setExecutor(new LoginCommandExecutor(this)); // 新增登录命令 + getCommand("reg").setExecutor(new RegCommandExecutor(this)); + getCommand("login").setExecutor(new LoginCommandExecutor(this)); getCommand("party").setExecutor(new PartyCommandExecutor(this)); + getCommand("inventory").setExecutor(new InventoryCommandExecutor(this)); + getCommand("pc").setExecutor(new PcCommandExecutor(this)); + getCommand("msg").setExecutor(new msgCommandExecutor(this)); + getCommand("friend").setExecutor(new FriendCommandExecutor(this)); + getCommand("point").setExecutor(new PointCommandExecutor(this)); + getCommand("selfkill").setExecutor(new KillCommandExecutor(this)); + getCommand("land").setExecutor(new LandCommandExecutor(this)); + getLogger().info("Survival插件已启用,信用分持久化功能加载完成!"); } @Override public void onDisable() { + // 保存玩家标签数据 playerTags.saveTags(); - accountManager.saveAccounts(); // 保存账号信息 - // Plugin shutdown logic + + // 保存信用分数据 + savePpoint(); + + // 保存好友数据 + try { + FriendCommandExecutor executor = (FriendCommandExecutor) this.getCommand("friend").getExecutor(); + if (executor != null) { + executor.saveFriendData(); + getLogger().info("好友数据已保存!"); + } + } catch (Exception e) { + getLogger().severe("插件卸载时保存好友数据失败:" + e.getMessage()); + } + + // 保存账号信息 + accountManager.saveAccounts(); + + getLogger().info("Survival插件已禁用,所有数据已保存!"); } + // 初始化信用分数据文件 + private void initPpointFile() { + // 创建插件数据文件夹(若不存在) + File dataFolder = getDataFolder(); + if (!dataFolder.exists()) { + if (dataFolder.mkdirs()) { + getLogger().info("插件数据文件夹创建成功!"); + } else { + getLogger().severe("插件数据文件夹创建失败!"); + return; + } + } + + // 创建信用分文件(路径:plugins/Survival/ppoint.yml) + ppointFile = new File(dataFolder, "ppoint.yml"); + if (!ppointFile.exists()) { + try { + if (ppointFile.createNewFile()) { + getLogger().info("信用分数据文件创建成功!"); + } else { + getLogger().severe("信用分数据文件创建失败!"); + } + } catch (IOException e) { + getLogger().severe("创建信用分文件时发生异常:" + e.getMessage()); + } + } + + // 加载配置文件 + ppointConfig = YamlConfiguration.loadConfiguration(ppointFile); + } + + // 保存信用分数据到文件(关键修正处) + public void savePpoint() { + if (ppointConfig == null || ppointFile == null) { + getLogger().severe("信用分配置未初始化,保存失败!"); + return; + } + + // 修正:清空原有配置的正确方式(将所有键设为null或移除) + for (String key : ppointConfig.getKeys(false)) { + ppointConfig.set(key, null); // 用null覆盖原有值,或用 ppointConfig.remove(key) 直接移除键 + } + + // 将在线玩家的信用分存入配置(用UUID作为键,参数完整) + for (Map.Entry entry : ppoint.entrySet()) { + Player player = entry.getKey(); + if (player.isOnline()) { + UUID playerUuid = player.getUniqueId(); + ppointConfig.set(playerUuid.toString(), entry.getValue()); // 完整参数:路径(UUID字符串)+ 值(信用分) + } + } + + // 写入文件 + try { + ppointConfig.save(ppointFile); + getLogger().info("信用分数据保存成功!"); + } catch (IOException e) { + getLogger().severe("保存信用分数据失败:" + e.getMessage()); + } + } + + // 加载信用分数据(仅加载在线玩家) + private void loadPpoint() { + if (ppointConfig == null || ppointFile == null) { + getLogger().severe("信用分配置未初始化,加载失败!"); + return; + } + + // 遍历配置中的所有UUID,为在线玩家分配信用分 + for (String uuidStr : ppointConfig.getKeys(false)) { + try { + UUID playerUuid = UUID.fromString(uuidStr); + Player player = Bukkit.getPlayer(playerUuid); + if (player != null && player.isOnline()) { + // 读取信用分(默认100分) + int point = ppointConfig.getInt(uuidStr, 100); + ppoint.put(player, point); + getLogger().info("加载玩家 " + player.getName() + " 的信用分:" + point); + } + } catch (IllegalArgumentException e) { + getLogger().warning("无效的UUID格式:" + uuidStr + ",跳过该数据"); + } + } + } + + // 玩家上线时加载其信用分(供JoinEvent/LoginEvent调用) + public void loadPlayerPpoint(Player player) { + if (ppointConfig == null) { + getLogger().severe("信用分配置未初始化,无法加载玩家 " + player.getName() + " 的信用分!"); + return; + } + + UUID playerUuid = player.getUniqueId(); + String uuidStr = playerUuid.toString(); + + // 读取已有信用分,无数据则设为默认100分 + int point = ppointConfig.getInt(uuidStr, 100); + ppoint.put(player, point); + getLogger().info("玩家 " + player.getName() + " 上线,加载信用分:" + point); + } + + // 获取玩家标签管理器 public PlayerTags getPlayerTags() { return playerTags; } - // 新增获取账号管理器的方法 + // 获取账号管理器 public AccountManager getAccountManager() { return accountManager; } -} +} \ No newline at end of file diff --git a/src/main/java/org/xgqy/survival/command/HelpCommandExecutor.java b/src/main/java/org/xgqy/survival/command/HelpCommandExecutor.java index bb48d94..fc763be 100644 --- a/src/main/java/org/xgqy/survival/command/HelpCommandExecutor.java +++ b/src/main/java/org/xgqy/survival/command/HelpCommandExecutor.java @@ -28,6 +28,7 @@ public class HelpCommandExecutor implements CommandExecutor { sender.sendMessage(ChatColor.GREEN+"/party <参数> <参数> - 队伍"); sender.sendMessage(ChatColor.GREEN+"/friend <参数> <参数> - 好友"); sender.sendMessage(ChatColor.GREEN+"/msg <内容> - 私聊"); + sender.sendMessage(ChatColor.GREEN+"/selfkill - 自杀"); sender.sendMessage(ChatColor.YELLOW + "-----------------------------"); return true; } diff --git a/src/main/java/org/xgqy/survival/event/ChooseTagEvent.java b/src/main/java/org/xgqy/survival/event/ChooseTagEvent.java index 31f9f76..587c72a 100644 --- a/src/main/java/org/xgqy/survival/event/ChooseTagEvent.java +++ b/src/main/java/org/xgqy/survival/event/ChooseTagEvent.java @@ -45,12 +45,14 @@ public class ChooseTagEvent implements Listener { return; } - if (!event.getView().getTitle().contains("称号") && !event.getView().getTitle().contains("商城")&& !event.getView().getTitle().contains("背包")) { + if (!event.getView().getTitle().contains("称号") && !event.getView().getTitle().contains("商城")&& !event.getView().getTitle().contains("背包")&& !event.getView().getTitle().contains("签到")) { return; } event.setCancelled(true); - if (event.getView().getTitle().contains("称号")) { + if(event.getView().getTitle().contains("签到")){ + + } else if (event.getView().getTitle().contains("称号")) { ItemStack clickedItem = event.getCurrentItem(); if (clickedItem == null || clickedItem.getType() != Material.NAME_TAG) { return; diff --git a/src/main/java/org/xgqy/survival/event/JoinEvent.java b/src/main/java/org/xgqy/survival/event/JoinEvent.java index 9070acf..6598a44 100644 --- a/src/main/java/org/xgqy/survival/event/JoinEvent.java +++ b/src/main/java/org/xgqy/survival/event/JoinEvent.java @@ -21,6 +21,12 @@ public class JoinEvent implements Listener { @EventHandler private void join(PlayerJoinEvent e) { + if(plugin.ppoint.getOrDefault(e.getPlayer(),100) <= 0){ + e.getPlayer().kickPlayer(ChatColor.RED+"您好! 您由于 信用分小于 0 ,我们决定对你的账号 "+ e.getPlayer().getName() +" 采取\n"+ChatColor.RED+ChatColor.BOLD+"永久封禁\n"+ChatColor.RED+"措施,如果您想解封您的账号,请到QQ群 717903781 申诉\n\n"+ChatColor.RED+"如果您对本次处罚不满,请采取以下措施:\n"+ChatColor.YELLOW+"1.如果您对自己的行为"+ChatColor.BOLD+" 问心无愧 "+ChatColor.YELLOW+"请立即向QQ 2213866559 发送解封申请\n"+ChatColor.YELLOW+"2.如果您属实有违规行为,请"+ChatColor.BOLD+"手写"+ChatColor.YELLOW+"一篇 "+ChatColor.BOLD+"100字以上且AIGC合格"+ChatColor.YELLOW+" 的检讨发送到申诉QQ群,态度诚恳我们将会对你进行解封"); + } + if(plugin.ppoint.getOrDefault(e.getPlayer(),100) == 100){ + plugin.ppoint.put(e.getPlayer(),100); + } PlayerTags playertags = plugin.getPlayerTags(); List tags = playertags.getTags(e.getPlayer()); if (!tags.isEmpty() && playertags.getCurrentTag(e.getPlayer()) != -1) { diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 0dda55b..a9f8b7d 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -45,6 +45,9 @@ commands: reg: description: to register an account usage: / + pc: + description: chat in a party + usage: / login: description: to login usage: / @@ -59,9 +62,27 @@ commands: msg: description: private chat with friend usage: / + qd: + description: qian dao + usage: / friend: description: add friend usage: / + gift: + description: gift + usage: / + aboutme: + description: about you + usage: / + point: + description: change point + usage: / + land: + description: change point + usage: / + selfkill: + description: self kill + usage: / permissions: permission.settag: description: Allows setting player tags