You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ktor服务器中ItemStack获取ItemMeta空指针问题咨询

问题:Ktor服务器调用Spigot API的ItemMeta时触发空指针异常

我正在开发一款Ktor服务器,用于实现玩家用游戏内货币购买游戏内物品的功能,当前使用1.20版本的Spigot API。调用getItemMeta()方法(Kotlin中为.itemMeta)时出现空指针异常,导致fromJson(string: String?):ItemStack?方法无法正常工作,同时调用toJson(itemStack: ItemStack):String方法也会触发空指针。

异常堆栈

java.lang.NullPointerException: null
    at org.bukkit.Bukkit.getItemFactory(Bukkit.java:1608)
    at org.bukkit.inventory.ItemStack.getItemMeta(ItemStack.java:550)
    at fr.plaglefleau.serialization.JsonItemStack.fromJson(JsonItemStack.kt:278)
    at fr.plaglefleau.bdd_MySql.Gestion.updateInventory(Gestion.kt:815)
    at fr.plaglefleau.plugins.RoutingKt$configureRouting$1$3$1$1$7.invokeSuspend(Routing.kt:588)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.internal.DispatchedContinuation.resumeWith(DispatchedContinuation.kt:205)
    at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:135)
    at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:109)
    at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(SuspendFunctionGun.kt:11)
    at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:59)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.ktor.server.netty.EventLoopGroupProxy$Companion.create$lambda$1$lambda$0(NettyApplicationEngine.kt:296)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:834)
2023-07-09 03:46:51.495 [eventLoopGroupProxy-4-1] TRACE io.ktor.server.sessions.Sessions - Sending session data for /api/client/updateInventory: connect
2023-07-09 03:46:51.496 [eventLoopGroupProxy-4-1] TRACE i.k.s.p.c.ContentNegotiation - Skipping response body transformation from HttpStatusCode to OutgoingContent for the PUT /api/client/updateInventory request because the HttpStatusCode type is ignored. See [ContentNegotiationConfig::ignoreType].

相关代码片段

Gestion.updateInventory方法

fun updateInventory(inventory: ArrayList<ItemSlotPair>, username: String) {
    val laConnexion = Connexion(url, this.username, password)
    var preparedStatement = laConnexion.getConnexion().prepareStatement(
        "SELECT id FROM user WHERE username = ?"
    )
    preparedStatement.setString(1,username)
    var rs = preparedStatement.executeQuery()
    val userID = if(rs.next()) {
        rs.getInt("id")
    } else {
        null
    }
    if(userID == null) {
        return
    }
    for(i in 0..inventory.size) {
        val item = JsonItemStack.fromJson(inventory[i].item) ?: return
        addItemIfNotExist(item)
        preparedStatement = laConnexion.getConnexion().prepareStatement(
            "UPDATE inventaire SET article_id = ?, quantité = ? WHERE slot_number = ? AND user_id = ?"
        )
        preparedStatement.setInt(1,item.type.id)
        preparedStatement.setInt(2,item.amount)
        preparedStatement.setInt(3, inventory[i].slot)
        preparedStatement.setInt(4,userID)
        preparedStatement.executeUpdate()
    }
    laConnexion.fermerConnexion()
}

JsonItemStack.kt:218行

val meta = itemStack.itemMeta

Routing.kt中的updateInventory路由

put("updateInventory") {
    val receive = call.receive<InventoryReceive>()
    gestion.updateInventory(receive.inventory, receive.username)
    call.respond(HttpStatusCode.OK, "Good")
}

问题推测与需求

获取ItemStack的ItemMeta需要依赖ItemFactory接口,而获取该接口需要调用Server.getItemFactory(),但我的服务未运行在Minecraft服务器环境中,导致Spigot API无法正常获取ItemMeta。现寻求可行的解决方案,目前考虑使用自定义类存储ItemStack的相关数据。


内容的提问来源于stack exchange,提问作者Plag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 22:20:42