stats.get/set/add don't work
kaliflowerx3 opened this issue · 7 comments
Versions:
kjs: kubejs-fabric-1802.5.4-build.506.jar
rhino: rhino-fabric-1802.1.14-build.190.jar
fabric: 0.14.6
fabric-api: fabric-api-0.56.1+1.18.2.jar
I wasn't able to find the method "Stats.CUSTOM.id(string)" (from the line above) in the fabric docs (unclear if this works on forge) and the functions player.stats.get/set/add(id) return a wrapped NPE.
Also, I'm pretty sure these methods read the stat file in /world/stats/playeruuid.json, but editing the file does not change the in game stat because it appears to need to be updated but I don't think it accepts changes to the file in that direction (file -> server). In the end I was able to edit the stat using serverPlayerEntity.resetStat
to which I passed Stats.CUSTOM.getOrCreateStat(Stats.TIME_SINCE_REST)
It seems like you should be able to pass instead, for example, a new Identifier with let dmg = new Identifier("minecraft:damage_taken")
but it gives me the error Wrapped java.lang.NullPointerException: Cannot invoke "net.minecraft.class_2960.toString()" because "$$0" is null
even though Stats.DAMAGE_TAKEN
is the same class (class 2960) and dmg == Stats.DAMAGE_TAKEN
returns true
Anyway I hope this has provided enough information.
here are the relevant mappings
https://github.com/FabricMC/yarn/blob/dfda2435aa0ca2f8707fa5a7d6ecb57b3e5546a9/mappings/net/minecraft/entity/player/PlayerEntity.mapping#L132
https://maven.fabricmc.net/docs/yarn-21w15a+build.2/net/minecraft/stat/Stats.html (this is not for the correct version but is easier to read and includes the fields)
https://github.com/FabricMC/yarn/blob/1.18.2/mappings/net/minecraft/stat/Stats.mapping
and here is my awful reflection code (works)
const Stats = java("net.minecraft.class_3468")
const Stat = java("net.minecraft.class_3445")
const Javaobj = java("java.lang.Object")
onEvent('player.chat', function (event) {
let serverPlayerEntity = event.player.minecraftPlayer
let resetStat = serverPlayerEntity.class.getMethod("method_7266", Stat)
let getOrCreateStat = Stats.CUSTOM.class.getMethod("method_14956", Javaobj)
resetStat.invoke(serverPlayerEntity, getOrCreateStat.invoke(Stats.CUSTOM, Stats.TIME_SINCE_REST))
event.server.tell(event.player.stats.getTimeSinceRest())
})
By the way, the reason I'm using reflection in this manner instead of the new deobsfuscated methods is because theres a fabric-specific bug with it starting with version 1.18.2; thread on the discord here: https://discord.com/channels/303440391124942858/981262916051423303
testing the same code on forge gives this:
Error occurred while handling event 'player.chat': Wrapped java.lang.NullPointerException: Cannot invoke "net.minecraft.resources.ResourceLocation.toString()" because "p_12866_" is null (server_scripts:test.js#3)
edit: https://bugs.mojang.com/browse/MC-254139 does this mean its a bug with minecraft itself?
Hokay, now that I've actually had the time to read this issue:
- KubeJS uses official mappings, not yarn. This is why you couldn't find any of these methods
- Do you have any logs that could give me, for example, a stack trace of the NPE you were talking about? I have a sneaking suspicion I know what the issue might be, but I am not entirely certain
Also, adding onto this, do you have a version of your script without the reflection hacks, because that'd be helpful, as well
code:
onEvent('player.chat', function (event) {
event.server.tell("time since rest 1: " + event.player.stats.getTimeSinceRest()) //says "time since rest 1: 322671"
event.server.tell("time since rest 2: " + event.player.stats.get("minecraft:time_since_rest")) //says nothing
})
Also tried "time_since_rest" and just nonsense strings and it always gives this error.
Error in console: Error occurred while handling event 'player.chat': Wrapped java.lang.NullPointerException: Cannot invoke "net.minecraft.class_2960.toString()" because "$$0" is null (server_scripts:test.js#3)
No stacktrace in the logs. Checked the console as well as logs/kubejs/server.txt
is there anywhere else I can look?
I don't know if it's at all helpful but I was only able to force a stacktrace when I put capital letters in stats.get(resourceid):
[STDERR]: net.minecraft.class_151: Non [a-z0-9/._-] character in path of location: minecraft:TIME_SINCE_REST
[STDERR]: at net.minecraft.class_2960.<init>(class_2960.java:41)
[STDERR]: at net.minecraft.class_2960.<init>(class_2960.java:46)
[STDERR]: at dev.latvian.mods.kubejs.util.UtilsJS.getMCID(UtilsJS.java:420)
[STDERR]: at dev.latvian.mods.rhino.NativeJavaObject.coerceTypeImpl(NativeJavaObject.java:550)
[STDERR]: at dev.latvian.mods.rhino.Context.jsToJava(Context.java:1383)
[STDERR]: at dev.latvian.mods.rhino.NativeJavaMethod.call(NativeJavaMethod.java:173)
[STDERR]: at dev.latvian.mods.rhino.Interpreter.interpretLoop(Interpreter.java:1310)
[STDERR]: at dev.latvian.mods.rhino.Interpreter.interpret(Interpreter.java:647)
[STDERR]: at dev.latvian.mods.rhino.InterpretedFunction.call(InterpretedFunction.java:78)
[STDERR]: at dev.latvian.mods.rhino.ContextFactory.doTopCall(ContextFactory.java:221)
[STDERR]: at dev.latvian.mods.rhino.ScriptRuntime.doTopCall(ScriptRuntime.java:2696)
[STDERR]: at dev.latvian.mods.rhino.InterpretedFunction.call(InterpretedFunction.java:76)
[STDERR]: at dev.latvian.mods.rhino.InterfaceAdapter.invokeImpl(InterfaceAdapter.java:131)
[STDERR]: at dev.latvian.mods.rhino.InterfaceAdapter.lambda$invoke$0(InterfaceAdapter.java:90)
[STDERR]: at dev.latvian.mods.rhino.Context.call(Context.java:368)
[STDERR]: at dev.latvian.mods.rhino.ContextFactory.call(ContextFactory.java:328)
[STDERR]: at dev.latvian.mods.rhino.InterfaceAdapter.invoke(InterfaceAdapter.java:90)
[STDERR]: at dev.latvian.mods.rhino.VMBridge.lambda$newInterfaceProxy$0(VMBridge.java:100)
[STDERR]: at jdk.proxy2/jdk.proxy2.$Proxy53.onEvent(Unknown Source)
[STDERR]: at dev.latvian.mods.kubejs.event.EventsJS.postToHandlers(EventsJS.java:58)
[STDERR]: at dev.latvian.mods.kubejs.event.EventJS.post(EventJS.java:32)
[STDERR]: at dev.latvian.mods.kubejs.level.LevelEventJS.post(LevelEventJS.java:30)
[STDERR]: at dev.latvian.mods.kubejs.player.KubeJSPlayerEventHandler.chat(KubeJSPlayerEventHandler.java:87)
[STDERR]: at net.minecraft.class_3244.handler$zma000$handleChat(class_3244.java:5215)
[STDERR]: at net.minecraft.class_3244.method_31286(class_3244.java:1243)
[STDERR]: at net.minecraft.class_3244.method_31284(class_3244.java:310)
[STDERR]: at java.base/java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:718)
[STDERR]: at java.base/java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:482)
[STDERR]: at net.minecraft.class_3738.run(class_3738.java:18)
[STDERR]: at net.minecraft.class_1255.method_18859(class_1255.java:157)
[STDERR]: at net.minecraft.class_4093.method_18859(class_4093.java:23)
[STDERR]: at net.minecraft.server.MinecraftServer.method_24306(MinecraftServer.java:808)
[STDERR]: at net.minecraft.server.MinecraftServer.method_18859(MinecraftServer.java:165)
[STDERR]: at net.minecraft.class_1255.method_16075(class_1255.java:131)
[STDERR]: at net.minecraft.server.MinecraftServer.method_20415(MinecraftServer.java:790)
[STDERR]: at net.minecraft.server.MinecraftServer.method_16075(MinecraftServer.java:784)
[STDERR]: at net.minecraft.class_1255.method_18857(class_1255.java:140)
[STDERR]: at net.minecraft.server.MinecraftServer.method_16208(MinecraftServer.java:769)
[STDERR]: at net.minecraft.server.MinecraftServer.method_29741(MinecraftServer.java:701)
[STDERR]: at net.minecraft.server.MinecraftServer.method_29739(MinecraftServer.java:273)
[STDERR]: at java.base/java.lang.Thread.run(Thread.java:833)