mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-04-04 23:06:05 +00:00
Fabric/Quilt fertilization support
This commit is contained in:
@@ -29,16 +29,18 @@ object Versions {
|
||||
|
||||
object Mod {
|
||||
const val mixin = "0.11.2+mixin.0.8.5"
|
||||
|
||||
|
||||
const val minecraft = "1.19"
|
||||
const val yarn = "$minecraft+build.1"
|
||||
const val fabricLoader = "0.14.2"
|
||||
|
||||
|
||||
const val minecraftGudAsm = "v0.3.1"
|
||||
|
||||
const val architecuryLoom = "0.12.0.290"
|
||||
const val architecturyPlugin = "3.4-SNAPSHOT"
|
||||
|
||||
|
||||
const val loomQuiltflower = "1.7.1"
|
||||
|
||||
|
||||
const val lazyDfu = "0.1.2"
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.dfsek.terra.bukkit.nms.v1_19_R1.config;
|
||||
import com.dfsek.tectonic.api.config.template.ConfigTemplate;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import java.util.List;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.Music;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
@@ -15,6 +14,9 @@ import net.minecraft.world.level.biome.Biome.Precipitation;
|
||||
import net.minecraft.world.level.biome.Biome.TemperatureModifier;
|
||||
import net.minecraft.world.level.biome.BiomeSpecialEffects.GrassColorModifier;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.dfsek.terra.api.properties.Properties;
|
||||
|
||||
|
||||
|
||||
@@ -12,6 +12,12 @@ architectury {
|
||||
dependencies {
|
||||
shadedApi(project(":common:implementation:base"))
|
||||
|
||||
annotationProcessor("net.fabricmc:sponge-mixin:${Versions.Mod.mixin}")
|
||||
annotationProcessor("dev.architectury:architectury-loom:${Versions.Mod.architecuryLoom}")
|
||||
|
||||
modImplementation("com.github.the-glitch-network:minecraft-gudasm:${Versions.Mod.minecraftGudAsm}")
|
||||
include("com.github.the-glitch-network:minecraft-gudasm:${Versions.Mod.minecraftGudAsm}")
|
||||
|
||||
implementation(project(path = ":platforms:mixin-common", configuration = "namedElements")) { isTransitive = false }
|
||||
"developmentFabric"(project(path = ":platforms:mixin-common", configuration = "namedElements")) { isTransitive = false }
|
||||
shaded(project(path = ":platforms:mixin-common", configuration = "transformProductionFabric")) { isTransitive = false }
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.dfsek.terra.fabric;
|
||||
|
||||
import com.dfsek.terra.fabric.util.FabricLoaderUtil;
|
||||
|
||||
import net.gudenau.minecraft.asm.api.v1.AsmInitializer;
|
||||
import net.gudenau.minecraft.asm.api.v1.AsmRegistry;
|
||||
|
||||
import com.dfsek.terra.lifecycle.asm.FertilizableASM;
|
||||
import com.dfsek.terra.lifecycle.util.LoaderUtil;
|
||||
import com.dfsek.terra.quilt.util.QuiltLoaderUtil;
|
||||
|
||||
|
||||
public class FabricASMEntryPoint implements AsmInitializer {
|
||||
@Override
|
||||
public void onInitializeAsm() {
|
||||
LoaderUtil.INSTANCE = new FabricLoaderUtil();
|
||||
AsmRegistry.getInstance().registerTransformer(new FertilizableASM());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.dfsek.terra.fabric.util;
|
||||
|
||||
import com.dfsek.terra.lifecycle.util.LoaderUtil;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
|
||||
public class FabricLoaderUtil extends LoaderUtil {
|
||||
@Override
|
||||
public String mapClassName(String namespace, String className) {
|
||||
return FabricLoader.getInstance().getMappingResolver().mapClassName(namespace, className);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapMethodName(String namespace, String owner, String name, String descriptor) {
|
||||
return FabricLoader.getInstance().getMappingResolver().mapMethodName(namespace, owner, name, descriptor);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,9 @@
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"com.dfsek.terra.fabric.FabricEntryPoint"
|
||||
],
|
||||
"gud_asm": [
|
||||
"com.dfsek.terra.fabric.FabricASMEntryPoint"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
|
||||
@@ -15,44 +15,52 @@ import net.minecraft.world.biome.BiomeEffects.GrassColorModifier;
|
||||
import net.minecraft.world.biome.BiomeParticleConfig;
|
||||
import net.minecraft.world.biome.SpawnSettings;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.properties.Properties;
|
||||
import com.dfsek.terra.api.structure.configured.ConfiguredStructure;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
|
||||
public class VanillaBiomeProperties implements ConfigTemplate, Properties {
|
||||
|
||||
@Value("minecraft.fertilizables")
|
||||
@Default
|
||||
private Map<Identifier, ProbabilityCollection<ConfiguredStructure>> fertilizables = Collections.emptyMap();
|
||||
|
||||
@Value("minecraft.tags")
|
||||
@Default
|
||||
private List<Identifier> tags = null;
|
||||
private List<Identifier> tags = Collections.emptyList();
|
||||
|
||||
@Value("minecraft.colors.grass")
|
||||
@Default
|
||||
private Integer grassColor = null;
|
||||
private Integer grassColor = 0;
|
||||
|
||||
@Value("minecraft.colors.fog")
|
||||
@Default
|
||||
private Integer fogColor = null;
|
||||
private Integer fogColor = 0;
|
||||
|
||||
@Value("minecraft.colors.water")
|
||||
@Default
|
||||
private Integer waterColor = null;
|
||||
private Integer waterColor = 0;
|
||||
|
||||
@Value("minecraft.colors.water-fog")
|
||||
@Default
|
||||
private Integer waterFogColor = null;
|
||||
private Integer waterFogColor = 0;
|
||||
|
||||
@Value("minecraft.colors.foliage")
|
||||
@Default
|
||||
private Integer foliageColor = null;
|
||||
private Integer foliageColor = 0;
|
||||
|
||||
@Value("minecraft.colors.sky")
|
||||
@Default
|
||||
private Integer skyColor = null;
|
||||
private Integer skyColor = 0;
|
||||
|
||||
@Value("minecraft.colors.modifier")
|
||||
@Default
|
||||
private GrassColorModifier grassColorModifier = null;
|
||||
private GrassColorModifier grassColorModifier = GrassColorModifier.NONE;
|
||||
|
||||
@Value("minecraft.particles")
|
||||
@Default
|
||||
@@ -60,19 +68,19 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
|
||||
|
||||
@Value("minecraft.climate.precipitation")
|
||||
@Default
|
||||
private Precipitation precipitation = null;
|
||||
private Precipitation precipitation = Precipitation.NONE;
|
||||
|
||||
@Value("minecraft.climate.temperature")
|
||||
@Default
|
||||
private Float temperature = null;
|
||||
private Float temperature = 0.0f;
|
||||
|
||||
@Value("minecraft.climate.temperature-modifier")
|
||||
@Default
|
||||
private TemperatureModifier temperatureModifier = null;
|
||||
private TemperatureModifier temperatureModifier = TemperatureModifier.NONE;
|
||||
|
||||
@Value("minecraft.climate.downfall")
|
||||
@Default
|
||||
private Float downfall = null;
|
||||
private Float downfall = 0.0f;
|
||||
|
||||
@Value("minecraft.sound.loop-sound.sound")
|
||||
@Default
|
||||
@@ -92,12 +100,16 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
|
||||
|
||||
@Value("minecraft.spawning")
|
||||
@Default
|
||||
private SpawnSettings spawnSettings = null;
|
||||
private SpawnSettings spawnSettings = SpawnSettings.INSTANCE;
|
||||
|
||||
@Value("minecraft.villager-type")
|
||||
@Default
|
||||
private VillagerType villagerType = null;
|
||||
|
||||
public Map<Identifier, ProbabilityCollection<ConfiguredStructure>> getFertilizables() {
|
||||
return fertilizables;
|
||||
}
|
||||
|
||||
public List<Identifier> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.dfsek.terra.mod.mixin;
|
||||
|
||||
import net.minecraft.block.Fertilizable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
|
||||
@Mixin(Fertilizable.class)
|
||||
public class FertilizableMixin {
|
||||
|
||||
}
|
||||
@@ -4,16 +4,21 @@ import net.minecraft.tag.TagKey;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryEntry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.village.VillagerType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.structure.configured.ConfiguredStructure;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.mod.CommonPlatform;
|
||||
import com.dfsek.terra.mod.config.ProtoPlatformBiome;
|
||||
@@ -24,6 +29,12 @@ import com.dfsek.terra.mod.mixin.access.VillagerTypeAccessor;
|
||||
public class BiomeUtil {
|
||||
private static final Logger logger = LoggerFactory.getLogger(BiomeUtil.class);
|
||||
|
||||
public static final Map<RegistryEntry<net.minecraft.world.biome.Biome>, Map<Identifier, ProbabilityCollection<ConfiguredStructure>>>
|
||||
TERRA_BIOME_FERTILIZABLE_MAP = new HashMap<>();
|
||||
|
||||
public static final Map<TagKey<net.minecraft.world.biome.Biome>, List<Identifier>>
|
||||
TERRA_BIOME_TAG_MAP = new HashMap<>();
|
||||
|
||||
public static void registerBiomes() {
|
||||
logger.info("Registering biomes...");
|
||||
CommonPlatform.get().getConfigRegistry().forEach(pack -> { // Register all Terra biomes.
|
||||
@@ -55,20 +66,22 @@ public class BiomeUtil {
|
||||
protected static void registerBiome(Biome biome, ConfigPack pack,
|
||||
com.dfsek.terra.api.registry.key.RegistryKey id) {
|
||||
VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);
|
||||
|
||||
|
||||
net.minecraft.world.biome.Biome minecraftBiome = MinecraftUtil.createBiome(vanillaBiomeProperties);
|
||||
|
||||
|
||||
Identifier identifier = new Identifier("terra", MinecraftUtil.createBiomeID(pack, id));
|
||||
|
||||
|
||||
biome.setPlatformBiome(new ProtoPlatformBiome(identifier, registerBiome(identifier, minecraftBiome)));
|
||||
|
||||
|
||||
Map villagerMap = VillagerTypeAccessor.getBiomeTypeToIdMap();
|
||||
|
||||
|
||||
villagerMap.put(RegistryKey.of(Registry.BIOME_KEY, identifier),
|
||||
Objects.requireNonNullElse(vanillaBiomeProperties.getVillagerType(), VillagerType.PLAINS));
|
||||
|
||||
|
||||
TERRA_BIOME_FERTILIZABLE_MAP.put(RegistryEntry.of(minecraftBiome), vanillaBiomeProperties.getFertilizables());
|
||||
|
||||
for(Identifier tag : vanillaBiomeProperties.getTags()) {
|
||||
MinecraftUtil.TERRA_BIOME_TAG_MAP.getOrDefault(TagKey.of(Registry.BIOME_KEY, tag), new ArrayList<>()).add(identifier);
|
||||
TERRA_BIOME_TAG_MAP.getOrDefault(TagKey.of(Registry.BIOME_KEY, tag), new ArrayList<>()).add(identifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.dfsek.terra.mod.util;
|
||||
|
||||
import com.dfsek.terra.api.util.Rotation;
|
||||
import com.dfsek.terra.api.util.vector.Vector3Int;
|
||||
|
||||
import com.dfsek.terra.api.world.WritableWorld;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.structure.configured.ConfiguredStructure;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
|
||||
public class FertilizableUtil {
|
||||
public static boolean grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
|
||||
Map<Identifier, ProbabilityCollection<ConfiguredStructure>> fertilizables = BiomeUtil.TERRA_BIOME_FERTILIZABLE_MAP.get(world.getBiome(pos));
|
||||
if (fertilizables != null) {
|
||||
ProbabilityCollection<ConfiguredStructure> probabilityCollection = fertilizables.get(Registry.BLOCK.getId(state.getBlock()));
|
||||
if (probabilityCollection != null) {
|
||||
ConfiguredStructure structure = probabilityCollection.get((java.util.Random) random);
|
||||
structure.getStructure().get((java.util.Random) random).generate(Vector3Int.of(pos.getX(), pos.getY(), pos.getZ()), (WritableWorld) world, (java.util.Random) random, Rotation.NONE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package com.dfsek.terra.mod.util;
|
||||
import net.minecraft.block.entity.LootableContainerBlockEntity;
|
||||
import net.minecraft.block.entity.MobSpawnerBlockEntity;
|
||||
import net.minecraft.block.entity.SignBlockEntity;
|
||||
import net.minecraft.tag.TagKey;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
@@ -17,10 +16,7 @@ import net.minecraft.world.biome.GenerationSettings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -35,8 +31,6 @@ import com.dfsek.terra.mod.config.VanillaBiomeProperties;
|
||||
public final class MinecraftUtil {
|
||||
public static final Logger logger = LoggerFactory.getLogger(MinecraftUtil.class);
|
||||
|
||||
public static final Map<TagKey<Biome>, List<Identifier>>
|
||||
TERRA_BIOME_TAG_MAP = new HashMap<>();
|
||||
|
||||
private MinecraftUtil() {
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ public final class TagUtil {
|
||||
logger.info("who let this data drive?");
|
||||
Map<TagKey<Biome>, List<RegistryEntry<Biome>>> collect = tagsToMutableMap(registry);
|
||||
|
||||
MinecraftUtil.TERRA_BIOME_TAG_MAP.forEach((tag, biomeList) -> {
|
||||
BiomeUtil.TERRA_BIOME_TAG_MAP.forEach((tag, biomeList) -> {
|
||||
collect.getOrDefault(tag, new ArrayList<>())
|
||||
.addAll(biomeList.stream()
|
||||
.map(registry::getOrEmpty)
|
||||
|
||||
@@ -11,6 +11,11 @@ dependencies {
|
||||
annotationProcessor("net.fabricmc:sponge-mixin:${Versions.Mod.mixin}")
|
||||
annotationProcessor("dev.architectury:architectury-loom:${Versions.Mod.architecuryLoom}")
|
||||
|
||||
modImplementation("com.github.the-glitch-network:minecraft-gudasm:${Versions.Mod.minecraftGudAsm}") {
|
||||
exclude("net.fabricmc")
|
||||
exclude("net.fabricmc.fabric-api")
|
||||
}
|
||||
|
||||
implementation(project(path = ":platforms:mixin-common", configuration = "namedElements")) { isTransitive = false }
|
||||
|
||||
minecraft("com.mojang:minecraft:${Versions.Mod.minecraft}")
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.dfsek.terra.lifecycle.asm;
|
||||
|
||||
import com.dfsek.terra.mod.util.FertilizableUtil;
|
||||
|
||||
import net.gudenau.minecraft.asm.api.v1.Identifier;
|
||||
import net.gudenau.minecraft.asm.api.v1.Transformer;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.InsnList;
|
||||
import org.objectweb.asm.tree.InsnNode;
|
||||
import org.objectweb.asm.tree.JumpInsnNode;
|
||||
import org.objectweb.asm.tree.LabelNode;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.dfsek.terra.lifecycle.util.ASMUtil;
|
||||
import com.dfsek.terra.lifecycle.util.LoaderUtil;
|
||||
|
||||
import org.objectweb.asm.tree.VarInsnNode;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.ACC_STATIC;
|
||||
|
||||
|
||||
public class FertilizableASM implements Transformer {
|
||||
|
||||
private static String fertilizableClassName = LoaderUtil.INSTANCE.mapClassName("intermediary", "net.minecraft.class_2256");
|
||||
|
||||
private static String fertilizableGrowMethodSignatureBase = String.format("(L%1$s;L%2$s;L%3$s;L%4$s;)",
|
||||
LoaderUtil.INSTANCE.mapClassName("intermediary", "net.minecraft.class_3218").replace(".", "/"),
|
||||
LoaderUtil.INSTANCE.mapClassName("intermediary", "net.minecraft.class_5819").replace(".", "/"),
|
||||
LoaderUtil.INSTANCE.mapClassName("intermediary", "net.minecraft.class_2338").replace(".", "/"),
|
||||
LoaderUtil.INSTANCE.mapClassName("intermediary", "net.minecraft.class_2680").replace(".", "/"));
|
||||
|
||||
private static String fertilizableGrowMethodSignature = fertilizableGrowMethodSignatureBase + "V";
|
||||
|
||||
private static String fertilizableGrowMethodName = LoaderUtil.INSTANCE.mapMethodName("intermediary", "net.minecraft.class_2256", "method_9652", "(Lnet/minecraft/class_3218;Lnet/minecraft/class_5819;Lnet/minecraft/class_2338;Lnet/minecraft/class_2680;)V");
|
||||
|
||||
@Override
|
||||
public Identifier getName() {
|
||||
return new Identifier("terra", "asm_test");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handlesClass(String name, String transformedName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transform(ClassNode classNode, Flags flags) {
|
||||
try {
|
||||
if (ASMUtil.inheritsFrom(classNode, fertilizableClassName.replace(".", "/"))) {
|
||||
for (MethodNode method : classNode.methods) {
|
||||
if (method.name.equals(fertilizableGrowMethodName)) {
|
||||
if ((method.access & ACC_STATIC) == 0) {
|
||||
if(method.desc.equals(fertilizableGrowMethodSignature)) {
|
||||
InsnList list = new InsnList();
|
||||
list.add(new VarInsnNode(Opcodes.ALOAD, 1));
|
||||
list.add(new VarInsnNode(Opcodes.ALOAD, 2));
|
||||
list.add(new VarInsnNode(Opcodes.ALOAD, 3));
|
||||
list.add(new VarInsnNode(Opcodes.ALOAD, 4));
|
||||
list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, FertilizableUtil.class.getName().replace(".", "/"), "grow", fertilizableGrowMethodSignatureBase + "Z", false));
|
||||
LabelNode jmp = new LabelNode();
|
||||
list.add(new JumpInsnNode(Opcodes.IFNE, jmp));
|
||||
list.add(new InsnNode(Opcodes.RETURN));
|
||||
list.add(jmp);
|
||||
method.instructions.insertBefore(method.instructions.getFirst(), list);
|
||||
flags.requestFrames();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.dfsek.terra.lifecycle.util;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import static org.objectweb.asm.ClassReader.SKIP_CODE;
|
||||
import static org.objectweb.asm.ClassReader.SKIP_DEBUG;
|
||||
import static org.objectweb.asm.ClassReader.SKIP_FRAMES;
|
||||
|
||||
|
||||
public class ASMUtil {
|
||||
static final ThreadLocal<WeakHashMap<String, WeakHashMap<String, Boolean>>> INHERITANCE_CACHE = new ThreadLocal<>();
|
||||
|
||||
public static boolean inheritsFrom(ClassNode classNode, String interfaceName) throws IOException {
|
||||
if (INHERITANCE_CACHE.get() == null) {
|
||||
INHERITANCE_CACHE.set(new WeakHashMap<>());
|
||||
}
|
||||
return inheritsFromInternal(classNode, interfaceName);
|
||||
}
|
||||
|
||||
protected static boolean inheritsFromInternal(ClassNode classNode, String interfaceName) throws IOException {
|
||||
if (INHERITANCE_CACHE.get().containsKey(classNode.name)) {
|
||||
if (INHERITANCE_CACHE.get().get(classNode.name).containsKey(interfaceName)) {
|
||||
return INHERITANCE_CACHE.get().get(classNode.name).get(interfaceName);
|
||||
}
|
||||
}
|
||||
for (String parent : classNode.interfaces) {
|
||||
if (checkClass(parent, interfaceName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (checkClass(classNode.superName, interfaceName)) {
|
||||
return true;
|
||||
}
|
||||
INHERITANCE_CACHE.get().getOrDefault(classNode.name, new WeakHashMap<>()).put(interfaceName, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static boolean checkClass(String name, String interfaceName) throws IOException {
|
||||
if (name.startsWith("java/")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isClass = name.equals(interfaceName);
|
||||
INHERITANCE_CACHE.get().getOrDefault(name, new WeakHashMap<>()).put(interfaceName, isClass);
|
||||
if (isClass) {
|
||||
return true;
|
||||
}
|
||||
ClassNode node = new ClassNode();
|
||||
new ClassReader(name).accept(node, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
|
||||
return inheritsFromInternal(node, interfaceName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.dfsek.terra.lifecycle.util;
|
||||
|
||||
public abstract class LoaderUtil {
|
||||
public static LoaderUtil INSTANCE;
|
||||
|
||||
public abstract String mapClassName(String namespace, String className);
|
||||
|
||||
public abstract String mapMethodName(String namespace, String owner, String name, String descriptor);
|
||||
}
|
||||
@@ -15,6 +15,14 @@ dependencies {
|
||||
annotationProcessor("net.fabricmc:sponge-mixin:${Versions.Mod.mixin}")
|
||||
annotationProcessor("dev.architectury:architectury-loom:${Versions.Mod.architecuryLoom}")
|
||||
|
||||
modImplementation("com.github.the-glitch-network:minecraft-gudasm:${Versions.Mod.minecraftGudAsm}") {
|
||||
exclude("net.fabricmc")
|
||||
exclude("net.fabricmc.fabric-api")
|
||||
}
|
||||
include("com.github.the-glitch-network:minecraft-gudasm:${Versions.Mod.minecraftGudAsm}") {
|
||||
exclude("net.fabricmc")
|
||||
exclude("net.fabricmc.fabric-api")
|
||||
}
|
||||
|
||||
implementation(project(path = ":platforms:mixin-common", configuration = "namedElements")) { isTransitive = false }
|
||||
"developmentQuilt"(project(path = ":platforms:mixin-common", configuration = "namedElements")) { isTransitive = false }
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.dfsek.terra.quilt;
|
||||
|
||||
import net.gudenau.minecraft.asm.api.v1.AsmInitializer;
|
||||
import net.gudenau.minecraft.asm.api.v1.AsmRegistry;
|
||||
|
||||
import com.dfsek.terra.lifecycle.asm.FertilizableASM;
|
||||
import com.dfsek.terra.lifecycle.util.LoaderUtil;
|
||||
import com.dfsek.terra.quilt.util.QuiltLoaderUtil;
|
||||
|
||||
|
||||
public class QuiltASMEntryPoint implements AsmInitializer {
|
||||
@Override
|
||||
public void onInitializeAsm() {
|
||||
LoaderUtil.INSTANCE = new QuiltLoaderUtil();
|
||||
AsmRegistry.getInstance().registerTransformer(new FertilizableASM());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.dfsek.terra.quilt.util;
|
||||
|
||||
import com.dfsek.terra.lifecycle.util.LoaderUtil;
|
||||
|
||||
import org.quiltmc.loader.api.QuiltLoader;
|
||||
|
||||
|
||||
public class QuiltLoaderUtil extends LoaderUtil {
|
||||
@Override
|
||||
public String mapClassName(String namespace, String className) {
|
||||
return QuiltLoader.getMappingResolver().mapClassName(namespace, className);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapMethodName(String namespace, String owner, String name, String descriptor) {
|
||||
return QuiltLoader.getMappingResolver().mapMethodName(namespace, owner, name, descriptor);
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,9 @@
|
||||
],
|
||||
"pre_launch": [
|
||||
"com.dfsek.terra.quilt.QuiltPreLaunchEntryPoint"
|
||||
],
|
||||
"gud_asm": [
|
||||
"com.dfsek.terra.quilt.QuiltASMEntryPoint"
|
||||
]
|
||||
},
|
||||
"depends": [
|
||||
|
||||
Reference in New Issue
Block a user