Skip to content

Commit 0922e32

Browse files
实现PersistentData兼容跨服
1 parent 7c0683e commit 0922e32

4 files changed

Lines changed: 152 additions & 45 deletions

File tree

src/main/java/ict/minesunshineone/peek/PeekPlugin.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,8 @@ public void onDisable() {
9393
statisticsManager.saveStats();
9494
}
9595

96-
if (privacyManager != null) {
97-
privacyManager.savePrivacyStates();
98-
}
96+
// 注意:隐私管理器现在使用 PersistentData,无需手动保存
97+
// 数据会自动随玩家数据保存,支持 HuskSync 等跨服同步插件
9998

10099
if (packetListener != null) {
101100
packetListener.unregisterPacketListeners();
@@ -183,4 +182,16 @@ public PrivacyManager getPrivacyManager() {
183182
public StatisticsManager getStatisticsManager() {
184183
return statisticsManager;
185184
}
185+
186+
/**
187+
* 重新加载配置和消息文件
188+
* 用于调试或运行时更新配置
189+
*/
190+
public void reloadConfigs() {
191+
reloadConfig();
192+
if (messages != null) {
193+
messages.reloadMessages();
194+
}
195+
getLogger().info("配置文件已重新加载");
196+
}
186197
}

src/main/java/ict/minesunshineone/peek/manager/PrivacyManager.java

Lines changed: 126 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,168 @@
11
package ict.minesunshineone.peek.manager;
22

3-
import java.io.File;
4-
import java.io.IOException;
53
import java.util.HashMap;
6-
import java.util.HashSet;
7-
import java.util.List;
84
import java.util.Map;
9-
import java.util.Set;
105
import java.util.UUID;
11-
import java.util.stream.Collectors;
126

7+
import org.bukkit.NamespacedKey;
138
import org.bukkit.Sound;
14-
import org.bukkit.configuration.file.YamlConfiguration;
159
import org.bukkit.entity.Player;
10+
import org.bukkit.persistence.PersistentDataType;
1611

1712
import ict.minesunshineone.peek.PeekPlugin;
1813
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
1914

2015
public class PrivacyManager {
2116

2217
private final PeekPlugin plugin;
23-
private final Set<UUID> privateModeUsers = new HashSet<>();
2418
private final Map<UUID, Map<UUID, ScheduledTask>> pendingRequests = new HashMap<>();
2519
private final Map<String, Long> requestCooldowns = new HashMap<>();
2620

2721
private final int requestTimeout;
2822
private final boolean cooldownEnabled;
2923
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;
3327

3428
public PrivacyManager(PeekPlugin plugin) {
3529
this.plugin = plugin;
3630
this.requestTimeout = plugin.getConfig().getInt("privacy.request-timeout", 30);
3731
this.cooldownEnabled = plugin.getConfig().getBoolean("privacy.cooldown.enabled", true);
3832
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 存储隐私模式设置");
4236
}
4337

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;
5345
}
46+
47+
return player.getPersistentDataContainer()
48+
.getOrDefault(PRIVACY_MODE_KEY, PersistentDataType.BYTE, (byte) 0) == 1;
5449
}
5550

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;
6558
}
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 ? "禁用" : "启用"));
6677
}
6778

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()));
7089
}
7190

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);
77103
} 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+
}
80165
}
81-
savePrivacyStates();
82166
}
83167

84168
public void sendPeekRequest(Player peeker, Player target) {

src/main/java/ict/minesunshineone/peek/util/Messages.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,13 @@ public void sendActionBar(Player player, String key, String... placeholders) {
9898

9999
player.sendActionBar(LegacyComponentSerializer.legacyAmpersand().deserialize(message));
100100
}
101+
102+
/**
103+
* 重新加载消息文件
104+
* 用于调试或在运行时更新消息
105+
*/
106+
public void reloadMessages() {
107+
loadMessages();
108+
plugin.getLogger().info("消息文件已重新加载");
109+
}
101110
}

src/main/resources/config.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ limits:
99

1010
# 隐私设置
1111
privacy:
12+
# 注意: 从 v3.1 开始,隐私模式状态使用 PersistentData 存储
13+
# 这意味着隐私模式设置会跟随玩家数据,支持 HuskSync 等跨服同步插件
14+
# 旧的 privacy.yml 文件将不再使用
1215
request-timeout: 30 # 请求超时时间(秒)
1316
cooldown:
1417
enabled: true # 是否启用请求冷却

0 commit comments

Comments
 (0)