Bukkit/CraftBukkit — pull request #1094 by psycowithespn (2013-03-23 20:13:41+00:00)
Title: [C+B] Add in sendSignChange(), fixes BUKKIT-2300

##### The Issue:
In Bukkit, there exists a player.sendBlockChange() that is able to send signs to clients, but the signs are blank due to the lack of a method to set them. Sign text is send via the SignUpdate packet, so the method will need to use this packet for the faked signs.

##### Justification for this PR:
With player.sendBlockChange(), you can send a block with a specific data value, such as a sign with a specific rotation. What you can not send with this is the text on said signs, or even have per player signs without some modification to CraftBukkit, probably using this same method.

##### PR Breakdown:
This PR implements a way to fake a sign update packet. It takes a location and an array of Strings. Before the packet is created, it does some validation to the array, making sure each line is not null and less than 16 characters (the text limit on a sign in nms). Afterwards, it sends the SignUpdate packet with the x, y, and z coordinates of the location and the validated array to the client.

The reason that I don't validate that the location given is a sign or not is that we don't know what the client thinks. A previous valid call to player.sendBlockChange() creating a sign client side would be unknown to the server, so it doesn't matter if the location server side is a sign or not.

##### Testing Results and Materials:
In order to test this, I created a plugin that used the newly created sendSignChange() method with the player's "target" block as the location parameter. The args were then directly handed over to the method, allowing me to create nulls and arrays too short. I also created a second command that uses the existing sendBlockChange() methods to send a sign to the client at their target location. This allowed me to test the sendSignChange() method on clientside signs.

The results of the testing were good. Calling sendSignChange() with a sign as the player's target block changes the lines as expected, trimming any lines longer than 15 and setting nulls to blank strings. Calling sendSignChange() with a sendBlockChange() sign as the target also works as expected. However, calling sendSignChange() with a location that does not show a sign on the client side ends with the client saying "Unable to locate sign at x, y, z" in chat. The client can not crash out of the game using the sendSignChange() method.

Test server jar: https://dl.dropbox.com/u/59767756/craftbukkit-1.5.1-sendsignchange.jar
Test plugin jar: https://dl.dropbox.com/u/59767756/SendSignChangeTest-1.0-SNAPSHOT.jar
Test plugin usage:
/testchange [lines] - lines to change the target "sign" to using sendSignChange().
/testfake - creates a fake sign using player.sendBlockChange().

##### Relevant PR(s):

B - To be filled
CB- To be filled

##### JIRA Ticket:
BUKKIT-2300 - https://bukkit.atlassian.net/browse/BUKKIT-2300