mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-06-16 22:01:07 +00:00
fix registry overwrite issue
This commit is contained in:
+17
-13
@@ -82,22 +82,18 @@ public class ConfigPackImpl implements ConfigPack {
|
|||||||
|
|
||||||
private final BiomeProviderBuilder biomeProviderBuilder;
|
private final BiomeProviderBuilder biomeProviderBuilder;
|
||||||
|
|
||||||
|
private final Map<Class<?>, ImmutablePair<OpenRegistry<?>, CheckedRegistry<?>>> registryMap = new HashMap<>();
|
||||||
|
|
||||||
private final ConfigTypeRegistry configTypeRegistry;
|
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<>();
|
private final TreeMap<Integer, List<ImmutablePair<String, ConfigType<?, ?>>>> configTypes = new TreeMap<>();
|
||||||
|
|
||||||
public ConfigPackImpl(File folder, TerraPlugin main) throws ConfigException {
|
public ConfigPackImpl(File folder, TerraPlugin main) throws ConfigException {
|
||||||
try {
|
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.loader = new FolderLoader(folder.toPath());
|
||||||
this.main = main;
|
this.main = main;
|
||||||
|
this.configTypeRegistry = createRegistry();
|
||||||
long l = System.nanoTime();
|
long l = System.nanoTime();
|
||||||
|
|
||||||
register(abstractConfigLoader);
|
register(abstractConfigLoader);
|
||||||
@@ -139,14 +135,9 @@ public class ConfigPackImpl implements ConfigPack {
|
|||||||
|
|
||||||
public ConfigPackImpl(ZipFile file, TerraPlugin main) throws ConfigException {
|
public ConfigPackImpl(ZipFile file, TerraPlugin main) throws ConfigException {
|
||||||
try {
|
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.loader = new ZIPLoader(file);
|
||||||
this.main = main;
|
this.main = main;
|
||||||
|
this.configTypeRegistry = createRegistry();
|
||||||
long l = System.nanoTime();
|
long l = System.nanoTime();
|
||||||
|
|
||||||
register(selfLoader);
|
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.
|
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) {
|
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 + "'")));
|
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 com.dfsek.terra.api.registry.exception.DuplicateEntryException;
|
||||||
|
|
||||||
import java.lang.reflect.AnnotatedType;
|
import java.lang.reflect.AnnotatedType;
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -47,10 +46,10 @@ public class OpenRegistryImpl<T> implements OpenRegistry<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean register(String identifier, T value) {
|
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);
|
boolean exists = objects.containsKey(identifier);
|
||||||
objects.put(identifier, value);
|
objects.put(identifier, value);
|
||||||
return exists;
|
return exists;
|
||||||
|
|||||||
+2
-2
@@ -19,9 +19,9 @@ public class ConfigTypeRegistry extends OpenRegistryImpl<ConfigType<?, ?>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean add(String identifier, Entry<ConfigType<?, ?>> value) {
|
public boolean register(String identifier, Entry<ConfigType<?, ?>> value) {
|
||||||
callback.accept(identifier, value.getValue());
|
callback.accept(identifier, value.getValue());
|
||||||
main.getDebugLogger().info("Registered config registry with ID " + identifier + " to class " + value.getValue().getTypeClass().getCanonicalName());
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -34,7 +34,7 @@ public class AddonRegistry extends OpenRegistryImpl<TerraAddon> {
|
|||||||
public boolean register(String identifier, TerraAddon addon) {
|
public boolean register(String identifier, TerraAddon addon) {
|
||||||
if(contains(identifier)) throw new IllegalArgumentException("Addon " + identifier + " is already registered.");
|
if(contains(identifier)) throw new IllegalArgumentException("Addon " + identifier + " is already registered.");
|
||||||
addon.initialize();
|
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);
|
return super.register(identifier, addon);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,6 +44,9 @@ public class AddonRegistry extends OpenRegistryImpl<TerraAddon> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean loadAll() {
|
public boolean loadAll() {
|
||||||
|
return loadAll(TerraPlugin.class.getClassLoader());
|
||||||
|
}
|
||||||
|
public boolean loadAll(ClassLoader parent) {
|
||||||
InjectorImpl<TerraPlugin> pluginInjector = new InjectorImpl<>(main);
|
InjectorImpl<TerraPlugin> pluginInjector = new InjectorImpl<>(main);
|
||||||
pluginInjector.addExplicitTarget(TerraPlugin.class);
|
pluginInjector.addExplicitTarget(TerraPlugin.class);
|
||||||
|
|
||||||
@@ -56,7 +59,7 @@ public class AddonRegistry extends OpenRegistryImpl<TerraAddon> {
|
|||||||
try {
|
try {
|
||||||
for(File jar : addonsFolder.listFiles(file -> file.getName().endsWith(".jar"))) {
|
for(File jar : addonsFolder.listFiles(file -> file.getName().endsWith(".jar"))) {
|
||||||
main.logger().info("Loading Addon(s) from: " + jar.getName());
|
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));
|
pool.add(new PreLoadAddon(addonClass, jar));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,35 +27,36 @@ public class AddonClassLoader extends URLClassLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@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);
|
JarFile jarFile = new JarFile(file);
|
||||||
Enumeration<JarEntry> entries = jarFile.entries();
|
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<>();
|
Set<Class<? extends TerraAddon>> set = new HashSet<>();
|
||||||
while(entries.hasMoreElements()) {
|
while(entries.hasMoreElements()) {
|
||||||
JarEntry entry = entries.nextElement();
|
JarEntry entry = entries.nextElement();
|
||||||
|
|
||||||
if(entry.isDirectory() || !entry.getName().endsWith(".class")) continue;
|
if(entry.isDirectory() || !entry.getName().endsWith(".class")) continue;
|
||||||
String className = entry.getName().substring(0, entry.getName().length() - 6).replace('/', '.');
|
String className = entry.getName().substring(0, entry.getName().length() - 6).replace('/', '.');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Class<?> clazz = loader.loadClass(className);
|
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))
|
if(!TerraAddon.class.isAssignableFrom(clazz))
|
||||||
throw new IllegalArgumentException("Addon class \"" + clazz + "\" must extend TerraAddon.");
|
throw new IllegalArgumentException("Addon class \"" + clazz + "\" must extend TerraAddon.");
|
||||||
|
|
||||||
set.add((Class<? extends TerraAddon>) clazz);
|
set.add((Class<? extends TerraAddon>) clazz);
|
||||||
} catch(ClassNotFoundException e) {
|
} catch(ClassNotFoundException e) {
|
||||||
throw new IllegalStateException(e); // this should literally never happen, if it does something is very wrong
|
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 {
|
public void rebuildDependencies(AddonPool pool, PreLoadAddon origin, boolean levelG1) throws AddonLoadException {
|
||||||
if(this.equals(origin) && !levelG1)
|
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) {
|
for(String dependency : dependencies) {
|
||||||
PreLoadAddon preLoadAddon = pool.get(dependency);
|
PreLoadAddon preLoadAddon = pool.get(dependency);
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
|||||||
debugLogger.setDebug(config.isDebugLogging());
|
debugLogger.setDebug(config.isDebugLogging());
|
||||||
if(config.isDebugProfiler()) profiler.start();
|
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.");
|
throw new IllegalStateException("Failed to load addons. Please correct com.dfsek.terra.addon installations to continue.");
|
||||||
}
|
}
|
||||||
logger.info("Loaded addons.");
|
logger.info("Loaded addons.");
|
||||||
@@ -317,10 +317,10 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
|
|||||||
eventManager.registerListener(this, this);
|
eventManager.registerListener(this, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Priority(Priority.LOWEST)
|
@Priority(Priority.HIGHEST)
|
||||||
@Global
|
@Global
|
||||||
public void injectTrees(ConfigPackPreLoadEvent event) {
|
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, "BROWN_MUSHROOM", ConfiguredFeatures.HUGE_BROWN_MUSHROOM);
|
||||||
injectTree(treeRegistry, "RED_MUSHROOM", ConfiguredFeatures.HUGE_RED_MUSHROOM);
|
injectTree(treeRegistry, "RED_MUSHROOM", ConfiguredFeatures.HUGE_RED_MUSHROOM);
|
||||||
injectTree(treeRegistry, "JUNGLE", ConfiguredFeatures.MEGA_JUNGLE_TREE);
|
injectTree(treeRegistry, "JUNGLE", ConfiguredFeatures.MEGA_JUNGLE_TREE);
|
||||||
|
|||||||
Reference in New Issue
Block a user