Skip to content

Commit b846cf6

Browse files
feat(api): 集成ApiRouter并支持完整HTTP方法
修复了HttpServer只使用ApiManager导致的API访问问题,现在支持GET、POST、DELETE请求。 整合白名单和管理员API端点,确保所有文档中列出的API均可正常使用。 新增统一请求路由逻辑,根据路径智能选择ApiManager或ApiRouter处理请求。 扩展ApiManager以支持多种HTTP方法,并添加服务器重载、缓存清理等新功能。 完善插件启动流程,注册白名单监听器并加载相关配置。 更新config.yml和plugin.yml,增加白名单控制选项及权限节点。
1 parent 5247580 commit b846cf6

6 files changed

Lines changed: 271 additions & 104 deletions

File tree

API_STATUS.md

Lines changed: 0 additions & 101 deletions
This file was deleted.

src/main/java/com/xaoxiao/convenientaccess/ConvenientAccessPlugin.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package com.xaoxiao.convenientaccess;
22

3+
import org.bukkit.plugin.java.JavaPlugin;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
6+
37
import com.xaoxiao.convenientaccess.api.ApiManager;
48
import com.xaoxiao.convenientaccess.cache.CacheManager;
59
import com.xaoxiao.convenientaccess.command.ConvenientAccessCommand;
@@ -8,9 +12,6 @@
812
import com.xaoxiao.convenientaccess.http.HttpServer;
913
import com.xaoxiao.convenientaccess.integration.SparkIntegration;
1014
import com.xaoxiao.convenientaccess.whitelist.WhitelistSystem;
11-
import org.bukkit.plugin.java.JavaPlugin;
12-
import org.slf4j.Logger;
13-
import org.slf4j.LoggerFactory;
1415

1516
public class ConvenientAccessPlugin extends JavaPlugin {
1617
private static final Logger logger = LoggerFactory.getLogger(ConvenientAccessPlugin.class);
@@ -69,6 +70,13 @@ public void onEnable() {
6970
// 注册命令
7071
getCommand("convenientaccess").setExecutor(new ConvenientAccessCommand(this));
7172

73+
// 注册白名单监听器
74+
getServer().getPluginManager().registerEvents(
75+
new com.xaoxiao.convenientaccess.listener.WhitelistListener(this),
76+
this
77+
);
78+
logger.info("白名单监听器已注册");
79+
7280
logger.info("ConvenientAccess 插件启动完成!");
7381

7482
} catch (Exception e) {

src/main/java/com/xaoxiao/convenientaccess/config/ConfigManager.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,50 @@ public int getSparkTimeout() {
128128
return config.getInt("spark.timeout", 5000);
129129
}
130130

131+
// 白名单配置
132+
public boolean isWhitelistEnabled() {
133+
return config.getBoolean("whitelist.enabled", true);
134+
}
135+
136+
public boolean isWhitelistStrictMode() {
137+
return config.getBoolean("whitelist.strict-mode", false);
138+
}
139+
140+
public String getWhitelistKickMessage() {
141+
return config.getString("whitelist.kick-message",
142+
"&c您不在服务器白名单中!\n&7请联系管理员申请加入白名单");
143+
}
144+
145+
public String getContactInfo() {
146+
return config.getString("whitelist.contact-info", "请联系管理员");
147+
}
148+
149+
public int getTokenExpiryHours() {
150+
return config.getInt("whitelist.token-expiry-hours", 24);
151+
}
152+
153+
public boolean isAutoCleanupTokens() {
154+
return config.getBoolean("whitelist.auto-cleanup-tokens", true);
155+
}
156+
157+
public boolean isJoinNotificationEnabled() {
158+
return config.getBoolean("whitelist.join-notification.enabled", true);
159+
}
160+
161+
public String getJoinNotificationPermission() {
162+
return config.getString("whitelist.join-notification.permission",
163+
"convenientaccess.whitelist.notify");
164+
}
165+
166+
public boolean isWelcomeMessageEnabled() {
167+
return config.getBoolean("whitelist.welcome-message.enabled", true);
168+
}
169+
170+
public String getWelcomeMessage() {
171+
return config.getString("whitelist.welcome-message.text",
172+
"&a欢迎回到服务器!\n&7玩家: &e{player}");
173+
}
174+
131175
// 日志配置
132176
public boolean isLogRequests() {
133177
return config.getBoolean("logging.log-requests", false);
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
package com.xaoxiao.convenientaccess.listener;
2+
3+
import java.util.concurrent.CompletableFuture;
4+
import java.util.concurrent.TimeUnit;
5+
6+
import org.bukkit.ChatColor;
7+
import org.bukkit.entity.Player;
8+
import org.bukkit.event.EventHandler;
9+
import org.bukkit.event.EventPriority;
10+
import org.bukkit.event.Listener;
11+
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
12+
import org.bukkit.event.player.PlayerJoinEvent;
13+
import org.slf4j.Logger;
14+
import org.slf4j.LoggerFactory;
15+
16+
import com.xaoxiao.convenientaccess.ConvenientAccessPlugin;
17+
import com.xaoxiao.convenientaccess.whitelist.WhitelistManager;
18+
19+
/**
20+
* 白名单监听器
21+
* 监听玩家连接事件,验证白名单并阻止未授权玩家进入
22+
*/
23+
public class WhitelistListener implements Listener {
24+
private static final Logger logger = LoggerFactory.getLogger(WhitelistListener.class);
25+
26+
private final ConvenientAccessPlugin plugin;
27+
private final WhitelistManager whitelistManager;
28+
29+
30+
31+
public WhitelistListener(ConvenientAccessPlugin plugin) {
32+
this.plugin = plugin;
33+
this.whitelistManager = plugin.getWhitelistSystem().getWhitelistManager();
34+
}
35+
36+
/**
37+
* 处理玩家预登录事件(异步)
38+
* 在玩家实际进入服务器前检查白名单
39+
*/
40+
@EventHandler(priority = EventPriority.HIGHEST)
41+
public void onAsyncPlayerPreLogin(AsyncPlayerPreLoginEvent event) {
42+
String playerName = event.getName();
43+
String playerUuid = event.getUniqueId().toString();
44+
45+
logger.debug("检查玩家白名单状态: {} ({})", playerName, playerUuid);
46+
47+
try {
48+
// 检查白名单系统是否已初始化
49+
if (!plugin.getWhitelistSystem().isInitialized()) {
50+
logger.warn("白名单系统未初始化,允许玩家 {} 进入", playerName);
51+
return;
52+
}
53+
54+
// 检查配置是否启用白名单
55+
if (!plugin.getConfigManager().isWhitelistEnabled()) {
56+
logger.debug("白名单功能已禁用,允许玩家 {} 进入", playerName);
57+
return;
58+
}
59+
60+
// 异步检查玩家是否在白名单中
61+
CompletableFuture<Boolean> whitelistCheck = whitelistManager.isPlayerWhitelisted(playerUuid);
62+
63+
// 等待结果(设置合理的超时时间)
64+
Boolean isWhitelisted = whitelistCheck.get(5, TimeUnit.SECONDS);
65+
66+
if (!isWhitelisted) {
67+
// 玩家不在白名单中,拒绝连接
68+
String kickMessage = getCustomKickMessage(playerName);
69+
event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_WHITELIST, kickMessage);
70+
71+
logger.info("拒绝玩家连接(未在白名单中): {} ({})", playerName, playerUuid);
72+
73+
// 记录操作日志
74+
logUnauthorizedAccess(playerName, playerUuid, event.getAddress().getHostAddress());
75+
} else {
76+
logger.info("允许玩家连接(已在白名单中): {} ({})", playerName, playerUuid);
77+
}
78+
79+
} catch (java.util.concurrent.TimeoutException | java.util.concurrent.ExecutionException | InterruptedException e) {
80+
logger.error("检查玩家白名单状态时发生错误: {} ({})", playerName, playerUuid, e);
81+
82+
// 发生错误时的处理策略
83+
if (plugin.getConfigManager().isWhitelistStrictMode()) {
84+
// 严格模式:发生错误时拒绝连接
85+
event.disallow(
86+
AsyncPlayerPreLoginEvent.Result.KICK_OTHER,
87+
"§c白名单验证失败,请稍后重试"
88+
);
89+
logger.warn("严格模式下拒绝玩家连接(白名单验证失败): {}", playerName);
90+
} else {
91+
// 宽松模式:发生错误时允许连接
92+
logger.warn("宽松模式下允许玩家连接(白名单验证失败): {}", playerName);
93+
}
94+
}
95+
}
96+
97+
/**
98+
* 处理玩家加入事件
99+
* 发送欢迎消息给白名单玩家
100+
*/
101+
@EventHandler(priority = EventPriority.MONITOR)
102+
public void onPlayerJoin(PlayerJoinEvent event) {
103+
Player player = event.getPlayer();
104+
String playerUuid = player.getUniqueId().toString();
105+
106+
// 异步检查玩家信息并发送消息
107+
whitelistManager.getPlayerByUuid(playerUuid).thenAccept(entryOpt -> {
108+
if (entryOpt.isPresent()) {
109+
// 向管理员发送玩家加入通知
110+
if (plugin.getConfigManager().isJoinNotificationEnabled()) {
111+
sendJoinNotificationToAdmins(player, entryOpt.get());
112+
}
113+
114+
// 向玩家发送自定义欢迎消息
115+
if (plugin.getConfigManager().isWelcomeMessageEnabled()) {
116+
sendWelcomeMessage(player);
117+
}
118+
}
119+
}).exceptionally(throwable -> {
120+
logger.error("处理玩家加入事件时发生错误: {}", player.getName(), throwable);
121+
return null;
122+
});
123+
}
124+
125+
/**
126+
* 获取自定义踢出消息
127+
*/
128+
private String getCustomKickMessage(String playerName) {
129+
String template = plugin.getConfigManager().getWhitelistKickMessage();
130+
131+
// 替换占位符
132+
return template
133+
.replace("{player}", playerName)
134+
.replace("{server}", plugin.getServer().getName())
135+
.replace("{contact}", plugin.getConfigManager().getContactInfo())
136+
.replace("&", "§"); // 支持颜色代码
137+
}
138+
139+
/**
140+
* 记录未授权访问
141+
*/
142+
private void logUnauthorizedAccess(String playerName, String playerUuid, String ipAddress) {
143+
logger.warn("未授权访问尝试 - 玩家: {} ({}), IP: {}", playerName, playerUuid, ipAddress);
144+
145+
// TODO: 可以扩展为写入数据库操作日志
146+
// plugin.getDatabaseManager().executeAsync(connection -> {
147+
// // 插入操作日志
148+
// return null;
149+
// });
150+
}
151+
152+
/**
153+
* 向管理员发送玩家加入通知
154+
*/
155+
private void sendJoinNotificationToAdmins(Player player, com.xaoxiao.convenientaccess.whitelist.WhitelistEntry entry) {
156+
String notification = ChatColor.GREEN + "" + ChatColor.BOLD + "[白名单] " +
157+
ChatColor.YELLOW + player.getName() +
158+
ChatColor.GRAY + " 已加入服务器 " +
159+
ChatColor.DARK_GRAY + "(添加者: " + entry.getAddedByName() + ")";
160+
161+
// 发送给有权限的管理员
162+
String permission = plugin.getConfigManager().getJoinNotificationPermission();
163+
plugin.getServer().getOnlinePlayers().stream()
164+
.filter(p -> p.hasPermission(permission))
165+
.forEach(admin -> admin.sendMessage(notification));
166+
}
167+
168+
/**
169+
* 发送欢迎消息给玩家
170+
*/
171+
private void sendWelcomeMessage(Player player) {
172+
String welcomeTemplate = plugin.getConfigManager().getWelcomeMessage();
173+
String welcomeMessage = welcomeTemplate
174+
.replace("{player}", player.getName())
175+
.replace("{server}", plugin.getServer().getName())
176+
.replace("&", "§");
177+
178+
// 延迟1秒发送,确保玩家完全加入
179+
plugin.getServer().getScheduler().runTaskLater(plugin, () -> {
180+
player.sendMessage(welcomeMessage);
181+
}, 20L);
182+
}
183+
}

0 commit comments

Comments
 (0)