update 8
This commit is contained in:
@@ -17,14 +17,10 @@ import java.util.UUID;
|
|||||||
public class PlayerTags {
|
public class PlayerTags {
|
||||||
private final Survival plugin;
|
private final Survival plugin;
|
||||||
private final File tagsFile;
|
private final File tagsFile;
|
||||||
// 原有:玩家-称号列表映射
|
|
||||||
private final Map<UUID, List<String>> playerTags = new HashMap<>();
|
private final Map<UUID, List<String>> playerTags = new HashMap<>();
|
||||||
// 新增:玩家-(称号-到期时间戳)映射(毫秒级,永久用Long.MAX_VALUE)
|
|
||||||
private final Map<UUID, Map<String, Long>> expireTimeMap = new HashMap<>();
|
private final Map<UUID, Map<String, Long>> expireTimeMap = new HashMap<>();
|
||||||
// 原有:玩家-选中称号索引映射
|
|
||||||
public Map<UUID, Integer> playerselectTag = new HashMap<>();
|
public Map<UUID, Integer> playerselectTag = new HashMap<>();
|
||||||
|
|
||||||
// 常量:7天的毫秒数(7*24*60*60*1000)
|
|
||||||
private static final long SEVEN_DAYS_MS = 604800000L;
|
private static final long SEVEN_DAYS_MS = 604800000L;
|
||||||
|
|
||||||
public PlayerTags(Survival plugin) {
|
public PlayerTags(Survival plugin) {
|
||||||
@@ -32,36 +28,28 @@ public class PlayerTags {
|
|||||||
this.tagsFile = new File(plugin.getDataFolder(), "playertags.data");
|
this.tagsFile = new File(plugin.getDataFolder(), "playertags.data");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 核心辅助:清理玩家的所有过期称号(所有方法调用前先执行)
|
|
||||||
*/
|
|
||||||
public void cleanExpiredTags(Player player) {
|
public void cleanExpiredTags(Player player) {
|
||||||
UUID uuid = player.getUniqueId();
|
UUID uuid = player.getUniqueId();
|
||||||
List<String> validTags = new ArrayList<>();
|
List<String> validTags = new ArrayList<>();
|
||||||
List<String> allTags = playerTags.getOrDefault(uuid, new ArrayList<>());
|
List<String> allTags = playerTags.getOrDefault(uuid, new ArrayList<>());
|
||||||
Map<String, Long> tagExpires = expireTimeMap.getOrDefault(uuid, new HashMap<>());
|
Map<String, Long> tagExpires = expireTimeMap.getOrDefault(uuid, new HashMap<>());
|
||||||
|
|
||||||
// 遍历所有称号,保留未过期的
|
|
||||||
for (String tag : allTags) {
|
for (String tag : allTags) {
|
||||||
long expireTime = tagExpires.getOrDefault(tag, Long.MAX_VALUE);
|
long expireTime = tagExpires.getOrDefault(tag, Long.MAX_VALUE);
|
||||||
// 未过期判断:永久(MAX)或当前时间 < 到期时间
|
|
||||||
if (expireTime == Long.MAX_VALUE || System.currentTimeMillis() < expireTime) {
|
if (expireTime == Long.MAX_VALUE || System.currentTimeMillis() < expireTime) {
|
||||||
validTags.add(tag);
|
validTags.add(tag);
|
||||||
} else {
|
} else {
|
||||||
// 过期:移除过期时间记录
|
|
||||||
tagExpires.remove(tag);
|
tagExpires.remove(tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新有效称号列表和过期时间映射
|
|
||||||
if (validTags.isEmpty()) {
|
if (validTags.isEmpty()) {
|
||||||
playerTags.remove(uuid);
|
playerTags.remove(uuid);
|
||||||
expireTimeMap.remove(uuid);
|
expireTimeMap.remove(uuid);
|
||||||
playerselectTag.put(uuid, -1); // 无有效称号,重置选中索引
|
playerselectTag.put(uuid, -1);
|
||||||
} else {
|
} else {
|
||||||
playerTags.put(uuid, validTags);
|
playerTags.put(uuid, validTags);
|
||||||
expireTimeMap.put(uuid, tagExpires);
|
expireTimeMap.put(uuid, tagExpires);
|
||||||
// 检查选中的称号是否已过期:若过期/索引无效,重置索引
|
|
||||||
int currentIndex = playerselectTag.getOrDefault(uuid, -1);
|
int currentIndex = playerselectTag.getOrDefault(uuid, -1);
|
||||||
if (currentIndex == -1 || currentIndex >= validTags.size()) {
|
if (currentIndex == -1 || currentIndex >= validTags.size()) {
|
||||||
playerselectTag.put(uuid, -1);
|
playerselectTag.put(uuid, -1);
|
||||||
@@ -69,11 +57,8 @@ public class PlayerTags {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前选中的称号索引(自动过滤过期)
|
|
||||||
*/
|
|
||||||
public int getCurrentTag(Player player) {
|
public int getCurrentTag(Player player) {
|
||||||
cleanExpiredTags(player); // 先清理过期
|
cleanExpiredTags(player);
|
||||||
UUID uuid = player.getUniqueId();
|
UUID uuid = player.getUniqueId();
|
||||||
Integer index = playerselectTag.get(uuid);
|
Integer index = playerselectTag.get(uuid);
|
||||||
if (index == null) {
|
if (index == null) {
|
||||||
@@ -82,34 +67,29 @@ public class PlayerTags {
|
|||||||
|
|
||||||
List<String> validTags = playerTags.getOrDefault(uuid, new ArrayList<>());
|
List<String> validTags = playerTags.getOrDefault(uuid, new ArrayList<>());
|
||||||
if (validTags.isEmpty() || index < 0 || index >= validTags.size()) {
|
if (validTags.isEmpty() || index < 0 || index >= validTags.size()) {
|
||||||
playerselectTag.put(uuid, -1); // 索引无效,重置
|
playerselectTag.put(uuid, -1);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置玩家选择的标签索引(自动过滤过期)
|
|
||||||
*/
|
|
||||||
public boolean setSelectedTag(Player player, int index) {
|
public boolean setSelectedTag(Player player, int index) {
|
||||||
cleanExpiredTags(player); // 先清理过期
|
cleanExpiredTags(player);
|
||||||
UUID uuid = player.getUniqueId();
|
UUID uuid = player.getUniqueId();
|
||||||
List<String> validTags = playerTags.getOrDefault(uuid, new ArrayList<>());
|
List<String> validTags = playerTags.getOrDefault(uuid, new ArrayList<>());
|
||||||
|
|
||||||
// 无有效称号或索引无效,返回失败
|
|
||||||
if (validTags.isEmpty() || index < 0 || index >= validTags.size()) {
|
if (validTags.isEmpty() || index < 0 || index >= validTags.size()) {
|
||||||
playerselectTag.put(uuid, -1);
|
playerselectTag.put(uuid, -1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置选中索引,返回成功
|
|
||||||
playerselectTag.put(uuid, index);
|
playerselectTag.put(uuid, index);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载称号数据:核心逻辑——识别旧数据并转为7天过期
|
* 修复核心:正确读取新版本数据中的expireTimeMap,避免误判为旧数据
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void loadTags() {
|
public void loadTags() {
|
||||||
@@ -118,17 +98,27 @@ public class PlayerTags {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(tagsFile))) {
|
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(tagsFile))) {
|
||||||
// 读取第一个对象:判断是旧版本(List<String>)还是新版本(含过期时间)
|
// 读取三个核心对象(新版本数据结构)
|
||||||
Object firstObj = ois.readObject();
|
Object firstObj = ois.readObject();
|
||||||
Object secondObj = ois.readObject();
|
Object secondObj = ois.readObject();
|
||||||
Object thirdObj = null; // 新版本的第三个对象:expireTimeMap
|
Object thirdObj = ois.readObject(); // 关键修复:读取第三个对象(expireTimeMap)
|
||||||
|
|
||||||
// 1. 识别旧版本数据(仅2个对象:playerTags + playerselectTag)
|
// 1. 优先判断新版本数据(3个对象完整)
|
||||||
if (firstObj instanceof Map<?, ?> && secondObj instanceof Map<?, ?> && ois.available() == 0) {
|
if (firstObj instanceof Map<?, ?> && secondObj instanceof Map<?, ?> && thirdObj instanceof Map<?, ?>) {
|
||||||
|
// 强制转换并加载数据
|
||||||
|
playerTags.putAll((Map<UUID, List<String>>) firstObj);
|
||||||
|
playerselectTag.putAll((Map<UUID, Integer>) secondObj);
|
||||||
|
expireTimeMap.putAll((Map<UUID, Map<String, Long>>) thirdObj);
|
||||||
|
plugin.getLogger().info("新版本称号数据加载完成!共加载 " + playerTags.size() + " 个玩家的称号");
|
||||||
|
return; // 加载成功直接返回,避免进入旧数据处理
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 处理旧版本数据(仅2个对象:无expireTimeMap)
|
||||||
|
if (firstObj instanceof Map<?, ?> && secondObj instanceof Map<?, ?>) {
|
||||||
Map<UUID, List<String>> oldPlayerTags = (Map<UUID, List<String>>) firstObj;
|
Map<UUID, List<String>> oldPlayerTags = (Map<UUID, List<String>>) firstObj;
|
||||||
Map<UUID, Integer> oldSelectTag = (Map<UUID, Integer>) secondObj;
|
Map<UUID, Integer> oldSelectTag = (Map<UUID, Integer>) secondObj;
|
||||||
|
|
||||||
// 旧数据转换:为每个称号设置“当前时间+7天”的到期时间
|
// 旧数据转换为7天过期
|
||||||
for (Map.Entry<UUID, List<String>> entry : oldPlayerTags.entrySet()) {
|
for (Map.Entry<UUID, List<String>> entry : oldPlayerTags.entrySet()) {
|
||||||
UUID uuid = entry.getKey();
|
UUID uuid = entry.getKey();
|
||||||
List<String> oldTags = entry.getValue();
|
List<String> oldTags = entry.getValue();
|
||||||
@@ -136,34 +126,27 @@ public class PlayerTags {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 为当前玩家创建“称号-到期时间”映射
|
|
||||||
Map<String, Long> tagExpires = new HashMap<>();
|
Map<String, Long> tagExpires = new HashMap<>();
|
||||||
long sevenDaysLater = System.currentTimeMillis() + SEVEN_DAYS_MS; // 7天后到期
|
long sevenDaysLater = System.currentTimeMillis() + SEVEN_DAYS_MS;
|
||||||
for (String tag : oldTags) {
|
for (String tag : oldTags) {
|
||||||
tagExpires.put(tag, sevenDaysLater); // 每个旧称号都设为7天过期
|
tagExpires.put(tag, sevenDaysLater);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 存入新结构
|
playerTags.put(uuid, new ArrayList<>(oldTags));
|
||||||
playerTags.put(uuid, new ArrayList<>(oldTags)); // 复制旧称号列表
|
expireTimeMap.put(uuid, tagExpires);
|
||||||
expireTimeMap.put(uuid, tagExpires); // 存入7天过期时间
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 恢复选中索引
|
|
||||||
playerselectTag.putAll(oldSelectTag);
|
playerselectTag.putAll(oldSelectTag);
|
||||||
plugin.getLogger().info("旧版本称号数据加载完成,已自动转为7日后到期!");
|
plugin.getLogger().info("旧版本称号数据加载完成,已自动转为7日后到期!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
// 3. 数据格式错误
|
||||||
// 2. 识别新版本数据(3个对象:playerTags + playerselectTag + expireTimeMap)
|
plugin.getLogger().warning("称号数据格式错误,无法识别!");
|
||||||
else if (firstObj instanceof Map<?, ?> && secondObj instanceof Map<?, ?> && thirdObj instanceof Map<?, ?>) {
|
|
||||||
playerTags.putAll((Map<UUID, List<String>>) firstObj);
|
|
||||||
playerselectTag.putAll((Map<UUID, Integer>) secondObj);
|
|
||||||
expireTimeMap.putAll((Map<UUID, Map<String, Long>>) thirdObj);
|
|
||||||
plugin.getLogger().info("新版本称号数据加载完成!");
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException | ClassNotFoundException e) {
|
} catch (IOException | ClassNotFoundException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
// 回退逻辑:仅加载称号列表,所有称号设为7天过期
|
// 回退逻辑:仅加载称号列表,设为7天过期
|
||||||
try (ObjectInputStream fallback = new ObjectInputStream(new FileInputStream(tagsFile))) {
|
try (ObjectInputStream fallback = new ObjectInputStream(new FileInputStream(tagsFile))) {
|
||||||
Object obj = fallback.readObject();
|
Object obj = fallback.readObject();
|
||||||
if (obj instanceof Map<?, ?> oldPlayerTags) {
|
if (obj instanceof Map<?, ?> oldPlayerTags) {
|
||||||
@@ -176,7 +159,7 @@ public class PlayerTags {
|
|||||||
for (Object tagObj : (List<?>) entry.getValue()) {
|
for (Object tagObj : (List<?>) entry.getValue()) {
|
||||||
if (tagObj instanceof String tag) {
|
if (tagObj instanceof String tag) {
|
||||||
tags.add(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() {
|
public void saveTags() {
|
||||||
if (!tagsFile.getParentFile().exists()) {
|
if (!tagsFile.getParentFile().exists()) {
|
||||||
tagsFile.getParentFile().mkdirs();
|
tagsFile.getParentFile().mkdirs();
|
||||||
}
|
}
|
||||||
|
|
||||||
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(tagsFile))) {
|
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(tagsFile))) {
|
||||||
// 按顺序写入3个核心结构(新版本)
|
// 按顺序写入三个核心结构(与加载时对应)
|
||||||
oos.writeObject(playerTags);
|
oos.writeObject(playerTags);
|
||||||
oos.writeObject(playerselectTag);
|
oos.writeObject(playerselectTag);
|
||||||
oos.writeObject(expireTimeMap);
|
oos.writeObject(expireTimeMap);
|
||||||
@@ -211,71 +191,50 @@ public class PlayerTags {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取玩家的有效称号列表(自动过滤过期)
|
|
||||||
*/
|
|
||||||
public List<String> getTags(Player player) {
|
public List<String> getTags(Player player) {
|
||||||
cleanExpiredTags(player);
|
cleanExpiredTags(player);
|
||||||
return playerTags.getOrDefault(player.getUniqueId(), new ArrayList<>());
|
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) {
|
public void addTag(Player player, String tag, boolean isPermanent) {
|
||||||
cleanExpiredTags(player); // 先清理过期
|
cleanExpiredTags(player);
|
||||||
UUID uuid = player.getUniqueId();
|
UUID uuid = player.getUniqueId();
|
||||||
List<String> tags = playerTags.computeIfAbsent(uuid, k -> new ArrayList<>());
|
List<String> tags = playerTags.computeIfAbsent(uuid, k -> new ArrayList<>());
|
||||||
Map<String, Long> tagExpires = expireTimeMap.computeIfAbsent(uuid, k -> new HashMap<>());
|
Map<String, Long> tagExpires = expireTimeMap.computeIfAbsent(uuid, k -> new HashMap<>());
|
||||||
|
|
||||||
// 避免重复添加相同称号
|
|
||||||
if (!tags.contains(tag)) {
|
if (!tags.contains(tag)) {
|
||||||
tags.add(tag);
|
tags.add(tag);
|
||||||
// 设置过期时间:永久=Long.MAX_VALUE,临时=当前时间+7天
|
|
||||||
long expireTime = isPermanent ? Long.MAX_VALUE : System.currentTimeMillis() + SEVEN_DAYS_MS;
|
long expireTime = isPermanent ? Long.MAX_VALUE : System.currentTimeMillis() + SEVEN_DAYS_MS;
|
||||||
tagExpires.put(tag, expireTime);
|
tagExpires.put(tag, expireTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 重载原有addTag方法:默认添加永久称号(保持向下兼容)
|
|
||||||
*/
|
|
||||||
public void addTag(Player player, String tag, int days) {
|
public void addTag(Player player, String tag, int days) {
|
||||||
cleanExpiredTags(player); // 先清理过期
|
cleanExpiredTags(player);
|
||||||
UUID uuid = player.getUniqueId();
|
UUID uuid = player.getUniqueId();
|
||||||
List<String> tags = playerTags.computeIfAbsent(uuid, k -> new ArrayList<>());
|
List<String> tags = playerTags.computeIfAbsent(uuid, k -> new ArrayList<>());
|
||||||
Map<String, Long> tagExpires = expireTimeMap.computeIfAbsent(uuid, k -> new HashMap<>());
|
Map<String, Long> tagExpires = expireTimeMap.computeIfAbsent(uuid, k -> new HashMap<>());
|
||||||
|
|
||||||
// 避免重复添加相同称号
|
|
||||||
if (!tags.contains(tag)) {
|
if (!tags.contains(tag)) {
|
||||||
tags.add(tag);
|
tags.add(tag);
|
||||||
long expireTime;
|
long expireTime;
|
||||||
if (days == 999) {
|
if (days == 999) {
|
||||||
expireTime = Long.MAX_VALUE; // 999天视为永久
|
expireTime = Long.MAX_VALUE;
|
||||||
} else if (days <= 0) {
|
} else if (days <= 0) {
|
||||||
expireTime = System.currentTimeMillis() - 1; // 天数≤0:立即过期(触发清理)
|
expireTime = System.currentTimeMillis() - 1;
|
||||||
} else {
|
} else {
|
||||||
// 计算有效期:当前时间 + 天数×24×60×60×1000(转换为毫秒)
|
|
||||||
expireTime = System.currentTimeMillis() + (long) days * 24 * 60 * 60 * 1000;
|
expireTime = System.currentTimeMillis() + (long) days * 24 * 60 * 60 * 1000;
|
||||||
}
|
}
|
||||||
tagExpires.put(tag, expireTime);
|
tagExpires.put(tag, expireTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 移除称号:同时删除过期时间记录
|
|
||||||
*/
|
|
||||||
public void removeTag(Player player, String tag) {
|
public void removeTag(Player player, String tag) {
|
||||||
cleanExpiredTags(player);
|
cleanExpiredTags(player);
|
||||||
UUID uuid = player.getUniqueId();
|
UUID uuid = player.getUniqueId();
|
||||||
List<String> tags = playerTags.get(uuid);
|
List<String> tags = playerTags.get(uuid);
|
||||||
Map<String, Long> tagExpires = expireTimeMap.get(uuid);
|
Map<String, Long> tagExpires = expireTimeMap.get(uuid);
|
||||||
|
|
||||||
// 移除称号列表和过期时间映射中的对应条目
|
|
||||||
if (tags != null) {
|
if (tags != null) {
|
||||||
tags.remove(tag);
|
tags.remove(tag);
|
||||||
if (tags.isEmpty()) {
|
if (tags.isEmpty()) {
|
||||||
@@ -293,7 +252,6 @@ public class PlayerTags {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 若移除的是当前选中称号,重置索引
|
|
||||||
int currentIndex = playerselectTag.getOrDefault(uuid, -1);
|
int currentIndex = playerselectTag.getOrDefault(uuid, -1);
|
||||||
List<String> validTags = playerTags.getOrDefault(uuid, new ArrayList<>());
|
List<String> validTags = playerTags.getOrDefault(uuid, new ArrayList<>());
|
||||||
if (currentIndex != -1 && (currentIndex >= validTags.size() || !validTags.contains(tag))) {
|
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) {
|
public long getTagExpireTime(Player player, String tag) {
|
||||||
cleanExpiredTags(player);
|
cleanExpiredTags(player);
|
||||||
UUID uuid = player.getUniqueId();
|
UUID uuid = player.getUniqueId();
|
||||||
Map<String, Long> tagExpires = expireTimeMap.getOrDefault(uuid, new HashMap<>());
|
Map<String, Long> tagExpires = expireTimeMap.getOrDefault(uuid, new HashMap<>());
|
||||||
List<String> validTags = playerTags.getOrDefault(uuid, new ArrayList<>());
|
List<String> validTags = playerTags.getOrDefault(uuid, new ArrayList<>());
|
||||||
|
|
||||||
// 称号不存在或已过期,返回-2
|
|
||||||
if (!validTags.contains(tag)) {
|
if (!validTags.contains(tag)) {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
long expireTime = tagExpires.getOrDefault(tag, Long.MAX_VALUE);
|
long expireTime = tagExpires.getOrDefault(tag, Long.MAX_VALUE);
|
||||||
// 永久称号返回-1,否则返回时间戳
|
|
||||||
return expireTime == Long.MAX_VALUE ? -1 : expireTime;
|
return expireTime == Long.MAX_VALUE ? -1 : expireTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增:获取称号的剩余时间(返回字符串,如“2天3小时”)
|
|
||||||
*/
|
|
||||||
public String getTagRemainingTime(Player player, String tag) {
|
public String getTagRemainingTime(Player player, String tag) {
|
||||||
long expireTime = getTagExpireTime(player, tag);
|
long expireTime = getTagExpireTime(player, tag);
|
||||||
if (expireTime == -1) {
|
if (expireTime == -1) {
|
||||||
@@ -334,18 +282,15 @@ public class PlayerTags {
|
|||||||
return "已过期/不存在";
|
return "已过期/不存在";
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算剩余毫秒数(可能为负,需处理)
|
|
||||||
long remainingMs = expireTime - System.currentTimeMillis();
|
long remainingMs = expireTime - System.currentTimeMillis();
|
||||||
if (remainingMs <= 0) {
|
if (remainingMs <= 0) {
|
||||||
return "已过期";
|
return "已过期";
|
||||||
}
|
}
|
||||||
|
|
||||||
// 转换为天、时、分
|
|
||||||
long days = remainingMs / (24 * 60 * 60 * 1000);
|
long days = remainingMs / (24 * 60 * 60 * 1000);
|
||||||
long hours = (remainingMs % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000);
|
long hours = (remainingMs % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000);
|
||||||
long minutes = (remainingMs % (60 * 60 * 1000)) / (60 * 1000);
|
long minutes = (remainingMs % (60 * 60 * 1000)) / (60 * 1000);
|
||||||
|
|
||||||
// 拼接剩余时间字符串
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
if (days > 0) sb.append(days).append("天");
|
if (days > 0) sb.append(days).append("天");
|
||||||
if (hours > 0) sb.append(hours).append("小时");
|
if (hours > 0) sb.append(hours).append("小时");
|
||||||
|
|||||||
@@ -3,15 +3,23 @@ package org.xgqy.survival;
|
|||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
import org.xgqy.survival.command.DqshopCommandExecutor;
|
import org.xgqy.survival.command.DqshopCommandExecutor;
|
||||||
|
import org.xgqy.survival.command.FriendCommandExecutor;
|
||||||
import org.xgqy.survival.command.HandleCommandExecutor;
|
import org.xgqy.survival.command.HandleCommandExecutor;
|
||||||
import org.xgqy.survival.command.HelpCommandExecutor;
|
import org.xgqy.survival.command.HelpCommandExecutor;
|
||||||
import org.xgqy.survival.command.HubCommandExecutor;
|
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.LoginCommandExecutor;
|
||||||
import org.xgqy.survival.command.PartyCommandExecutor;
|
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.PvpCommandExecutor;
|
||||||
import org.xgqy.survival.command.RegCommandExecutor;
|
import org.xgqy.survival.command.RegCommandExecutor;
|
||||||
import org.xgqy.survival.command.ReportCommandExecutor;
|
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.TeleportCommandExecutor;
|
||||||
import org.xgqy.survival.command.TpAccCommandExecutor;
|
import org.xgqy.survival.command.TpAccCommandExecutor;
|
||||||
import org.xgqy.survival.command.TpFinCommandExecutor;
|
import org.xgqy.survival.command.TpFinCommandExecutor;
|
||||||
|
import org.xgqy.survival.command.msgCommandExecutor;
|
||||||
import org.xgqy.survival.event.ChatEvent;
|
import org.xgqy.survival.event.ChatEvent;
|
||||||
import org.xgqy.survival.event.ChooseTagEvent;
|
import org.xgqy.survival.event.ChooseTagEvent;
|
||||||
import org.xgqy.survival.event.JoinEvent;
|
import org.xgqy.survival.event.JoinEvent;
|
||||||
|
import org.xgqy.survival.event.LandEvent;
|
||||||
import org.xgqy.survival.event.LoginEvent;
|
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.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public final class Survival extends JavaPlugin {
|
public final class Survival extends JavaPlugin {
|
||||||
private PlayerTags playerTags;
|
private PlayerTags playerTags;
|
||||||
private AccountManager accountManager; // 新增账号管理器
|
private AccountManager accountManager;
|
||||||
public Map<Player, Boolean> krt = new HashMap<>();
|
public Map<Player, Boolean> krt = new HashMap<>();
|
||||||
public Map<Player, Player> banlist = new HashMap<>();
|
public Map<Player, Player> banlist = new HashMap<>();
|
||||||
public Map<Player, String> banreason = new HashMap<>();
|
public Map<Player, String> banreason = new HashMap<>();
|
||||||
public Map<Player, HashSet<Player>> reportlist = new HashMap<>();
|
public Map<Player, HashSet<Player>> reportlist = new HashMap<>();
|
||||||
|
// Teleport
|
||||||
public Map<Player, Player> teleport = new HashMap<>();
|
public Map<Player, Player> teleport = new HashMap<>();
|
||||||
public Map<Player, Player> Ateleport = new HashMap<>();
|
public Map<Player, Player> Ateleport = new HashMap<>();
|
||||||
public Map<Player, Location> teleportp = new HashMap<>();
|
public Map<Player, Location> teleportp = new HashMap<>();
|
||||||
@@ -59,18 +76,88 @@ public final class Survival extends JavaPlugin {
|
|||||||
friend
|
friend
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
*/
|
*/
|
||||||
public Map<Player,List<Player>> friends = new HashMap<>();
|
public Map<Player, List<Player>> friends = new ConcurrentHashMap<>();
|
||||||
|
public Map<Player, List<Player>> waiting = new ConcurrentHashMap<>();
|
||||||
/*
|
/*
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
信用分
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
*/
|
*/
|
||||||
|
public Map<Player, Integer> ppoint = new HashMap<>();
|
||||||
private List<String> msg = new ArrayList<>();
|
private List<String> msg = new ArrayList<>();
|
||||||
|
public Map<Player, String> breason = new HashMap<>();
|
||||||
|
/*
|
||||||
|
----------------------------------------
|
||||||
|
领地
|
||||||
|
----------------------------------------
|
||||||
|
*/
|
||||||
|
public static class Land{
|
||||||
|
public Location start,end;
|
||||||
|
public List<Boolean> defaultperm;
|
||||||
|
public String owner;
|
||||||
|
public Map<String,List<Boolean>> perm;
|
||||||
|
public boolean boomb;
|
||||||
|
public Land(Location start,Location end,List<Boolean> defaultperm,String owner,Map<String,List<Boolean>> 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<Boolean> getDefaultperm(){
|
||||||
|
return defaultperm;
|
||||||
|
}
|
||||||
|
public String getOwner(){
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
|
public List<Boolean> 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<Boolean> defaultperm){
|
||||||
|
this.defaultperm=defaultperm;
|
||||||
|
}
|
||||||
|
public void setOwner(String owner){
|
||||||
|
this.owner=owner;
|
||||||
|
}
|
||||||
|
public void setPerm(Player player,List<Boolean> perm){
|
||||||
|
this.perm.put(player.getName(),perm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public List<Land> land =new ArrayList<>();
|
||||||
|
|
||||||
|
public Map<Player,String> inland=new HashMap<>();
|
||||||
|
// 信用分数据文件相关
|
||||||
|
private File ppointFile;
|
||||||
|
private FileConfiguration ppointConfig;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
// 初始化账号管理器
|
// 初始化账号管理器
|
||||||
accountManager = new AccountManager(this);
|
accountManager = new AccountManager(this);
|
||||||
|
|
||||||
|
// 初始化信用分数据文件
|
||||||
|
initPpointFile();
|
||||||
|
// 加载已在线玩家的信用分数据
|
||||||
|
loadPpoint();
|
||||||
|
|
||||||
msg.add(ChatColor.GREEN + "可以用 /help 命令来查看命令列表");
|
msg.add(ChatColor.GREEN + "可以用 /help 命令来查看命令列表");
|
||||||
msg.add(ChatColor.GREEN + "如果遇到作弊玩家可以用 /report <玩家名> <原因> 来举报!管理员会很快处理的");
|
msg.add(ChatColor.GREEN + "如果遇到作弊玩家可以用 /report <玩家名> <原因> 来举报!管理员会很快处理的");
|
||||||
msg.add(ChatColor.GREEN + "想传送到玩家怎么办? 用 /teleport <玩家名> 命令!");
|
msg.add(ChatColor.GREEN + "想传送到玩家怎么办? 用 /teleport <玩家名> 命令!");
|
||||||
@@ -81,7 +168,12 @@ public final class Survival extends JavaPlugin {
|
|||||||
msg.add(ChatColor.GREEN + "今天签到了吗?快输入 /qd 签到吧!");
|
msg.add(ChatColor.GREEN + "今天签到了吗?快输入 /qd 签到吧!");
|
||||||
msg.add(ChatColor.GREEN + "其实可以输入 /pvp 来开启/关闭自己的pvp模式");
|
msg.add(ChatColor.GREEN + "其实可以输入 /pvp 来开启/关闭自己的pvp模式");
|
||||||
msg.add(ChatColor.RED + "你不可以把别人的家毁掉!这样你将会受到处罚");
|
msg.add(ChatColor.RED + "你不可以把别人的家毁掉!这样你将会受到处罚");
|
||||||
msg.add(ChatColor.GOLD+"能给我捐点钱吗");
|
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() {
|
new BukkitRunnable() {
|
||||||
@Override
|
@Override
|
||||||
@@ -95,49 +187,227 @@ public final class Survival extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
}.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 = new PlayerTags(this);
|
||||||
playerTags.loadTags();
|
playerTags.loadTags();
|
||||||
|
|
||||||
// 注册事件监听器,包括新的登录事件
|
// 注册事件监听器
|
||||||
Bukkit.getPluginManager().registerEvents(new JoinEvent(this), this);
|
Bukkit.getPluginManager().registerEvents(new JoinEvent(this), this);
|
||||||
Bukkit.getPluginManager().registerEvents(new ChatEvent(this), this);
|
Bukkit.getPluginManager().registerEvents(new ChatEvent(this), this);
|
||||||
Bukkit.getPluginManager().registerEvents(new ChooseTagEvent(this), this);
|
Bukkit.getPluginManager().registerEvents(new ChooseTagEvent(this), this);
|
||||||
Bukkit.getPluginManager().registerEvents(new LoginEvent(this), this); // 新增登录事件监听器
|
Bukkit.getPluginManager().registerEvents(new LoginEvent(this), this);
|
||||||
Bukkit.getPluginManager().registerEvents(new QuitEvent(this),this);
|
Bukkit.getPluginManager().registerEvents(new LandEvent(this),this);
|
||||||
//Bukkit.getPluginManager().registerEvents(new AntiExploit(),this);
|
|
||||||
//Bukkit.getPluginManager().registerEvents(new AntiXray(this),this);
|
|
||||||
|
|
||||||
// 注册命令执行器,包括新的注册和登录命令
|
// 注册命令执行器
|
||||||
getCommand("report").setExecutor(new ReportCommandExecutor(this));
|
getCommand("report").setExecutor(new ReportCommandExecutor(this));
|
||||||
getCommand("handle").setExecutor(new HandleCommandExecutor(this));
|
getCommand("handle").setExecutor(new HandleCommandExecutor(this));
|
||||||
getCommand("pvp").setExecutor(new PvpCommandExecutor(this));
|
getCommand("pvp").setExecutor(new PvpCommandExecutor(this));
|
||||||
getCommand("settag").setExecutor(new SetTagCommandExecutor(this));
|
getCommand("settag").setExecutor(new SetTagCommandExecutor(this));
|
||||||
getCommand("help").setExecutor(new HelpCommandExecutor(this));
|
getCommand("help").setExecutor(new HelpCommandExecutor(this));
|
||||||
//getCommand("fly").setExecutor(new FlyCommandExecutor(this));
|
|
||||||
getCommand("tag").setExecutor(new TagCommandExecutor(this));
|
getCommand("tag").setExecutor(new TagCommandExecutor(this));
|
||||||
getCommand("hub").setExecutor(new HubCommandExecutor(this));
|
getCommand("hub").setExecutor(new HubCommandExecutor(this));
|
||||||
getCommand("teleport").setExecutor(new TeleportCommandExecutor(this));
|
getCommand("teleport").setExecutor(new TeleportCommandExecutor(this));
|
||||||
getCommand("tpacc").setExecutor(new TpAccCommandExecutor(this));
|
getCommand("tpacc").setExecutor(new TpAccCommandExecutor(this));
|
||||||
getCommand("tpfin").setExecutor(new TpFinCommandExecutor(this));
|
getCommand("tpfin").setExecutor(new TpFinCommandExecutor(this));
|
||||||
getCommand("shop").setExecutor(new DqshopCommandExecutor(this));
|
getCommand("shop").setExecutor(new DqshopCommandExecutor(this));
|
||||||
getCommand("reg").setExecutor(new RegCommandExecutor(this)); // 新增注册命令
|
getCommand("reg").setExecutor(new RegCommandExecutor(this));
|
||||||
getCommand("login").setExecutor(new LoginCommandExecutor(this)); // 新增登录命令
|
getCommand("login").setExecutor(new LoginCommandExecutor(this));
|
||||||
getCommand("party").setExecutor(new PartyCommandExecutor(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
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
|
// 保存玩家标签数据
|
||||||
playerTags.saveTags();
|
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<Player, Integer> 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() {
|
public PlayerTags getPlayerTags() {
|
||||||
return playerTags;
|
return playerTags;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增获取账号管理器的方法
|
// 获取账号管理器
|
||||||
public AccountManager getAccountManager() {
|
public AccountManager getAccountManager() {
|
||||||
return accountManager;
|
return accountManager;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public class HelpCommandExecutor implements CommandExecutor {
|
|||||||
sender.sendMessage(ChatColor.GREEN+"/party <参数> <参数> - 队伍");
|
sender.sendMessage(ChatColor.GREEN+"/party <参数> <参数> - 队伍");
|
||||||
sender.sendMessage(ChatColor.GREEN+"/friend <参数> <参数> - 好友");
|
sender.sendMessage(ChatColor.GREEN+"/friend <参数> <参数> - 好友");
|
||||||
sender.sendMessage(ChatColor.GREEN+"/msg <内容> - 私聊");
|
sender.sendMessage(ChatColor.GREEN+"/msg <内容> - 私聊");
|
||||||
|
sender.sendMessage(ChatColor.GREEN+"/selfkill - 自杀");
|
||||||
sender.sendMessage(ChatColor.YELLOW + "-----------------------------");
|
sender.sendMessage(ChatColor.YELLOW + "-----------------------------");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,12 +45,14 @@ public class ChooseTagEvent implements Listener {
|
|||||||
return;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
if (event.getView().getTitle().contains("称号")) {
|
if(event.getView().getTitle().contains("签到")){
|
||||||
|
|
||||||
|
} else if (event.getView().getTitle().contains("称号")) {
|
||||||
ItemStack clickedItem = event.getCurrentItem();
|
ItemStack clickedItem = event.getCurrentItem();
|
||||||
if (clickedItem == null || clickedItem.getType() != Material.NAME_TAG) {
|
if (clickedItem == null || clickedItem.getType() != Material.NAME_TAG) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -21,6 +21,12 @@ public class JoinEvent implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
private void join(PlayerJoinEvent e) {
|
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();
|
PlayerTags playertags = plugin.getPlayerTags();
|
||||||
List<String> tags = playertags.getTags(e.getPlayer());
|
List<String> tags = playertags.getTags(e.getPlayer());
|
||||||
if (!tags.isEmpty() && playertags.getCurrentTag(e.getPlayer()) != -1) {
|
if (!tags.isEmpty() && playertags.getCurrentTag(e.getPlayer()) != -1) {
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ commands:
|
|||||||
reg:
|
reg:
|
||||||
description: to register an account
|
description: to register an account
|
||||||
usage: /<command> <password> <password>
|
usage: /<command> <password> <password>
|
||||||
|
pc:
|
||||||
|
description: chat in a party
|
||||||
|
usage: /<command> <message>
|
||||||
login:
|
login:
|
||||||
description: to login
|
description: to login
|
||||||
usage: /<command> <password>
|
usage: /<command> <password>
|
||||||
@@ -59,9 +62,27 @@ commands:
|
|||||||
msg:
|
msg:
|
||||||
description: private chat with friend
|
description: private chat with friend
|
||||||
usage: /<command> <player> <message>
|
usage: /<command> <player> <message>
|
||||||
|
qd:
|
||||||
|
description: qian dao
|
||||||
|
usage: /<command>
|
||||||
friend:
|
friend:
|
||||||
description: add friend
|
description: add friend
|
||||||
usage: /<command> <add|allow|deny|remove> <player>
|
usage: /<command> <add|allow|deny|remove> <player>
|
||||||
|
gift:
|
||||||
|
description: gift
|
||||||
|
usage: /<command>
|
||||||
|
aboutme:
|
||||||
|
description: about you
|
||||||
|
usage: /<command>
|
||||||
|
point:
|
||||||
|
description: change point
|
||||||
|
usage: /<command> <player> <set|add|remove> <number>
|
||||||
|
land:
|
||||||
|
description: change point
|
||||||
|
usage: /<command> <player> <set|add|remove> <number>
|
||||||
|
selfkill:
|
||||||
|
description: self kill
|
||||||
|
usage: /<command>
|
||||||
permissions:
|
permissions:
|
||||||
permission.settag:
|
permission.settag:
|
||||||
description: Allows setting player tags
|
description: Allows setting player tags
|
||||||
|
|||||||
Reference in New Issue
Block a user