|
1 | 1 | package ict.minesunshineone.peek.manager; |
2 | 2 |
|
3 | | -import java.io.File; |
4 | | -import java.io.IOException; |
5 | 3 | import java.util.HashMap; |
6 | | -import java.util.HashSet; |
7 | | -import java.util.List; |
8 | 4 | import java.util.Map; |
9 | | -import java.util.Set; |
10 | 5 | import java.util.UUID; |
11 | | -import java.util.stream.Collectors; |
12 | 6 |
|
| 7 | +import org.bukkit.NamespacedKey; |
13 | 8 | import org.bukkit.Sound; |
14 | | -import org.bukkit.configuration.file.YamlConfiguration; |
15 | 9 | import org.bukkit.entity.Player; |
| 10 | +import org.bukkit.persistence.PersistentDataType; |
16 | 11 |
|
17 | 12 | import ict.minesunshineone.peek.PeekPlugin; |
18 | 13 | import io.papermc.paper.threadedregions.scheduler.ScheduledTask; |
19 | 14 |
|
20 | 15 | public class PrivacyManager { |
21 | 16 |
|
22 | 17 | private final PeekPlugin plugin; |
23 | | - private final Set<UUID> privateModeUsers = new HashSet<>(); |
24 | 18 | private final Map<UUID, Map<UUID, ScheduledTask>> pendingRequests = new HashMap<>(); |
25 | 19 | private final Map<String, Long> requestCooldowns = new HashMap<>(); |
26 | 20 |
|
27 | 21 | private final int requestTimeout; |
28 | 22 | private final boolean cooldownEnabled; |
29 | 23 | private final int cooldownDuration; |
30 | | - |
31 | | - private final File privacyFile; |
32 | | - private final YamlConfiguration privacyConfig; |
| 24 | + |
| 25 | + // PersistentData Key for privacy mode |
| 26 | + private final NamespacedKey PRIVACY_MODE_KEY; |
33 | 27 |
|
34 | 28 | public PrivacyManager(PeekPlugin plugin) { |
35 | 29 | this.plugin = plugin; |
36 | 30 | this.requestTimeout = plugin.getConfig().getInt("privacy.request-timeout", 30); |
37 | 31 | this.cooldownEnabled = plugin.getConfig().getBoolean("privacy.cooldown.enabled", true); |
38 | 32 | this.cooldownDuration = plugin.getConfig().getInt("privacy.cooldown.duration", 60); |
39 | | - this.privacyFile = new File(plugin.getDataFolder(), "privacy.yml"); |
40 | | - this.privacyConfig = YamlConfiguration.loadConfiguration(privacyFile); |
41 | | - loadPrivacyStates(); |
| 33 | + this.PRIVACY_MODE_KEY = new NamespacedKey(plugin, "privacy_mode"); |
| 34 | + |
| 35 | + plugin.getLogger().info("隐私管理器已初始化,使用 PersistentData 存储隐私模式设置"); |
42 | 36 | } |
43 | 37 |
|
44 | | - private void loadPrivacyStates() { |
45 | | - List<String> uuids = privacyConfig.getStringList("private_mode_players"); |
46 | | - privateModeUsers.clear(); |
47 | | - for (String uuid : uuids) { |
48 | | - try { |
49 | | - privateModeUsers.add(UUID.fromString(uuid)); |
50 | | - } catch (IllegalArgumentException e) { |
51 | | - plugin.getLogger().warning(String.format("无效的UUID格式: %s", uuid)); |
52 | | - } |
| 38 | + /** |
| 39 | + * 检查玩家是否启用了私人模式 |
| 40 | + * 使用 PersistentData 存储,支持跨服同步 |
| 41 | + */ |
| 42 | + public boolean isPrivateMode(Player player) { |
| 43 | + if (player == null || !player.isOnline()) { |
| 44 | + return false; |
53 | 45 | } |
| 46 | + |
| 47 | + return player.getPersistentDataContainer() |
| 48 | + .getOrDefault(PRIVACY_MODE_KEY, PersistentDataType.BYTE, (byte) 0) == 1; |
54 | 49 | } |
55 | 50 |
|
56 | | - public void savePrivacyStates() { |
57 | | - List<String> uuids = privateModeUsers.stream() |
58 | | - .map(UUID::toString) |
59 | | - .collect(Collectors.toList()); |
60 | | - privacyConfig.set("private_mode_players", uuids); |
61 | | - try { |
62 | | - privacyConfig.save(privacyFile); |
63 | | - } catch (IOException e) { |
64 | | - plugin.getLogger().warning(String.format("无法保存私人模式状态: %s", e.getMessage())); |
| 51 | + /** |
| 52 | + * 切换玩家的私人模式状态 |
| 53 | + * 使用 PersistentData 存储,支持跨服同步 |
| 54 | + */ |
| 55 | + public void togglePrivateMode(Player player) { |
| 56 | + if (player == null || !player.isOnline()) { |
| 57 | + return; |
65 | 58 | } |
| 59 | + |
| 60 | + boolean currentMode = isPrivateMode(player); |
| 61 | + |
| 62 | + if (currentMode) { |
| 63 | + // 禁用私人模式 |
| 64 | + player.getPersistentDataContainer().set(PRIVACY_MODE_KEY, PersistentDataType.BYTE, (byte) 0); |
| 65 | + plugin.getMessages().send(player, "privacy-mode-disabled"); |
| 66 | + |
| 67 | + // 取消所有待处理的请求 |
| 68 | + cancelAllPendingRequests(player); |
| 69 | + } else { |
| 70 | + // 启用私人模式 |
| 71 | + player.getPersistentDataContainer().set(PRIVACY_MODE_KEY, PersistentDataType.BYTE, (byte) 1); |
| 72 | + plugin.getMessages().send(player, "privacy-mode-enabled"); |
| 73 | + } |
| 74 | + |
| 75 | + plugin.getLogger().info(String.format("玩家 %s %s了私人模式", |
| 76 | + player.getName(), currentMode ? "禁用" : "启用")); |
66 | 77 | } |
67 | 78 |
|
68 | | - public boolean isPrivateMode(Player player) { |
69 | | - return privateModeUsers.contains(player.getUniqueId()); |
| 79 | + /** |
| 80 | + * 清除玩家的私人模式状态(用于调试或管理员操作) |
| 81 | + */ |
| 82 | + public void clearPrivateMode(Player player) { |
| 83 | + if (player == null || !player.isOnline()) { |
| 84 | + return; |
| 85 | + } |
| 86 | + |
| 87 | + player.getPersistentDataContainer().remove(PRIVACY_MODE_KEY); |
| 88 | + plugin.getLogger().info(String.format("已清除玩家 %s 的私人模式设置", player.getName())); |
70 | 89 | } |
71 | 90 |
|
72 | | - public void togglePrivateMode(Player player) { |
73 | | - UUID uuid = player.getUniqueId(); |
74 | | - if (privateModeUsers.contains(uuid)) { |
75 | | - privateModeUsers.remove(uuid); |
76 | | - plugin.getMessages().send(player, "privacy-mode-disabled"); |
| 91 | + /** |
| 92 | + * 管理员方法:设置玩家的隐私模式状态 |
| 93 | + * @param player 目标玩家 |
| 94 | + * @param enabled 是否启用隐私模式 |
| 95 | + */ |
| 96 | + public void setPrivateMode(Player player, boolean enabled) { |
| 97 | + if (player == null || !player.isOnline()) { |
| 98 | + return; |
| 99 | + } |
| 100 | + |
| 101 | + if (enabled) { |
| 102 | + player.getPersistentDataContainer().set(PRIVACY_MODE_KEY, PersistentDataType.BYTE, (byte) 1); |
77 | 103 | } else { |
78 | | - privateModeUsers.add(uuid); |
79 | | - plugin.getMessages().send(player, "privacy-mode-enabled"); |
| 104 | + player.getPersistentDataContainer().set(PRIVACY_MODE_KEY, PersistentDataType.BYTE, (byte) 0); |
| 105 | + } |
| 106 | + |
| 107 | + plugin.getLogger().info(String.format("管理员设置玩家 %s 的隐私模式为: %s", |
| 108 | + player.getName(), enabled ? "启用" : "禁用")); |
| 109 | + } |
| 110 | + |
| 111 | + /** |
| 112 | + * 获取所有在线玩家中启用了隐私模式的玩家数量 |
| 113 | + */ |
| 114 | + public int getPrivateModePlayerCount() { |
| 115 | + return (int) plugin.getServer().getOnlinePlayers().stream() |
| 116 | + .filter(this::isPrivateMode) |
| 117 | + .count(); |
| 118 | + } |
| 119 | + |
| 120 | + /** |
| 121 | + * 调试方法:验证 PersistentData 实施 |
| 122 | + */ |
| 123 | + public String debugPrivacyStatus(Player player) { |
| 124 | + if (player == null) { |
| 125 | + return "玩家为空"; |
| 126 | + } |
| 127 | + |
| 128 | + boolean hasKey = player.getPersistentDataContainer().has(PRIVACY_MODE_KEY, PersistentDataType.BYTE); |
| 129 | + byte value = player.getPersistentDataContainer().getOrDefault(PRIVACY_MODE_KEY, PersistentDataType.BYTE, (byte) -1); |
| 130 | + boolean isPrivate = isPrivateMode(player); |
| 131 | + |
| 132 | + return String.format("玩家: %s | 有PersistentData键: %s | 值: %d | 隐私模式: %s", |
| 133 | + player.getName(), hasKey, value, isPrivate); |
| 134 | + } |
| 135 | + |
| 136 | + /** |
| 137 | + * 取消玩家的所有待处理请求 |
| 138 | + */ |
| 139 | + private void cancelAllPendingRequests(Player player) { |
| 140 | + UUID playerUuid = player.getUniqueId(); |
| 141 | + |
| 142 | + // 取消作为目标的所有请求 |
| 143 | + Map<UUID, ScheduledTask> targetRequests = pendingRequests.get(playerUuid); |
| 144 | + if (targetRequests != null) { |
| 145 | + for (Map.Entry<UUID, ScheduledTask> entry : targetRequests.entrySet()) { |
| 146 | + entry.getValue().cancel(); |
| 147 | + Player requester = plugin.getServer().getPlayer(entry.getKey()); |
| 148 | + if (requester != null && requester.isOnline()) { |
| 149 | + plugin.getMessages().send(requester, "request-cancel"); |
| 150 | + } |
| 151 | + } |
| 152 | + pendingRequests.remove(playerUuid); |
| 153 | + } |
| 154 | + |
| 155 | + // 取消作为请求者的所有请求 |
| 156 | + for (Map.Entry<UUID, Map<UUID, ScheduledTask>> entry : pendingRequests.entrySet()) { |
| 157 | + ScheduledTask task = entry.getValue().remove(playerUuid); |
| 158 | + if (task != null) { |
| 159 | + task.cancel(); |
| 160 | + Player target = plugin.getServer().getPlayer(entry.getKey()); |
| 161 | + if (target != null && target.isOnline()) { |
| 162 | + plugin.getMessages().send(target, "request-cancel"); |
| 163 | + } |
| 164 | + } |
80 | 165 | } |
81 | | - savePrivacyStates(); |
82 | 166 | } |
83 | 167 |
|
84 | 168 | public void sendPeekRequest(Player peeker, Player target) { |
|
0 commit comments