我正在尝试为 Minecraft spigot 1.20.2 创建 Ban 命令。我正在使用 SQLITE 来存储数据。我正在使用 OnPlayerJoinEvent 来检查玩家是否被禁止,如果是,那么我们会获取禁止信息并阻止他们进入服务器。但是,当它尝试获取禁令信息时,它会在数据库连接关闭或为空时出错。
这是加入事件代码。
Main plugin = Main.getInstance();
public JoinEvent(Main plugin)
{
this.plugin = plugin;
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event)
{
Player player = event.getPlayer();
String playerName = event.getPlayer().getName();
if (isPlayerBanned(playerName)) {
System.out.println("Person banned.");
// Get ban information
BanInfo banInfo = getBanInfo(playerName);
// Prevent the player from joining
event.setJoinMessage(null); // Remove default join message
player.kickPlayer(getKickMessage(banInfo));
}
if(event.getPlayer().hasPlayedBefore())
{
FileConfiguration config = plugin.getConfig();
String joinMessage = config.getString("join-message-has-played-before");
joinMessage = joinMessage.replace("%player%", playerName);
event.setJoinMessage(joinMessage);
}
else
{
FileConfiguration config = plugin.getConfig();
String joinMessage = config.getString("join-message-has-not-played-before");
joinMessage = joinMessage.replace("%player%", playerName);
event.setJoinMessage(joinMessage);
}
}
private boolean isPlayerBanned(String playerName) {
try (Connection connection = SQLiteConnector.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT COUNT(*) FROM bans WHERE player_name = ?")) {
statement.setString(1, playerName);
try (ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
int count = resultSet.getInt(1);
return count > 0;
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
private BanInfo getBanInfo(String playerName) {
PreparedStatement statement = null;
ResultSet resultSet = null;
try{
Connection connection = SQLiteConnector.getConnection();
if (connection == null || connection.isClosed()) {
throw new SQLException("Database connection is null or closed.");
}
statement = connection.prepareStatement("SELECT * FROM bans WHERE player_name = ?");
statement.setString(1, playerName);
resultSet = statement.executeQuery();
if (resultSet.next()) {
String staffMember = resultSet.getString("staff_member");
String reason = resultSet.getString("reason");
return new BanInfo(playerName, staffMember, reason);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
// Note: Do not close the connection here to keep it open for later use
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
private String getKickMessage(BanInfo banInfo) {
if (banInfo != null) {
return ChatColor.RED + "You are banned from this server.\n" +
ChatColor.RED + "Banned by: " + ChatColor.YELLOW + banInfo.getStaffMember() + "\n" +
ChatColor.RED + "Reason: " + ChatColor.YELLOW + banInfo.getReason();
} else {
return ChatColor.RED + "You are banned from this server.";
}
}
这是 SQLConnector 代码:
private static Connection connection;
public static Connection getConnection() {
if(connection == null) {
try {
Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection("jdbc:sqlite:plugins/Jellyfish-Hosting-Plugin/punishments.db");
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
return connection;
}
public static void closeConnection() {
try {
if (connection != null && !connection.isClosed()) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
我收到的错误是(一半):
[22:20:03 WARN]: java.sql.SQLException: Database connection is null or closed.
[22:20:03 WARN]: at plugin-1.0-beta.jar//xyz.jellyfishhosting.plugin.events.JoinEvent.getBanInfo(JoinEvent.java:82)
[22:20:03 WARN]: at plugin-1.0-beta.jar//xyz.jellyfishhosting.plugin.events.JoinEvent.onPlayerJoin(JoinEvent.java:35)
[22:20:03 WARN]: at com.destroystokyo.paper.event.executor.asm.generated.GeneratedEventExecutor1.execute(Unknown Source)
[22:20:03 WARN]: at org.bukkit.plugin.EventExecutor$2.execute(EventExecutor.java:77)
[22:20:03 WARN]: at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:81)
[22:20:03 WARN]: at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70)
[22:20:03 WARN]: at io.papermc.paper.plugin.manager.PaperEventManager.callEvent(PaperEventManager.java:54)
[22:20:03 WARN]: at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.callEvent(PaperPluginManagerImpl.java:126)
[22:20:03 WARN]: at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:615)
[22:20:03 WARN]: at net.minecraft.server.players.PlayerList.a(PlayerList.java:346)
[22:20:03 WARN]: at net.minecraft.server.network.ServerConfigurationPacketListenerImpl.a(ServerConfigurationPacketListenerImpl.java:130)
[22:20:03 WARN]: at net.minecraft.network.protocol.configuration.ServerboundFinishConfigurationPacket.a(ServerboundFinishConfigurationPacket.java:18)
[22:20:03 WARN]: at net.minecraft.network.protocol.configuration.ServerboundFinishConfigurationPacket.a(ServerboundFinishConfigurationPacket.java:9)
[22:20:03 WARN]: at net.minecraft.network.protocol.PlayerConnectionUtils.lambda$ensureRunningOnSameThread$0(PlayerConnectionUtils.java:53)
我尝试使用正常的调试语句来找出它在哪里关闭,似乎是在检查玩家是否被禁止之后。
我自己设法解决了这个问题,具体方法如下。 所以主要的问题是我首先检查该会员是否被禁止。 连接并未真正正确关闭/打开,因此稍后会导致错误。 这是更新后的 isPlayerBanned 代码:
private boolean isPlayerBanned(String playerName) {
try{
Connection connection = SQLiteConnector.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT COUNT(*) FROM bans WHERE player_name = ?");
statement.setString(1, playerName);
try(ResultSet resultSet = statement.executeQuery()) {
if(resultSet.next()) {
int count = resultSet.getInt(1);
return count > 0;
}
}
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}