mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 02:20:57 +00:00
fix registry overwrite issue
This commit is contained in:
@@ -82,22 +82,18 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
|
||||
private final BiomeProviderBuilder biomeProviderBuilder;
|
||||
|
||||
private final Map<Class<?>, ImmutablePair<OpenRegistry<?>, CheckedRegistry<?>>> registryMap = new HashMap<>();
|
||||
|
||||
private final ConfigTypeRegistry configTypeRegistry;
|
||||
private final Map<Class<?>, ImmutablePair<OpenRegistry<?>, CheckedRegistry<?>>> registryMap = new HashMap<>();
|
||||
|
||||
|
||||
private final TreeMap<Integer, List<ImmutablePair<String, ConfigType<?, ?>>>> configTypes = new TreeMap<>();
|
||||
|
||||
public ConfigPackImpl(File folder, TerraPlugin main) throws ConfigException {
|
||||
try {
|
||||
this.configTypeRegistry = new ConfigTypeRegistry(main, (id, configType) -> {
|
||||
OpenRegistry<?> openRegistry = configType.registrySupplier().get();
|
||||
selfLoader.registerLoader(configType.getTypeClass(), openRegistry);
|
||||
abstractConfigLoader.registerLoader(configType.getTypeClass(), openRegistry);
|
||||
registryMap.put(configType.getTypeClass(), ImmutablePair.of(openRegistry, new CheckedRegistryImpl<>(openRegistry)));
|
||||
});
|
||||
this.loader = new FolderLoader(folder.toPath());
|
||||
this.main = main;
|
||||
this.configTypeRegistry = createRegistry();
|
||||
long l = System.nanoTime();
|
||||
|
||||
register(abstractConfigLoader);
|
||||
@@ -139,14 +135,9 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
|
||||
public ConfigPackImpl(ZipFile file, TerraPlugin main) throws ConfigException {
|
||||
try {
|
||||
this.configTypeRegistry = new ConfigTypeRegistry(main, (id, configType) -> {
|
||||
OpenRegistry<?> openRegistry = configType.registrySupplier().get();
|
||||
selfLoader.registerLoader(configType.getTypeClass(), openRegistry);
|
||||
abstractConfigLoader.registerLoader(configType.getTypeClass(), openRegistry);
|
||||
registryMap.put(configType.getTypeClass(), ImmutablePair.of(openRegistry, new CheckedRegistryImpl<>(openRegistry)));
|
||||
});
|
||||
this.loader = new ZIPLoader(file);
|
||||
this.main = main;
|
||||
this.configTypeRegistry = createRegistry();
|
||||
long l = System.nanoTime();
|
||||
|
||||
register(selfLoader);
|
||||
@@ -196,6 +187,19 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
toWorldConfig(new TerraWorldImpl(new DummyWorld(), this, main)); // Build now to catch any errors immediately.
|
||||
}
|
||||
|
||||
private ConfigTypeRegistry createRegistry() {
|
||||
return new ConfigTypeRegistry(main, (id, configType) -> {
|
||||
OpenRegistry<?> openRegistry = configType.registrySupplier().get();
|
||||
if(registryMap.containsKey(configType.getTypeClass())) { // Someone already registered something; we need to copy things to the new registry.
|
||||
//noinspection unchecked
|
||||
registryMap.get(configType.getTypeClass()).getLeft().forEach(((OpenRegistry<Object>) openRegistry)::register);
|
||||
}
|
||||
selfLoader.registerLoader(configType.getTypeClass(), openRegistry);
|
||||
abstractConfigLoader.registerLoader(configType.getTypeClass(), openRegistry);
|
||||
registryMap.put(configType.getTypeClass(), ImmutablePair.of(openRegistry, new CheckedRegistryImpl<>(openRegistry)));
|
||||
});
|
||||
}
|
||||
|
||||
private void checkDeadEntries(TerraPlugin main) {
|
||||
registryMap.forEach((clazz, pair) -> ((OpenRegistryImpl<?>) pair.getLeft()).getDeadEntries().forEach((id, value) -> main.getDebugLogger().warning("Dead entry in '" + clazz + "' registry: '" + id + "'")));
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import com.dfsek.terra.api.registry.OpenRegistry;
|
||||
import com.dfsek.terra.api.registry.exception.DuplicateEntryException;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -47,10 +46,10 @@ public class OpenRegistryImpl<T> implements OpenRegistry<T> {
|
||||
|
||||
@Override
|
||||
public boolean register(String identifier, T value) {
|
||||
return add(identifier, new Entry<>(value));
|
||||
return register(identifier, new Entry<>(value));
|
||||
}
|
||||
|
||||
public boolean add(String identifier, Entry<T> value) {
|
||||
public boolean register(String identifier, Entry<T> value) {
|
||||
boolean exists = objects.containsKey(identifier);
|
||||
objects.put(identifier, value);
|
||||
return exists;
|
||||
|
||||
@@ -19,9 +19,9 @@ public class ConfigTypeRegistry extends OpenRegistryImpl<ConfigType<?, ?>> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(String identifier, Entry<ConfigType<?, ?>> value) {
|
||||
public boolean register(String identifier, Entry<ConfigType<?, ?>> value) {
|
||||
callback.accept(identifier, value.getValue());
|
||||
main.getDebugLogger().info("Registered config registry with ID " + identifier + " to class " + value.getValue().getTypeClass().getCanonicalName());
|
||||
return super.add(identifier, value);
|
||||
return super.register(identifier, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class AddonRegistry extends OpenRegistryImpl<TerraAddon> {
|
||||
public boolean register(String identifier, TerraAddon addon) {
|
||||
if(contains(identifier)) throw new IllegalArgumentException("Addon " + identifier + " is already registered.");
|
||||
addon.initialize();
|
||||
main.logger().info("Loaded com.dfsek.terra.addon " + addon.getName() + " v" + addon.getVersion() + ", by " + addon.getAuthor());
|
||||
main.logger().info("Loaded addon " + addon.getName() + " v" + addon.getVersion() + ", by " + addon.getAuthor());
|
||||
return super.register(identifier, addon);
|
||||
}
|
||||
|
||||
@@ -44,6 +44,9 @@ public class AddonRegistry extends OpenRegistryImpl<TerraAddon> {
|
||||
}
|
||||
|
||||
public boolean loadAll() {
|
||||
return loadAll(TerraPlugin.class.getClassLoader());
|
||||
}
|
||||
public boolean loadAll(ClassLoader parent) {
|
||||
InjectorImpl<TerraPlugin> pluginInjector = new InjectorImpl<>(main);
|
||||
pluginInjector.addExplicitTarget(TerraPlugin.class);
|
||||
|
||||
@@ -56,7 +59,7 @@ public class AddonRegistry extends OpenRegistryImpl<TerraAddon> {
|
||||
try {
|
||||
for(File jar : addonsFolder.listFiles(file -> file.getName().endsWith(".jar"))) {
|
||||
main.logger().info("Loading Addon(s) from: " + jar.getName());
|
||||
for(Class<? extends TerraAddon> addonClass : AddonClassLoader.fetchAddonClasses(jar)) {
|
||||
for(Class<? extends TerraAddon> addonClass : AddonClassLoader.fetchAddonClasses(jar, parent)) {
|
||||
pool.add(new PreLoadAddon(addonClass, jar));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,35 +27,36 @@ public class AddonClassLoader extends URLClassLoader {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Set<Class<? extends TerraAddon>> fetchAddonClasses(File file) throws IOException {
|
||||
public static Set<Class<? extends TerraAddon>> fetchAddonClasses(File file, ClassLoader parent) throws IOException {
|
||||
JarFile jarFile = new JarFile(file);
|
||||
Enumeration<JarEntry> entries = jarFile.entries();
|
||||
|
||||
AddonClassLoader loader = new AddonClassLoader(new URL[] {file.toURI().toURL()}, AddonClassLoader.class.getClassLoader());
|
||||
try(AddonClassLoader loader = new AddonClassLoader(new URL[] {file.toURI().toURL()}, parent)) {
|
||||
|
||||
Set<Class<? extends TerraAddon>> set = new HashSet<>();
|
||||
while(entries.hasMoreElements()) {
|
||||
JarEntry entry = entries.nextElement();
|
||||
Set<Class<? extends TerraAddon>> set = new HashSet<>();
|
||||
while(entries.hasMoreElements()) {
|
||||
JarEntry entry = entries.nextElement();
|
||||
|
||||
if(entry.isDirectory() || !entry.getName().endsWith(".class")) continue;
|
||||
String className = entry.getName().substring(0, entry.getName().length() - 6).replace('/', '.');
|
||||
if(entry.isDirectory() || !entry.getName().endsWith(".class")) continue;
|
||||
String className = entry.getName().substring(0, entry.getName().length() - 6).replace('/', '.');
|
||||
|
||||
try {
|
||||
Class<?> clazz = loader.loadClass(className);
|
||||
try {
|
||||
Class<?> clazz = loader.loadClass(className);
|
||||
|
||||
Addon addon = clazz.getAnnotation(Addon.class);
|
||||
Addon addon = clazz.getAnnotation(Addon.class);
|
||||
|
||||
if(addon == null) continue;
|
||||
if(addon == null) continue;
|
||||
|
||||
if(!TerraAddon.class.isAssignableFrom(clazz))
|
||||
throw new IllegalArgumentException("Addon class \"" + clazz + "\" must extend TerraAddon.");
|
||||
if(!TerraAddon.class.isAssignableFrom(clazz))
|
||||
throw new IllegalArgumentException("Addon class \"" + clazz + "\" must extend TerraAddon.");
|
||||
|
||||
set.add((Class<? extends TerraAddon>) clazz);
|
||||
} catch(ClassNotFoundException e) {
|
||||
throw new IllegalStateException(e); // this should literally never happen, if it does something is very wrong
|
||||
set.add((Class<? extends TerraAddon>) clazz);
|
||||
} catch(ClassNotFoundException e) {
|
||||
throw new IllegalStateException(e); // this should literally never happen, if it does something is very wrong
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return set;
|
||||
return set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class PreLoadAddon {
|
||||
|
||||
public void rebuildDependencies(AddonPool pool, PreLoadAddon origin, boolean levelG1) throws AddonLoadException {
|
||||
if(this.equals(origin) && !levelG1)
|
||||
throw new CircularDependencyException("Detected circular dependency in com.dfsek.terra.addon \"" + id + "\", dependencies: " + Arrays.toString(dependencies));
|
||||
throw new CircularDependencyException("Detected circular dependency in addon \"" + id + "\", dependencies: " + Arrays.toString(dependencies));
|
||||
|
||||
for(String dependency : dependencies) {
|
||||
PreLoadAddon preLoadAddon = pool.get(dependency);
|
||||
|
||||
@@ -260,7 +260,7 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
||||
debugLogger.setDebug(config.isDebugLogging());
|
||||
if(config.isDebugProfiler()) profiler.start();
|
||||
|
||||
if(!addonRegistry.loadAll()) {
|
||||
if(!addonRegistry.loadAll(getClass().getClassLoader())) {
|
||||
throw new IllegalStateException("Failed to load addons. Please correct com.dfsek.terra.addon installations to continue.");
|
||||
}
|
||||
logger.info("Loaded addons.");
|
||||
@@ -317,10 +317,10 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
||||
eventManager.registerListener(this, this);
|
||||
}
|
||||
|
||||
@Priority(Priority.LOWEST)
|
||||
@Priority(Priority.HIGHEST)
|
||||
@Global
|
||||
public void injectTrees(ConfigPackPreLoadEvent event) {
|
||||
CheckedRegistry<Tree> treeRegistry = event.getPack().getCheckedRegistry(Tree.class);
|
||||
CheckedRegistry<Tree> treeRegistry = event.getPack().getOrCreateRegistry(Tree.class);
|
||||
injectTree(treeRegistry, "BROWN_MUSHROOM", ConfiguredFeatures.HUGE_BROWN_MUSHROOM);
|
||||
injectTree(treeRegistry, "RED_MUSHROOM", ConfiguredFeatures.HUGE_RED_MUSHROOM);
|
||||
injectTree(treeRegistry, "JUNGLE", ConfiguredFeatures.MEGA_JUNGLE_TREE);
|
||||
|
||||
Reference in New Issue
Block a user