I'm currently working on a mod that is all about signs and one part of it is a multi-tool that enables editing existing signs in the world.
Opening the GUI on the client side, changing the text and updating the TileEntitySign all works fine and dandy in SMP. But one caveat is that players are able to edit the same sign at the same time. This results in a scenario where PlayerA is editing, PlayerB just clicked on it, PlayerA presses "Done", PlayerB presses "Done" and the end result is the message from PlayerB - while both of them started on a copy of the original sign text.
The GUI for this works slightly different than the typical container GUI, the class GuiEditSign on the client-side does all the rendering without any container class.
The funny part is that TileEntitySign has a attribute named isEditable, but lets see.
The rundown is as follows:
[*]Player right-clicks with multi-tool on existing sign, onItemUse() gets called
[*]in there, displayGUIEditSign() gets called to display the GUI on the client-side
[*]on initGui() the method actually sets the TileEntitySign to being non-editable
[*]onGuiClosed() a Packet130UpdateSign gets send and the TileEntitySign is editable again
[*]the global packet-handler updates the TileEntitySign upon receiving the packet, showing the new text
Now, the culprit lies in the fact that the isEditable attribute is only ever changed on the client. The actual TileEntitySign.isEditable in the server world still reads true and won't ever get updated. That means every player can click and edit the sign and we won't be able to block it in our onItemUse() method.
The solution I have thought about so far:
onItemUse() sets isEditable to false (on the server TileEntitySign) in anticipation that the GuiEditSign gets called
the sign is now blocked for other players
OptionA: somehow receive the Packet130UpdateSign, upon we can assume that editing was done and change isEditable to true again
OptionB: somehow register an event to get notified when the TileEntitySign gets updated/changed in the world, upon we know that the editing was done
The gist of it is that we don't really know when the client finishes editing the sign and I'm thinking of ways around editing base classes.
If you have any ideas about this, please chip in