Bukkit/CraftBukkit — pull request #1090 by YLivay (2013-03-22 20:29:52+00:00)
Title: Adds BUKKIT-3859, InventoryPaintEvent

Added InventoryPaintEvent
-------
Since 1.5 there's two new inventory operations:
* __Painting mode__ - where you can drag a stack of items onto slots to "paint" with it. If you left click, you split the items evenly across the painted slots, and if you right click you put 1 in each slot.
* __Stacking mode__ - where a double click on an item attempts to stack at the cursor all items that are equal to the double clicked item.

### What's happening
When the client paints is that when the client releases the mouse button, it goes through 3 steps:
* Send a signal packet with raw slot ID -999 and action modifier 5 (Called Packet102WindowClick.shift for some reason) with a null ItemStack. This tells the server to start painting.
* A batch of windows click packets (Packet102WindowClick) for every slot. The server accumulates these clicks and then...
* Send another signal packet indicating the end of painting operation. At this point the server runs the logic for all the slots and distributes the item stack in the cursor to the selected slots depending on which mouse button the client held.

To make everything worse, there's also a bug that sometimes makes normal click operations act like painting operations for a single item.

### The problem
As it is now, Bukkit is not equipped to deal with these operations.
Bukkit does not detect the signal packets and filter them out, and send InventoryClickEvent for them anyways, which causes problems to plugins monitoring it,
and for the rest of the packets, it doesn't detect the items put in the slots or the cursor state because the logic is done only when the end signal packet arrives.

### The solution
InventoryPaintEvent handles this problem by filtering out all painting mode packets, and throwing a flexible, cancellable event for all the accumulated packet changes.
The event saves the changes to the slots and allows plugin developers to react to each slot individually by modifying the list of slots. After the event finishes, any changes made to the operation will be applied to the slots.

Using this implementation you can:
* Cancel the event completely.
* Cancel changes to individual slots.
* Get the itemstacks for each slot before the painting operation.
* Get the cursor itemstack before the painting operation.
* Change each slot's result item stack individually.
* Get the result cursor itemstack after the painting operation (Changes to slot itemstacks after the event is raised are not reflected in the result cursor itemstack).
* Change the result cursor itemstack.

__Note:__ I chose not to extend InventoryClickEvent since it is not a click, it's a hold operation, and also not to check type/damage/amount for result items (going by the decision in my EntityEquipEvent PR).

__Bukkit PR:__ https://github.com/Bukkit/Bukkit/pull/821
__Leaky:__ https://bukkit.atlassian.net/browse/BUKKIT-3859