Question Replacing an NMS registry entry with your own

Vizzoid

New member
Jan 23, 2022
12
0
1
I have been working on a class called Registry Writer, which I am using to, for instance, replace the SpawnEggItem with my own, but it isn't working for some reason, the item (Bat Spawn Egg) will not drop on my client.

Just to start, this is part big project and nothing else messes with registries, only this, so I will not switch to Forge. I am fine with editing the server jar but I would rather do that as a last resort. If you are wondering why I am doing this, it is because you can stop spawning of a spawn egg, but not when it is used on an entity to create offspring (at least, not without losing the item).

Here's the registry writer:
Java:
    public synchronized void clearCache() {
        INTRUSIVE_HOLDER_CACHE.set(registry, new IdentityHashMap<>());
    }

    public synchronized void open() {
        FROZEN.set(registry, false);
        clearCache();
    }

    public synchronized <V extends T> V register(ResourceKey<T> id, V entry) {
        return register(id, entry, -1, Lifecycle.stable());
    }

    private <V extends T> V register(ResourceKey<T> key, V entry, int rawId, Lifecycle lifecycle) {
        if (isClosed()) open();
        if (rawId < 0) registry.register(key, entry, lifecycle);
        else registry.registerMapping(rawId, key, entry, lifecycle);
        return entry;
    }

    // inspired by Registry.registerOrOverride()
    public synchronized T unregister(ResourceKey<T> key) {
        if (isClosed()) open();
        if (key== null) return null;
        Optional<Holder<T>> toRemove = registry.getHolder(key);
        T t;
        if (toRemove.isPresent()) {
            t = toRemove.get().value();
            lifecycles.remove(t);
            toId.removeInt(t);
            byValue.remove(t);
        } else t = null;
        byKey.remove(key);
        return t;
    }

    // should (supposedly) replace the entry of the object at the key with a new entry without changing anything else, but does not work
    public synchronized T replace(ResourceKey<T> key, T entry) {
        if (isClosed()) open();
        int id = toId.getInt(key);
        T old = unregister(key);
        if (old != null) register(key, entry, id, Lifecycle.stable());
        else register(key, entry);
        return old;
    }

    public synchronized boolean isClosed() {
        return !FROZEN.get(registry);
    }

Any uppercase variables are reflection fields, all fields are the objects within the MappedRegistry class pulled and cached.
 
Last edited:

Machine Maker

Paper Developer
Staff member
Dec 17, 2021
132
6
19
18
California
Your method which attempts to work around ResourceKey using reference equality is not needed. When you call ResourceKey.create() it will return the already existing instance if it's for the same registry and value. All created ResourceKeys are interned and cached so that you can use reference equality and know they are the same.
 

Vizzoid

New member
Jan 23, 2022
12
0
1
Thank you, I've edited the post, but unfortunately the item still does not drop and still sometimes disappear when I click on it. I'm still unsure what is the problem because, from the looks of it, it uses the same key and id as the old item, and I've even added another part that updates CraftMagicNumbers as well, but it still fails.

EDIT: The item is still invisible, but it functions normally. I was testing it and the server recognizes that it isn't air and is able to read the PersistentDataContainer, which means everything server-side seems to work. Now I'm trying to find out why the client does not recognize it.
 

Machine Maker

Paper Developer
Staff member
Dec 17, 2021
132
6
19
18
California
Your best bet is going to be to clone the server source, and run a debugger on the server with your plugin. That way you can look at each step of the logic and figure out where things are going wrong. Check out CONTRIBUTING.md on the Paper repo for instructions on how to clone and build the source.
 

Vizzoid

New member
Jan 23, 2022
12
0
1
I'm sorry, I am having some difficulties.
I've cloned the repository and made the changes needed, how to rebuild it to a runnable server?
 

Machine Maker

Paper Developer
Staff member
Dec 17, 2021
132
6
19
18
California
You can run ./gradlew createReobfPaperclipJar to get a jar equivalent to one downloaded from the paper downloads site.