GlowstoneMC / Glowstone

A fast, customizable and compatible open source server for Minecraft: Java Edition
https://glowstone.net
Other
1.89k stars 271 forks source link

NullPointerException when setting potion data using .getData().setData(byte) without PotionMeta #307

Open daboross opened 8 years ago

daboross commented 8 years ago

Here's the error:

20:59:33 [INFO] a [/127.0.0.1:60496] connected, UUID: 52428a0e-1e30-3cb1-976c-e728b2614047
20:59:33 [INFO] a joined the game
20:59:33 [SEVERE] Error while executing GlowTask{id=22, plugin=null, sync=true: net.glowstone.net.handler.login.LoginStartHandler$$Lambda$40/22042775@1f15420}
java.lang.NullPointerException
        at net.glowstone.inventory.GlowMetaPotion.dataToString(GlowMetaPotion.java:191)
        at net.glowstone.inventory.GlowMetaPotion.writeNbt(GlowMetaPotion.java:87)
        at net.glowstone.inventory.GlowItemFactory.writeNbt(GlowItemFactory.java:80)
        at net.glowstone.io.nbt.NbtSerialization.writeItem(NbtSerialization.java:74)
        at net.glowstone.io.nbt.NbtSerialization.writeInventory(NbtSerialization.java:112)
        at net.glowstone.block.entity.TEContainer.saveNbt(TEContainer.java:45)
        at net.glowstone.GlowChunk.toMessage(GlowChunk.java:697)
        at net.glowstone.GlowChunk.toMessage(GlowChunk.java:616)
        at net.glowstone.entity.GlowPlayer.streamBlocks(GlowPlayer.java:716)
        at net.glowstone.entity.GlowPlayer.join(GlowPlayer.java:403)
        at net.glowstone.net.GlowSession.setPlayer(GlowSession.java:342)
        at net.glowstone.net.handler.login.LoginStartHandler.lambda$handle$0(LoginStartHandler.java:56)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at net.glowstone.scheduler.GlowTask.run(GlowTask.java:167)
        at net.glowstone.scheduler.GlowScheduler.pulse(GlowScheduler.java:152)
        at net.glowstone.scheduler.GlowScheduler.lambda$start$0(GlowScheduler.java:83)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

This isn't logging in with a regular client, but with a java program using https://github.com/Steveice10/MCProtocolLib to test.

This may or may not be related to an earlier error, which was caused by the plugin I'm testing. Earlier error:

java.lang.NullPointerException                                                  
        at net.glowstone.inventory.GlowMetaPotion.dataToString(GlowMetaPotion.java:191)                                  
        at net.glowstone.inventory.GlowMetaPotion.writeNbt(GlowMetaPotion.java:87)        
        at net.glowstone.inventory.GlowItemFactory.writeNbt(GlowItemFactory.java:80)      
        at net.glowstone.io.nbt.NbtSerialization.writeItem(NbtSerialization.java:74)                                                      
        at net.glowstone.io.nbt.NbtSerialization.writeInventory(NbtSerialization.java:112)
        at net.glowstone.block.entity.TEContainer.saveNbt(TEContainer.java:45)
        at net.glowstone.GlowChunk.toMessage(GlowChunk.java:697)
        at net.glowstone.GlowChunk.toMessage(GlowChunk.java:616)
        at net.glowstone.entity.GlowPlayer.streamBlocks(GlowPlayer.java:716)
        at net.glowstone.entity.GlowPlayer.spawnAt(GlowPlayer.java:761)
        at net.glowstone.entity.GlowPlayer.teleport(GlowPlayer.java:1524)
        at net.glowstone.entity.GlowPlayer.teleport(GlowPlayer.java:1506)
        at net.daboross.bukkitdev.skywars.world.SkyWorldHandler.onGameStart1(SkyWorldHandler.java:167)
        at net.daboross.bukkitdev.skywars.events.GameEventDistributor.distribute(GameEventDistributor.java:72)
        at net.daboross.bukkitdev.skywars.game.GameQueue.queuePlayer(GameQueue.java:61)
        at net.daboross.bukkitdev.skywars.commands.mainsubcommands.JoinCommand.runCommand$7bc4b72f(JoinCommand.java:50)
        at net.daboross.bukkitdev.skywars.libraries.commands.CommandExecutorBase.onCommand(CommandExecutorBase.java:54)
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45)
        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:194)
        at net.glowstone.GlowServer.dispatchCommand(GlowServer.java:1244)
        at net.glowstone.entity.GlowPlayer.lambda$chat$7(GlowPlayer.java:1794)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at net.glowstone.scheduler.GlowTask.run(GlowTask.java:167)
        at net.glowstone.scheduler.GlowScheduler.pulse(GlowScheduler.java:152)
        at net.glowstone.scheduler.GlowScheduler.lambda$start$0(GlowScheduler.java:83)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

The line, net.daboross.bukkitdev.skywars.world.SkyWorldHandler.onGameStart1(SkyWorldHandler.java:167), shouldn't be sending anything null, but would there be any clue as to what it's sending which is wrong?

To test, and I'm not sure if this is reproducible, the program I'm using which uses MCProtocolLib is http://github.com/daboross/minecraft-commandline-interface - a command line bot tester.

I'm mostly submitting this to get input on what MCProtocolLib/minecraft-command-line-interface is doing wrong / different from the default Minecraft client. I don't know enough about Glowstone to know what isn't being sent, so it'd be awesome if someone with knowledge of Glowstone could give input on this.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/35621690-nullpointerexception-when-setting-potion-data-using-getdata-setdata-byte-without-potionmeta?utm_campaign=plugin&utm_content=tracker%2F14691067&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F14691067&utm_medium=issues&utm_source=github).
daboross commented 8 years ago

The earlier error might want to be a separate issue, as I can confirm it occurs reproducibly with regular minecraft clients, and a non-null Location.

Here's the full error:

21:31:22 [INFO] [SkyWars] Sending player zbsh (uuid: 0df069e1-a82f-3aa9-af99-ac99e7b9ada8) to spawn Location{world=GlowWorld(name=SkyWarsArenaWorld),x=46.5,y=27.0,z=14.5,pitch=0.0,yaw=0.0}
21:31:22 [SEVERE] [SkyWars] Couldn't broadcast GameStart in SkyWars version skywars-2.1.5-8-g2320b65 - 2.1.6-SNAPSHOT:
java.lang.NullPointerException
        at net.glowstone.inventory.GlowMetaPotion.dataToString(GlowMetaPotion.java:191)
        at net.glowstone.inventory.GlowMetaPotion.writeNbt(GlowMetaPotion.java:87)
        at net.glowstone.inventory.GlowItemFactory.writeNbt(GlowItemFactory.java:80)
        at net.glowstone.io.nbt.NbtSerialization.writeItem(NbtSerialization.java:74)
        at net.glowstone.io.nbt.NbtSerialization.writeInventory(NbtSerialization.java:112)
        at net.glowstone.block.entity.TEContainer.saveNbt(TEContainer.java:45)
        at net.glowstone.GlowChunk.toMessage(GlowChunk.java:697)
        at net.glowstone.GlowChunk.toMessage(GlowChunk.java:616)
        at net.glowstone.entity.GlowPlayer.streamBlocks(GlowPlayer.java:714)
        at net.glowstone.entity.GlowPlayer.spawnAt(GlowPlayer.java:761)
        at net.glowstone.entity.GlowPlayer.teleport(GlowPlayer.java:1524)
        at net.glowstone.entity.GlowPlayer.teleport(GlowPlayer.java:1506)
        at net.daboross.bukkitdev.skywars.world.SkyWorldHandler.onGameStart1(SkyWorldHandler.java:173)
        at net.daboross.bukkitdev.skywars.events.GameEventDistributor.distribute(GameEventDistributor.java:72)
        at net.daboross.bukkitdev.skywars.game.GameHandler.startNewGame(GameHandler.java:51)
        at net.daboross.bukkitdev.skywars.commands.mainsubcommands.ForceStartCommand.runCommand$7bc4b72f(ForceStartCommand.java:42)
        at net.daboross.bukkitdev.skywars.libraries.commands.CommandExecutorBase.onCommand(CommandExecutorBase.java:54)
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45)
        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:194)
        at net.glowstone.GlowServer.dispatchCommand(GlowServer.java:1244)
        at net.glowstone.ConsoleManager$CommandTask.run(ConsoleManager.java:284)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at net.glowstone.scheduler.GlowTask.run(GlowTask.java:167)
        at net.glowstone.scheduler.GlowScheduler.pulse(GlowScheduler.java:152)
        at net.glowstone.scheduler.GlowScheduler.lambda$start$0(GlowScheduler.java:83)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
21:31:22 [WARNING] zbsh moved too quickly!

The debug message from my plugin is definitely the location passed. SkyWarsArenaWorld is the world which the plugin creates.

gdude2002 commented 8 years ago

I'm not 100% certain that potions are implemented yet, but if they are then it looks like your problem is that you're passing in an invalid potion from your plugin. Can you check that?

aramperes commented 8 years ago

Seems like you are using numerical IDs (data values) to give a potion, which is not supported as of 1.9 (#281) . Please use PotionMeta if you are not already.

Edit: This could also be an incompatibility issue with inventories containing potions before 1.9.

daboross commented 8 years ago

Yeah, the plugin is using numerical IDs to set potions. The only reason currently to do it though is to restore stored items in chests, which were only stored by item data. I guess I'll just have to find a way to detect what PotionEffectType is used for the raw item data.

Thanks!

daboross commented 8 years ago

@momothereal Sorry, to be clear, what API replaces the raw data? PotionMeta seems to only support potions with getCustomPotions(), which only returns plugin-added potions, not ones that are placed on the potion by brewing.

Is there a Bukkit (or Glowkit) API which supports the current equivalent of raw item data?

If not I'd be happy to try to contribute one.

aramperes commented 8 years ago

@daboross I am not exactly sure when this was added to Bukkit, but you can find such a method here.

I think that method might have been added in the Bukkit 1.9.4 release, but I myself cannot find it in the official Bukkit 1.9.4 JAR. Anyhow, if you have a problem with finding that method, use the 1.9.4 Glowstone JAR in your classpath instead of Bukkit (which supports that method)

Edit: I'd also add that I have no idea if there's an API to convert old data values to the PotionData API.

daboross commented 8 years ago

@momothereal Thanks, I must not have been looking at the most up to date docs. Should I close this issue now?

gdude2002 commented 8 years ago

Is your problem solved?

daboross commented 8 years ago

I can now fix my plugin to not cause this error, but if it is desirable that Glowstone produce a more descriptive error when this happens then the issue could remain open.

If Glowstone producing an NPE for an incorrect use of the raw data API is fine, then this can be considered solved.

mastercoms commented 8 years ago

I think @momothereal is working on supporting the legacy method as well. This issue can be a tracker for that.

daboross commented 8 years ago

@momothereal If it helps at all, I've now written a raw-byte-to-modern-API and vice-versa converter for my plugin. I'm sure it'd be easy to re-create, but it took me a while to read through the old Minecraft potion documentation and type everything up, so here's this if you want to grab anything from it: https://github.com/daboross/bukkit-storage-protobuf/blob/master/src/main/java/net/daboross/bukkitdev/bukkitstorageprotobuf/CrossPotions.java#L172. You are free to use it as if it were public domain.