SQLite 数据库连接已关闭或 Java 为空

问题描述 投票:0回答:1

我正在尝试为 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)

我尝试使用正常的调试语句来找出它在哪里关闭,似乎是在检查玩家是否被禁止之后。

java sqlite minecraft spigot
1个回答
0
投票

我自己设法解决了这个问题,具体方法如下。 所以主要的问题是我首先检查该会员是否被禁止。 连接并未真正正确关闭/打开,因此稍后会导致错误。 这是更新后的 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;
    }
© www.soinside.com 2019 - 2024. All rights reserved.