Skip to content

Instantly share code, notes, and snippets.

@aadnk
Created August 11, 2014 23:13
Show Gist options
  • Save aadnk/13a7cea653118dd6f187 to your computer and use it in GitHub Desktop.
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).
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