feat: code

This commit is contained in:
2025-12-29 18:03:34 +08:00
parent a63c841076
commit d4ec8ab5ee
5 changed files with 18 additions and 16 deletions

View File

@@ -20,6 +20,7 @@ import online.mineroo.common.BindRequest;
import online.mineroo.common.BindRequest.PlayerBindEnum; import online.mineroo.common.BindRequest.PlayerBindEnum;
import online.mineroo.common.BindRequest.PlayerBindResponse; import online.mineroo.common.BindRequest.PlayerBindResponse;
import online.mineroo.common.BindRequest.PlayerBindStatusEnum; import online.mineroo.common.BindRequest.PlayerBindStatusEnum;
import online.mineroo.common.MessageManager;
import online.mineroo.paper.Config; import online.mineroo.paper.Config;
import online.mineroo.paper.MinerooCore; import online.mineroo.paper.MinerooCore;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@@ -53,6 +54,8 @@ public class PlayerBindListener implements Listener {
@EventHandler @EventHandler
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
Config config = this.plugin.getConfigObject(); Config config = this.plugin.getConfigObject();
MessageManager messageManager = this.plugin.getMessageManager();
if (!config.getPlayer().getPlayerBind().isRequired()) { if (!config.getPlayer().getPlayerBind().isRequired()) {
return; return;
} }
@@ -63,21 +66,18 @@ public class PlayerBindListener implements Listener {
// Lock player immediately upon join // Lock player immediately upon join
restrictedPlayers.add(uuid); restrictedPlayers.add(uuid);
// 延迟 2 秒 (40 ticks) 再发送检查请求,给予 Proxy 通道建立缓冲时间,防止发包过快导致丢失 (504)
Bukkit.getScheduler().runTaskLater(plugin, () -> { Bukkit.getScheduler().runTaskLater(plugin, () -> {
if (!player.isOnline()) { if (!player.isOnline()) {
restrictedPlayers.remove(uuid); // 玩家中途退出,清理缓存 restrictedPlayers.remove(uuid);
return; return;
} }
// 异步检查,避免阻塞主线程
this.plugin.getBindRequest() this.plugin.getBindRequest()
.checkPlayerBindStatus(uuid, null) .checkPlayerBindStatus(uuid, null)
.thenAccept(response -> { .thenAccept(response -> {
// 回到主线程处理 UI 和 踢出逻辑
Bukkit.getScheduler().runTask(plugin, () -> { Bukkit.getScheduler().runTask(plugin, () -> {
if (!player.isOnline()) if (!player.isOnline())
return; // 玩家可能在检查期间退出了 return;
handleBindStatus(player, response.getStatus(), response.getMessage()); handleBindStatus(player, response.getStatus(), response.getMessage());
}); });
@@ -86,9 +86,7 @@ public class PlayerBindListener implements Listener {
plugin.getLogger().severe("Failed to check bind status for " + uuid); plugin.getLogger().severe("Failed to check bind status for " + uuid);
e.printStackTrace(); e.printStackTrace();
Bukkit.getScheduler().runTask(plugin, () -> { Bukkit.getScheduler().runTask(plugin, () -> {
player.kick( player.kick(messageManager.get("error.internal"));
Component.text("Internal server error, please try again later.", NamedTextColor.RED)
);
}); });
return null; return null;
}); });
@@ -114,10 +112,8 @@ public class PlayerBindListener implements Listener {
dialogResponse.completeOnTimeout(null, 2, TimeUnit.MINUTES); dialogResponse.completeOnTimeout(null, 2, TimeUnit.MINUTES);
awaitingResponse.put(uniqueId, dialogResponse); awaitingResponse.put(uniqueId, dialogResponse);
// 使用 player 直接显示 Dialog
player.showDialog(dialog); player.showDialog(dialog);
// 异步等待 Dialog 结果,不阻塞主线程
dialogResponse.thenAccept(bindResponse -> { dialogResponse.thenAccept(bindResponse -> {
Bukkit.getScheduler().runTask(plugin, () -> { Bukkit.getScheduler().runTask(plugin, () -> {
awaitingResponse.remove(uniqueId); awaitingResponse.remove(uniqueId);
@@ -130,12 +126,10 @@ public class PlayerBindListener implements Listener {
} }
if (bindResponse.getStatus() == PlayerBindEnum.BOUND) { if (bindResponse.getStatus() == PlayerBindEnum.BOUND) {
// 极其罕见的情况:请求瞬间已绑定(通常不会发生,除非已有自动绑定逻辑)
restrictedPlayers.remove(uniqueId); restrictedPlayers.remove(uniqueId);
player.sendMessage(this.plugin.getMessageManager().get("info.bind.player.success")); player.sendMessage(this.plugin.getMessageManager().get("info.bind.player.success"));
} else if (bindResponse.getStatus() == PlayerBindEnum.PENDING) { } else if (bindResponse.getStatus() == PlayerBindEnum.PENDING) {
player.closeDialog(); player.closeDialog();
// 提交成功,踢出玩家,让其去网站确认
player.kick(this.plugin.getMessageManager().get("info.bind.player.pending")); player.kick(this.plugin.getMessageManager().get("info.bind.player.pending"));
} else { } else {
player.closeDialog(); player.closeDialog();
@@ -158,6 +152,8 @@ public class PlayerBindListener implements Listener {
@EventHandler @EventHandler
void onHandleDialog(PlayerCustomClickEvent event) { void onHandleDialog(PlayerCustomClickEvent event) {
MessageManager messageManager = plugin.getMessageManager();
Player player = null; Player player = null;
if (event.getCommonConnection() instanceof PlayerGameConnection conn) { if (event.getCommonConnection() instanceof PlayerGameConnection conn) {
player = conn.getPlayer(); player = conn.getPlayer();
@@ -191,7 +187,10 @@ public class PlayerBindListener implements Listener {
}); });
} else if (key.equals(Key.key("mineroo:bind_user/cancel"))) { } else if (key.equals(Key.key("mineroo:bind_user/cancel"))) {
setConnectionJoinResult( setConnectionJoinResult(
playerUuid, BindRequest.createPlayerBindErrorResponse("Canceled by user") playerUuid,
BindRequest.createPlayerBindErrorResponse(
messageManager.getString("info.bind.player.canceled")
)
); );
} }
} }

View File

@@ -18,10 +18,13 @@ command.bind.server.retry=<yellow>验证未通过10 秒后重试 (<current>/<
## Player Bind [Both for screen and command] ## Player Bind [Both for screen and command]
info.bind.player.already-bound=<yellow>当前用户已绑定</yellow> info.bind.player.already-bound=<yellow>当前用户已绑定</yellow>
info.bind.player.dialog-undefined=<red>Dialog 加载失败,请联系管理员</red> info.bind.player.dialog-undefined=<red>Dialog 加载失败,请联系管理员</red>
info.bind.player.pending = "<green>绑定申请已发送,请登录 Mineroo 网站进行后续操作。</green>" info.bind.player.pending = <green>绑定申请已发送,请登录 Mineroo 网站进行后续操作。</green>
info.bind.player.success = "<green>绑定成功!</green>" info.bind.player.success = <green>绑定成功!</green>
info.bind.player.canceled = "绑定请求已取消。" info.bind.player.canceled = <red>绑定请求已取消。</red>
# Reload Command # Reload Command
command.reload.success=<green>配置文件重载成功!耗时 <time>ms</green> command.reload.success=<green>配置文件重载成功!耗时 <time>ms</green>
command.reload.failed=<red>配置文件重载失败,请查看控制台日志。</red> command.reload.failed=<red>配置文件重载失败,请查看控制台日志。</red>
# Error info
error.internal =<red>内部服务器错误,请稍后再试。</red>