Created
August 11, 2014 23:13
-
-
Save aadnk/13a7cea653118dd6f187 to your computer and use it in GitHub Desktop.
Add enchantment glow to items in creative mode. Requires AttributeStorage and TinyProtocol (can be added directly to your plugin).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.comphenix.example; | |
import java.sql.Ref; | |
import java.util.Collections; | |
import java.util.UUID; | |
import net.minecraft.util.io.netty.channel.Channel; | |
import org.bukkit.Material; | |
import org.bukkit.command.Command; | |
import org.bukkit.command.CommandSender; | |
import org.bukkit.enchantments.Enchantment; | |
import org.bukkit.entity.Player; | |
import org.bukkit.event.Listener; | |
import org.bukkit.inventory.ItemStack; | |
import org.bukkit.plugin.java.JavaPlugin; | |
import com.comphenix.example.Reflection.FieldAccessor; | |
import com.comphenix.example.Reflection.MethodInvoker; | |
public class GlowInCreativeMode extends JavaPlugin implements Listener { | |
// Generate your own at uuidgenerator.net | |
private static final UUID MY_RANDOM_UUID = UUID.fromString("057d9831-1966-40e4-8e57-f82b59c95a60"); | |
private static final String MY_SECRET_VALUE = "glow"; | |
private static Class<?> PACKET_WINDOW_ITEMS = Reflection.getMinecraftClass("PacketPlayOutWindowItems"); | |
private static Class<?> PACKET_SET_SLOT = Reflection.getMinecraftClass("PacketPlayOutSetSlot"); | |
// net.minecraft.server.VERSION.ItemStack, not org.bukkit.inventory.ItemStack: | |
private static Class<Object> NMS_ITEM_STACK = Reflection.getUntypedClass("{nms}.ItemStack"); | |
private static Class<Object> NMS_ITEM_STACK_ARRAY = Reflection.getUntypedClass("[L{nms}.ItemStack;"); | |
private static FieldAccessor<Object> setSlotStacks = Reflection.getField(PACKET_SET_SLOT, NMS_ITEM_STACK, 0); | |
private static FieldAccessor<Object> windowItemStacks = Reflection.getField(PACKET_WINDOW_ITEMS, NMS_ITEM_STACK_ARRAY, 0); | |
// Convert NMS ItemStack to Bukkit ItemStack | |
private static MethodInvoker GET_CRAFT_ITEM_STACK = Reflection.getMethod("{obc}.inventory.CraftItemStack", "asCraftMirror", NMS_ITEM_STACK); | |
private TinyProtocol tiny; | |
@Override | |
public void onEnable() { | |
tiny = new TinyProtocol(this) { | |
@Override | |
public Object onPacketOutAsync(Player reciever, Channel channel, Object packet) { | |
// This check should be as efficient as possible, as it is called for EVERY packet sent to the players | |
if (PACKET_WINDOW_ITEMS.isInstance(packet)) { | |
for (Object nmsItem : (Object[])windowItemStacks.get(packet)) { | |
processItemStack(getItemStack(nmsItem)); | |
} | |
} else if (PACKET_SET_SLOT.isInstance(packet)) { | |
processItemStack(getItemStack(setSlotStacks.get(packet))); | |
} | |
return packet; | |
} | |
}; | |
} | |
private ItemStack getItemStack(Object nmsStack) { | |
return (ItemStack) GET_CRAFT_ITEM_STACK.invoke(null, nmsStack); | |
} | |
/** | |
* Invoked for every stack sent to every player. | |
* @param stack - the stack. | |
*/ | |
private void processItemStack(ItemStack stack) { | |
if (stack == null || stack.getType() == Material.AIR) | |
return; | |
// Consider if you should limit this to a certain type of item | |
//if (stack.getType() != Material.IRON_AXE) | |
// return; | |
if (MY_SECRET_VALUE.equals(AttributeStorage.newTarget(stack, MY_RANDOM_UUID).getData(null))) { | |
// Add a fake enchantment with NbtFactory from AttributeStorage | |
NbtFactory.fromItemTag(stack).put("ench", NbtFactory.createList()); | |
} | |
} | |
@Override | |
public void onDisable() { | |
tiny.close(); | |
} | |
@Override | |
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { | |
if (sender instanceof Player) { | |
Player player = (Player) sender; | |
ItemStack stack = new ItemStack(Material.IRON_AXE); | |
// Make it glow! | |
AttributeStorage storage = AttributeStorage.newTarget(stack, MY_RANDOM_UUID); | |
storage.setData(MY_SECRET_VALUE); | |
// Always use target! | |
player.getInventory().addItem(storage.getTarget()); | |
} | |
return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment