Adding glow to an item without having an actual enchantment

In bukkit I used this class for it:

import org.bukkit.enchantments.Enchantment;
import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.enchantments.EnchantmentWrapper;
import org.bukkit.inventory.ItemStack;
 
import java.lang.reflect.Field;
 
public class EnchantGlow extends EnchantmentWrapper
{
    private static Enchantment glow;
 
    public EnchantGlow(int id)
    {
        super(id);
    }
 
    @Override
    public boolean canEnchantItem(ItemStack item)
    {
        return false;
    }
 
    @Override
    public boolean conflictsWith(Enchantment other)
    {
        return false;
    }
 
    @Override
    public EnchantmentTarget getItemTarget()
    {
        return null;
    }
 
    @Override
    public int getMaxLevel()
    {
        return 10;
    }
 
    @Override
    public String getName()
    {
        return "Glow";
    }
 
    @Override
    public int getStartLevel()
    {
        return 1;
    }
 
    public static Enchantment getGlow()
    {
        if (glow != null) return glow;
 
        if(Enchantment.getByName("Glow") != null)
            return Enchantment.getByName("Glow");
 
        try
        {
            Field f = Enchantment.class.getDeclaredField("acceptingNew");
            f.setAccessible(true);
            f.set(null, true);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
 
        glow = new EnchantGlow(255);
        Enchantment.registerEnchantment(glow);
        return glow;
    }
 
    public static ItemStack addGlow(ItemStack item)
    {
        Enchantment glow = getGlow();
 
        if(!item.containsEnchantment(glow))
            item.addUnsafeEnchantment(glow, 1);
 
        return item;
    }
 
    public static ItemStack removeGlow(ItemStack item)
    {
        Enchantment glow = getGlow();
 
        if(item.containsEnchantment(glow))
            item.removeEnchantment(glow);
 
        return item;
    }
}

Is this possible in sponge? And if it is not, will it be possible later?

While it’s possible to utilise the base NMS code like you can in bukkit, it’s not recommended or supported (just like in Bukkit).

This makes use of a bug (feature?) of enchantments in that if the packet is sent with an empty enchantments field, the client will apply the glow effect but not have any actual enchantments.

Sponge could add this in the API, however as it’s based on a bug, and not a feature, it could be fixed at any point.

One of the thinks I don’t like about sponge is that things have to be in the API in order to use them. Bukkit had NMS where you could do anything you want, where Sponge has multiple implementations and for sure some of them don’t have NMS.

IMO, that’s one of the strengths of Sponge. We aren’t linked to a single implementation, and if one goes down (eg for DMCA), the others can stay standing.

Again, editing or use of base minecraft classes is completely unsupported. You can either tell your users that your plugin is only works/is tested with a given implementation, or design your code to be able to support multiple different implementations (many NMS plugins already do this to support version bumps)

I’ll be blunt—I’m not sure you understand how Bukkit, or Sponge, works. NMS was not a part of “Bukkit”, and Bukkit did not have NMS. While most Bukkit servers ran on CraftBukkit, there were plenty of other implementations, many of which would break your “working” code. And nothing in your code has anything to do with the mojang server (colloquially referred to as “net.minecraft.server” or NMS) so I’m not sure why you bring it up. You’re just modifying the internal state of the implementation on the fly.

2 Likes

I don’t see the problem with allowing people to set a DataManipulator of an empty enchantment list, then letting the implementation determine what it means.

It might work on some implementations, and may completely disappear in minecraft itself, but there is no reason why it can’t be semi supported in the API, just don’t name it as a feature, or specifically name it, and if people use the API in such a way to depend on something implementation specific, it’s no worse then an implementation that doesn’t support worldgen or something.

Especially if it’s not mentioned in the JavaDocs, or method names as adding enchantment glow.

3 Likes

Sorry for late response but old messages are here to help us ^^

I trying to make a item glow with this code:

item.offer(Keys.STORED_ENCHANTMENTS, Arrays.asList(new ItemEnchantment(Enchantments.UNBREAKING, 1)));

No errors, but the item dont glow. I tryed to find a way to use dataManipulator to add enchantments but i didnt found.
Is there a way?

You’re using the wrong key. Keys.STORED_ENCAHANTMENTS is for things like enchanted books, which carry an enchantment without applying it to the item. You’ll want to use Keys.ITEM_ENCHANTMENTS.

When in doubt, check the DataTransactionResult to see if offering the data worked.

lol

Thanks, now worked ^^

A note: Theres no Javadoc comment for this enums.

2 Likes