-
Bug
-
Resolution: Fixed
-
Minor
-
None
-
None
Keep in mind that I'm using a "Sign" just to demonstrate the bug,
but it is the same for all blocks with TileEnitities like Chests, Banners, etc.
I have provided a solution to fix it inside Craftbukkit at the end of the description.
Shouldn't be much to do.
Example Code
public void createSign(Block block) { block.setType(Material.SIGN_POST); Sign sign = (Sign)block.getState(); sign.setLine(0, "test"); sign.update(); } public void testBug(Block block) { //create a sign with "test" in first line createSign(block); //now remember the block state, so we can restore changes to the block later on BlockState state = block.getState(); //a wild minecrafter appears and replaces the sign with another block (e.g. dirt) block.setType(Material.DIRT); //now some time has passed and we want to FORCE restore the old state. state.update(true); //The sign and it's orientation got restored (due to material id and data byte getting force-set) //But, alas, the signs text did NOT! /* * WORKAROUND in USER-CODE */ //we can workaround this quite easily in user-code: //I figured out the text is actually updated in the source code (CraftSign.java), //but it seems like it isn't displayed. //This is because the old TileEntity saved in the BlockState gets updated, and not the one created by the block-change. //So what we have to do is either use the new blockstate and call: state.update(true); Sign new_state = (Sign)block.getState(); new_state.setLine(0, old_state.getLine(0)); //repeat this for all the data saved in the TileEntity (e.g. Skulls have a orientation) //and finally: new_state.update(); }
FIX in Craftbukkit:
My suggestion to fix this is to also update the newly created tile entity
when a blockstate gets force-updated via update(true);
Example for CraftSign.java. would have to be repeated for all TileEntity-BlockStates:
/** * CODE COPIED from current craftbukkit-build */ @Override public boolean update(boolean force, boolean applyPhysics) { boolean result = super.update(force, applyPhysics); if (result) { //FIX -- HERE if (force) { //update the internal tile-entity to the one created by minecraft sign = ...; } //FIX END IChatBaseComponent[] newLines = sanitizeLines(lines); System.arraycopy(newLines, 0, sign.lines, 0, 4); sign.update(); } return result; }