copygirl / BetterStorage

A Minecraft mod aimed at offering more storage options.
http://copy.mcft.net/mc/BetterStorage/
MIT License
57 stars 33 forks source link

Incompatibility between Storage crates and ForgeEssentials' Multiworld (and potentially any mod implementing their own SaveHandler) #312

Closed DashFury closed 8 years ago

DashFury commented 8 years ago

When breaking a storage crate in a dimension created by ForgeEssentials with its Multiworld module, the following exception is thrown:

[Server thread/WARN] [betterstorage]: Error saving CratePileData: java.lang.ClassCastException: com.forgeessentials.multiworld.MultiworldSaveHandler cannot be cast to net.minecraft.world.storage.SaveHandler

If the broken crate is also the only one of a crate group, meaning that the inventory will be deleted, the client crash when playing in single player, or is disconnected from the server in multiplayer. When reconnecting, the crate is deleted, but its inventory and the crate itself aren't dropped on the ground.

This is the line throwing the exception:

File saveFolder = ((SaveHandler)world.getSaveHandler()).getWorldDirectory();

ForgeEssentials's MultiworldSaveHandler implements ISaveHandler and not SaveHandler. Since SaveHandler also implements ISaveHandler, and since getSaveHandler() is declared in ISaveHandler, BetterStorage should cast to the interface and not the classes that implements it.

This has been tested with BetterStorage 0.13.1.126, ForgeEssentials 1.4.3.1012 and Forge 10.13.4.1517.

Stacktrace:

java.lang.ClassCastException: com.forgeessentials.multiworld.MultiworldSaveHandler cannot be cast to net.minecraft.world.storage.SaveHandler
    at net.mcft.copy.betterstorage.tile.crate.CratePileCollection.getSaveDirectory(CratePileCollection.java:107)
    at net.mcft.copy.betterstorage.tile.crate.CratePileCollection.getSaveFile(CratePileCollection.java:111)
    at net.mcft.copy.betterstorage.tile.crate.CratePileCollection.removeCratePile(CratePileCollection.java:68)
    at net.mcft.copy.betterstorage.tile.crate.CratePileData.remove(CratePileData.java:95)
    at net.mcft.copy.betterstorage.tile.crate.CratePileData.removeCrate(CratePileData.java:155)
    at net.mcft.copy.betterstorage.tile.crate.TileEntityCrate.setPileData(TileEntityCrate.java:59)
    at net.mcft.copy.betterstorage.tile.crate.TileEntityCrate.func_145843_s(TileEntityCrate.java:185)
    at net.minecraft.world.chunk.Chunk.func_150805_f(Chunk.java:901)
    at net.minecraft.world.World.func_147475_p(World.java:2609)
    at net.minecraft.block.Block.func_149749_a(Block.java:627)
    at net.minecraft.world.chunk.Chunk.func_150807_a(Chunk.java:600)
    at net.minecraft.world.World.func_147465_d(World.java:451)
    at net.minecraft.world.World.func_147468_f(World.java:573)
    at net.minecraft.block.Block.removedByPlayer(Block.java:1341)
    at net.mcft.copy.betterstorage.tile.TileContainerBetterStorage.removedByPlayer(TileContainerBetterStorage.java:49)
    at net.minecraft.block.Block.removedByPlayer(Block.java:1335)
    at net.minecraft.server.management.ItemInWorldManager.removeBlock(ItemInWorldManager.java:247)
    at net.minecraft.server.management.ItemInWorldManager.func_73079_d(ItemInWorldManager.java:240)
    at net.minecraft.server.management.ItemInWorldManager.func_73084_b(ItemInWorldManager.java:278)
    at net.minecraft.server.management.ItemInWorldManager.func_73074_a(ItemInWorldManager.java:151)
    at net.minecraft.network.NetHandlerPlayServer.func_147345_a(NetHandlerPlayServer.java:489)
    at net.minecraft.network.play.client.C07PacketPlayerDigging.func_148833_a(SourceFile:53)
    at net.minecraft.network.play.client.C07PacketPlayerDigging.func_148833_a(SourceFile:8)
    at net.minecraft.network.NetworkManager.func_74428_b(NetworkManager.java:212)
    at net.minecraft.network.NetworkSystem.func_151269_c(NetworkSystem.java:165)
    at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:659)
    at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:547)
    at net.minecraft.server.integrated.IntegratedServer.func_71217_p(IntegratedServer.java:111)
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:427)
    at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:685)
DashFury commented 8 years ago

After further testing, it appears that the crates are actually completely unusable in those dimensions, as they won't even be saved when the dimension is unloaded. Restarting the server and trying to access those crates will throw another exception: java.lang.ArithmeticException: / by zero similar to this issue.

copygirl commented 8 years ago

Weird, I wonder why this has only been reported now. Every crate pile is saved to an individual <dim>/data/crates/<id>.dat file. This is just how I got the dimension's folder at the time. There probably is a better way (I assume villages work, they use the same folder afaik).

I'd like to have a try at fixing this, but I stopped modding - I don't even have Java or an IDE installed - and the only way I could imagine to come back to it is by starting from scratch. Crates would really need to be redone.

Maybe @Victorious3 or one of the other guys would like to have a stab at it?

DashFury commented 8 years ago

I don't know if crates needs to be redone, but your implementation seems fine by me.

As far as I can tell, it's just a matter of casting on the interface and not the class. Everything's alright in dimensions that use the default SaveHandler instead of declaring their own. Casting on ISaveHandler would make it work with everything.

copygirl commented 8 years ago

Isn't it already ISaveHandler? And that is lacking getWorldDirectory() afair.

DashFury commented 8 years ago

Currently, it's just SaveHandler, as you can see from the CratePileCollection file:

File saveFolder = ((SaveHandler)world.getSaveHandler()).getWorldDirectory();

getWorldDirectory() shouldn't be a problem, it's declared in the interface too :)

copygirl commented 8 years ago

I could swear it wasn't when I first wrote that.

skyem123 commented 8 years ago

Hmm... It seems like a simple fix, so I'm going to fix it.

DashFury commented 8 years ago

Nice :)

copygirl commented 8 years ago

Thanks, @skyem123 and @Victorious3 :heart:

Does this fix the issue?

DashFury commented 8 years ago

Yes :D

Thanks to all of you!