mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 08:17:35 +00:00
Created a CreativeModeTabEvent to register creative mode tabs and populate entries per tab Moved datapack registries to DataPackRegistryEvent.NewRegistry event instead of tying them to ForgeRegistry Made it easier for mods to datagen datapack builtin entries with DatapackBuiltinEntriesProvider Provided access to lookupProvider for datagen Updated dependencies to match versions used by vanilla and update JarJar to 0.3.18 Added a test mod for the new CreativeModeTabEvent Throws better error message for Forge registries in tag datagen Deleted ForgeRegistryTagsProvider Updated ClientChatReceivedEvent and ServerChatEvent for Mojang changes Added patches for both sign related methods in ModelLayers Changed RegisterShadersEvent to use ResourceProvider Migrated old Mojang math types to JOML Co-authored-by: Marc Hermans <marc.hermans@ldtteam.com> Co-authored-by: LexManos <LexManos@gmail.com> Co-authored-by: sciwhiz12 <arnoldnunag12@gmail.com> Co-authored-by: coehlrich <coehlrich@users.noreply.github.com>
217 lines
7.4 KiB
Java
217 lines
7.4 KiB
Java
/*
|
|
* Copyright (c) Forge Development LLC and contributors
|
|
* SPDX-License-Identifier: LGPL-2.1-only
|
|
*/
|
|
|
|
package net.minecraftforge.registries;
|
|
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.stream.Collectors;
|
|
|
|
import com.google.common.collect.BiMap;
|
|
import com.google.common.collect.HashBiMap;
|
|
import com.google.common.collect.Maps;
|
|
import com.google.common.collect.Sets;
|
|
|
|
import com.mojang.serialization.Lifecycle;
|
|
import net.minecraft.core.WritableRegistry;
|
|
import net.minecraft.core.registries.BuiltInRegistries;
|
|
import net.minecraft.resources.ResourceKey;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.core.Registry;
|
|
import net.minecraftforge.fml.ModLoader;
|
|
import net.minecraftforge.fml.ModLoadingContext;
|
|
import net.minecraftforge.network.HandshakeMessages;
|
|
import net.minecraftforge.registries.ForgeRegistry.Snapshot;
|
|
import org.apache.commons.lang3.tuple.Pair;
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
public class RegistryManager
|
|
{
|
|
private static final Logger LOGGER = LogManager.getLogger();
|
|
public static final RegistryManager ACTIVE = new RegistryManager("ACTIVE");
|
|
public static final RegistryManager VANILLA = new RegistryManager("VANILLA");
|
|
public static final RegistryManager FROZEN = new RegistryManager("FROZEN");
|
|
private static Set<ResourceLocation> vanillaRegistryKeys = Set.of();
|
|
|
|
BiMap<ResourceLocation, ForgeRegistry<?>> registries = HashBiMap.create();
|
|
private Set<ResourceLocation> persisted = Sets.newHashSet();
|
|
private Set<ResourceLocation> synced = Sets.newHashSet();
|
|
private Map<ResourceLocation, ResourceLocation> legacyNames = new HashMap<>();
|
|
private final String name;
|
|
|
|
RegistryManager()
|
|
{
|
|
this("STAGING");
|
|
}
|
|
|
|
public RegistryManager(String name)
|
|
{
|
|
this.name = name;
|
|
}
|
|
|
|
public String getName()
|
|
{
|
|
return this.name;
|
|
}
|
|
|
|
boolean isStaging()
|
|
{
|
|
return "STAGING".equals(this.name);
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
public <V> ForgeRegistry<V> getRegistry(ResourceLocation key)
|
|
{
|
|
return (ForgeRegistry<V>)this.registries.get(key);
|
|
}
|
|
|
|
public <V> ForgeRegistry<V> getRegistry(ResourceKey<? extends Registry<V>> key)
|
|
{
|
|
return getRegistry(key.location());
|
|
}
|
|
|
|
public <V> ResourceLocation getName(IForgeRegistry<V> reg)
|
|
{
|
|
return this.registries.inverse().get(reg);
|
|
}
|
|
|
|
public <V> ResourceLocation updateLegacyName(ResourceLocation legacyName)
|
|
{
|
|
ResourceLocation originalName = legacyName;
|
|
while (getRegistry(legacyName) == null)
|
|
{
|
|
legacyName = legacyNames.get(legacyName);
|
|
if (legacyName == null)
|
|
{
|
|
return originalName;
|
|
}
|
|
}
|
|
return legacyName;
|
|
}
|
|
|
|
public <V> ForgeRegistry<V> getRegistry(ResourceLocation key, RegistryManager other)
|
|
{
|
|
if (!this.registries.containsKey(key))
|
|
{
|
|
ForgeRegistry<V> ot = other.getRegistry(key);
|
|
if (ot == null)
|
|
return null;
|
|
this.registries.put(key, ot.copy(this));
|
|
if (other.persisted.contains(key))
|
|
this.persisted.add(key);
|
|
if (other.synced.contains(key))
|
|
this.synced.add(key);
|
|
other.legacyNames.entrySet().stream()
|
|
.filter(e -> e.getValue().equals(key))
|
|
.forEach(e -> addLegacyName(e.getKey(), e.getValue()));
|
|
}
|
|
return getRegistry(key);
|
|
}
|
|
|
|
<V> ForgeRegistry<V> createRegistry(ResourceLocation name, RegistryBuilder<V> builder)
|
|
{
|
|
if (registries.containsKey(name))
|
|
throw new IllegalArgumentException("Attempted to register a registry for " + name + " but it already exists");
|
|
ForgeRegistry<V> reg = new ForgeRegistry<V>(this, name, builder);
|
|
registries.put(name, reg);
|
|
if (builder.getSaveToDisc())
|
|
this.persisted.add(name);
|
|
if (builder.getSync())
|
|
this.synced.add(name);
|
|
for (ResourceLocation legacyName : builder.getLegacyNames())
|
|
addLegacyName(legacyName, name);
|
|
return getRegistry(name);
|
|
}
|
|
|
|
static <V> void registerToRootRegistry(ForgeRegistry<V> forgeReg)
|
|
{
|
|
injectForgeRegistry(forgeReg, BuiltInRegistries.REGISTRY);
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
private static <V> void injectForgeRegistry(ForgeRegistry<V> forgeReg, Registry<? extends Registry<?>> rootRegistry)
|
|
{
|
|
WritableRegistry<Registry<V>> registry = (WritableRegistry<Registry<V>>) rootRegistry;
|
|
Registry<V> wrapper = forgeReg.getWrapper();
|
|
if (wrapper != null)
|
|
registry.register(forgeReg.getRegistryKey(), wrapper, Lifecycle.experimental());
|
|
}
|
|
|
|
public static void postNewRegistryEvent()
|
|
{
|
|
NewRegistryEvent event = new NewRegistryEvent();
|
|
DataPackRegistryEvent.NewRegistry dataPackEvent = new DataPackRegistryEvent.NewRegistry();
|
|
vanillaRegistryKeys = Set.copyOf(BuiltInRegistries.REGISTRY.keySet());
|
|
|
|
ModLoader.get().postEventWithWrapInModOrder(event, (mc, e) -> ModLoadingContext.get().setActiveContainer(mc), (mc, e) -> ModLoadingContext.get().setActiveContainer(null));
|
|
ModLoader.get().postEventWithWrapInModOrder(dataPackEvent, (mc, e) -> ModLoadingContext.get().setActiveContainer(mc), (mc, e) -> ModLoadingContext.get().setActiveContainer(null));
|
|
|
|
event.fill();
|
|
dataPackEvent.process();
|
|
}
|
|
|
|
private void addLegacyName(ResourceLocation legacyName, ResourceLocation name)
|
|
{
|
|
if (this.legacyNames.containsKey(legacyName))
|
|
{
|
|
throw new IllegalArgumentException("Legacy name conflict for registry " + name + ", upgrade path must be linear: " + legacyName);
|
|
}
|
|
this.legacyNames.put(legacyName, name);
|
|
}
|
|
|
|
private void findSuperTypes(Class<?> type, Set<Class<?>> types)
|
|
{
|
|
if (type == null || type == Object.class)
|
|
{
|
|
return;
|
|
}
|
|
types.add(type);
|
|
for (Class<?> interfac : type.getInterfaces())
|
|
{
|
|
findSuperTypes(interfac, types);
|
|
}
|
|
findSuperTypes(type.getSuperclass(), types);
|
|
}
|
|
|
|
public Map<ResourceLocation, Snapshot> takeSnapshot(boolean savingToDisc)
|
|
{
|
|
Map<ResourceLocation, Snapshot> ret = Maps.newHashMap();
|
|
Set<ResourceLocation> keys = savingToDisc ? this.persisted : this.synced;
|
|
keys.forEach(name -> ret.put(name, getRegistry(name).makeSnapshot()));
|
|
return ret;
|
|
}
|
|
|
|
//Public for testing only
|
|
public void clean()
|
|
{
|
|
this.persisted.clear();
|
|
this.synced.clear();
|
|
this.registries.clear();
|
|
}
|
|
|
|
public static List<Pair<String, HandshakeMessages.S2CRegistry>> generateRegistryPackets(boolean isLocal)
|
|
{
|
|
return !isLocal ? ACTIVE.takeSnapshot(false).entrySet().stream().
|
|
map(e->Pair.of("Registry " + e.getKey(), new HandshakeMessages.S2CRegistry(e.getKey(), e.getValue()))).
|
|
collect(Collectors.toList()) : Collections.emptyList();
|
|
}
|
|
|
|
public static List<ResourceLocation> getRegistryNamesForSyncToClient()
|
|
{
|
|
return ACTIVE.registries.keySet().stream().
|
|
filter(resloc -> ACTIVE.synced.contains(resloc)).
|
|
collect(Collectors.toList());
|
|
}
|
|
|
|
public static Set<ResourceLocation> getVanillaRegistryKeys()
|
|
{
|
|
return vanillaRegistryKeys;
|
|
}
|
|
}
|