Posted April 5, 201312 yr Problems with Minecraft Comes Alive: Users of my mod that have Forge 7.7.1.624 and above (so far) report problems that are not present on the recommended version that I link them to: 7.7.1.611. Description I use a certain packet to update the client with the same randomly selected information that the server selected and keep it updated. This is the process: Client entity doesn't have a texture -> Sends "sync request" packet to Server containing entity id -> Server handles "sync request" by serializing and sending back the entity with the provided id -> Client searches for entity with the same id as the one that was just received and deserialized -> ERROR. ID doesn't match any entities on the client. Client side entity is never updated. Packet is not properly handled. This problem was fixed by adding the entity id to the sync packet by itself, alongside the entity that was serialized. The client side entity was successfully updated but still did not receive its texture. Instead it used the default char.png. I specifically tell my entities to write their textures and entityIds when being serialized; for some reason this data wasn't written correctly. /** * Writes this object to an object output stream. (Serialization) * * @param out The object output stream that this object should be written to. * * @throws IOException This exception should never happen. */ private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(texture); out.writeObject(entityId); } /** * Reads this object from an object input stream. (Deserialization) * * @param in The object input stream that this object should be read from. * * @throws IOException This exception should never happen. * @throws ClassNotFoundException This exception should never happen. */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); texture = (String)in.readObject(); entityId = (Integer)in.readObject(); } Log verifying that some error has occurred with the entity id. They do not match when on previous versions they do! To see this output, you must use the command "/mca.debug on" before allowing a villager from the mod to spawn. 2013-04-03 22:04:37 [FINER] [ForgeModLoader] Minecraft Comes Alive [DEBUG] SERVER: Sync packet pre-sending data verification: entityBase = EntityVillagerAdult['entity.EntityVillagerAdult.name'/31999, l='New World', x=-829.50, y=4.00, z=270.50], data = [b@ece186, compressed data length = 1730 bytes 2013-04-03 22:04:37 [FINER] [ForgeModLoader] Minecraft Comes Alive [DEBUG] CLIENT: Received packet: MCA_SYNC. Size = 1730 2013-04-03 22:04:37 [FINER] [ForgeModLoader] Minecraft Comes Alive [DEBUG] CLIENT: Sync packet received. data length = [b@ece186 2013-04-03 22:04:37 [FINER] [ForgeModLoader] Minecraft Comes Alive [DEBUG] CLIENT: Decompressing bytes... 2013-04-03 22:04:37 [FINER] [ForgeModLoader] Minecraft Comes Alive [DEBUG] CLIENT: Decompressed data length = 3846 2013-04-03 22:04:37 [FINER] [ForgeModLoader] Minecraft Comes Alive [DEBUG] CLIENT: Received packet data verification: entityBase = EntityVillagerAdult['entity.EntityVillagerAdult.name'/32061, l='~NULL~', x=0.00, y=0.00, z=0.00], data = [b@1ca2f25, data length = 3846 After I fixed the problem with the entity ID, I also had to add the texture to the packet so that the client would actually receive the right texture data. My writeObject and readObject methods are being skipped. Why? More verification that these methods are skipped: the entity's inventory must also be serialized and sent back and forth. When I try to serialize the inventory for a packet, I get a NotSerializableException on a field. I override the serialization with writeObject and readObject, and I do not allow defaultWriteObject() to run so that I won't have the problem with a field not being serializable. It only writes what I tell it to. This is the error I get when trying to serialize an Inventory: 2013-04-04 23:10:27 [iNFO] [sTDERR] java.io.NotSerializableException: net.minecraft.item.ItemStack 2013-04-04 23:10:27 [iNFO] [sTDERR] at java.io.ObjectOutputStream.writeObject0(Unknown Source) 2013-04-04 23:10:27 [iNFO] [sTDERR] at java.io.ObjectOutputStream.writeArray(Unknown Source) 2013-04-04 23:10:27 [iNFO] [sTDERR] at java.io.ObjectOutputStream.writeObject0(Unknown Source) 2013-04-04 23:10:27 [iNFO] [sTDERR] at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) 2013-04-04 23:10:27 [iNFO] [sTDERR] at java.io.ObjectOutputStream.writeSerialData(Unknown Source) 2013-04-04 23:10:27 [iNFO] [sTDERR] at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) 2013-04-04 23:10:27 [iNFO] [sTDERR] at java.io.ObjectOutputStream.writeObject0(Unknown Source) 2013-04-04 23:10:27 [iNFO] [sTDERR] at java.io.ObjectOutputStream.writeObject(Unknown Source) 2013-04-04 23:10:27 [iNFO] [sTDERR] at mods.MCA.PacketCreator.createInventoryPacket(PacketCreator.java:432) 2013-04-04 23:10:27 [iNFO] [sTDERR] at mods.MCA.EntityVillagerAdult.interact(EntityVillagerAdult.java:678) 2013-04-04 23:10:27 [iNFO] [sTDERR] at net.minecraft.entity.player.EntityPlayer.interactWith(EntityPlayer.java:1222) 2013-04-04 23:10:27 [iNFO] [sTDERR] at net.minecraft.client.multiplayer.PlayerControllerMP.func_78768_b(PlayerControllerMP.java:462) 2013-04-04 23:10:27 [iNFO] [sTDERR] at net.minecraft.client.Minecraft.clickMouse(Minecraft.java:1291) 2013-04-04 23:10:27 [iNFO] [sTDERR] at net.minecraft.client.Minecraft.runTick(Minecraft.java:1796) 2013-04-04 23:10:27 [iNFO] [sTDERR] at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:831) 2013-04-04 23:10:27 [iNFO] [sTDERR] at net.minecraft.client.Minecraft.run(Minecraft.java:756) 2013-04-04 23:10:27 [iNFO] [sTDERR] at java.lang.Thread.run(Unknown Source) I specifically include the writeObject() method in Inventory to skip the default serialization and prevent this problem. You can view this for yourself in both versions of the source code. Why does this happen? And why only on later versions of Forge? Source Code (Broken on 624+, perfect on 611-) - https://dl.dropbox.com/u/64124307/Broken%20Source.zip Source Code (Semi-Fixed for later Forge versions, Inventory packet kills the game. Gift a sword to a villager.) - https://dl.dropbox.com/u/64124307/Semi-Fixed%20Source.zip Files of interest: PacketHandler.java, createSyncPacket(), createSyncRequestPacket(), createInventoryPacket() PacketCreator.java, handleSync(), handleSyncRequest(), handleInventory() EntityVillagerAdult.java, interact() EntityBase.java, writeObject(), readObject() Inventory.java, writeObject(), readObject() While it seems entirely wrong to blame Forge for what appears to be a problem with serialization (I have no idea how you can screw with built-in java), the exact same code works flawlessly on Forge 611 and has been working for months! I don't know what else to blame.
April 5, 201312 yr Humm aside from the fact that you're doing things horribly wrong! jesus christ! We have facilities in place for extra spawn data for a reason! Lookin at those changesets, it doesn't seem like we do anything that would effect your mod this way. However, I did test on 611 and 624, and do see the issue happening. Will do a little more testing with versions and see if I can track down to a specific build. Taking a wild guess i'm gunna say it has something to do with runtime deobfusication based on the horribly method you're using for serializing your data... Seriously dude, thats bad, you should just send enough to get the information you need across not THE ENTIRE OBJECT, it is nothing but massive network churn. Alright, I was correct, you are trying to serialize the entire object. Which does not work as to maintain ModLoader compatibility we need to make all fields/methods public in all remapped classes. So you need to look into actually determining what data you need and not relying on ObjectOutputStream, that was designed for small data objects, not large great grandchild objects. I do Forge for free, however the servers to run it arn't free, so anything is appreciated. Consider supporting the team on Patreon
April 5, 201312 yr Author If I could be pointed to some documentation of these "facilities" I'd gladly use them. And I know my method is bad, but it does/has worked without networking issues until now. Guess it has to go.
April 5, 201312 yr https://github.com/MinecraftForge/FML/blob/master/common/cpw/mods/fml/common/registry/IEntityAdditionalSpawnData.java I do Forge for free, however the servers to run it arn't free, so anything is appreciated. Consider supporting the team on Patreon
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.