mixin injection on client in forge

This commit is contained in:
dfsek 2021-05-21 23:36:20 -07:00
parent ce3d09cf2e
commit 3b3905b513
9 changed files with 104 additions and 74 deletions

View File

@ -54,8 +54,10 @@ import net.minecraft.world.gen.placement.DecoratedPlacement;
import net.minecraft.world.gen.placement.NoPlacementConfig;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.ForgeRegistry;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.objectweb.asm.Type;
@ -143,7 +145,7 @@ public class TerraForgePlugin implements TerraPlugin {
});
}
public void setup() {
public void init() {
logger.info("Initializing Terra...");
if(!addonRegistry.loadAll()) {
@ -153,6 +155,10 @@ public class TerraForgePlugin implements TerraPlugin {
registry.loadAll(this);
logger.info("Loaded packs.");
((ForgeRegistry<Biome>) ForgeRegistries.BIOMES).unfreeze(); // Evil
getConfigRegistry().forEach(pack -> pack.getBiomeRegistry().forEach((id, biome) -> ForgeRegistries.BIOMES.register(ForgeUtil.createBiome(biome)))); // Register all Terra biomes.
((ForgeRegistry<Biome>) ForgeRegistries.BIOMES).freeze();
}
@Override

View File

@ -0,0 +1,24 @@
package com.dfsek.terra.forge.generation;
import com.dfsek.terra.config.pack.ConfigPack;
import net.minecraft.client.gui.screen.BiomeGeneratorTypeScreens;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.DimensionSettings;
import org.jetbrains.annotations.NotNull;
public class TerraGeneratorType extends BiomeGeneratorTypeScreens {
private final ConfigPack pack;
public TerraGeneratorType(ConfigPack pack) {
super(new StringTextComponent("Terra:" + pack.getTemplate().getID()));
this.pack = pack;
}
@Override
protected @NotNull ChunkGenerator generator(@NotNull Registry<Biome> biomeRegistry, @NotNull Registry<DimensionSettings> chunkGeneratorSettingsRegistry, long seed) {
return new ForgeChunkGeneratorWrapper(new TerraBiomeSource(biomeRegistry, seed, pack), seed, pack);
}
}

View File

@ -1,22 +0,0 @@
package com.dfsek.terra.forge.generation;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.forge.TerraForgePlugin;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.DimensionSettings;
import net.minecraftforge.common.world.ForgeWorldType;
public class TerraLevelType implements ForgeWorldType.IChunkGeneratorFactory {
public static final TerraLevelType TERRA_LEVEL_TYPE = new TerraLevelType();
public static final ForgeWorldType FORGE_WORLD_TYPE = new ForgeWorldType(TERRA_LEVEL_TYPE).setRegistryName("terra", "world");
@Override
public ChunkGenerator createChunkGenerator(Registry<Biome> biomeRegistry, Registry<DimensionSettings> dimensionSettingsRegistry, long seed, String generatorSettings) {
System.out.println(generatorSettings);
dimensionSettingsRegistry.forEach(System.out::println);
ConfigPack pack = TerraForgePlugin.getInstance().getConfigRegistry().get("DEFAULT");
TerraForgePlugin.getInstance().logger().info("Creating generator for config pack " + pack.getTemplate().getID());
return new ForgeChunkGeneratorWrapper(new TerraBiomeSource(biomeRegistry, seed, pack), seed, pack);
}
}

View File

@ -1,25 +1,10 @@
package com.dfsek.terra.forge.listener;
import com.dfsek.terra.api.util.mutable.MutableInteger;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.forge.TerraForgePlugin;
import com.dfsek.terra.forge.generation.TerraLevelType;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.ForgeWorldTypeScreens;
import net.minecraftforge.common.world.ForgeWorldType;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
@Mod.EventBusSubscriber(value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD)
public class ClientListener {
@ -28,31 +13,5 @@ public class ClientListener {
@SubscribeEvent
public static void register(FMLClientSetupEvent event) {
INSTANCE.logger().info("Client setup...");
ForgeWorldType world = TerraLevelType.FORGE_WORLD_TYPE;
ForgeWorldTypeScreens.registerFactory(world, (returnTo, dimensionGeneratorSettings) -> new Screen(world.getDisplayName()) {
private final MutableInteger num = new MutableInteger(0);
private final List<ConfigPack> packs = new ArrayList<>();
private final Button toggle = new Button(width/2, 25, 120, 20, new StringTextComponent(""), button -> {
num.increment();
if(num.get() >= packs.size()) num.set(0);
button.setMessage(new StringTextComponent("Pack: " + packs.get(num.get()).getTemplate().getID()));
});
@Override
protected void init() {
packs.clear();
INSTANCE.getConfigRegistry().forEach((Consumer<ConfigPack>) packs::add);
addButton(new Button(0, 0, 120, 20, new StringTextComponent("Close"), btn -> Minecraft.getInstance().setScreen(returnTo)));
toggle.setMessage(new StringTextComponent("Pack: " + packs.get(num.get()).getTemplate().getID()));
addButton(toggle);
}
@Override
public void render(@NotNull MatrixStack p_230430_1_, int p_230430_2_, int p_230430_3_, float p_230430_4_) {
renderBackground(p_230430_1_);
super.render(p_230430_1_, p_230430_2_, p_230430_3_, p_230430_4_);
}
});
}
}

View File

@ -2,10 +2,8 @@ package com.dfsek.terra.forge.listener;
import com.dfsek.terra.forge.ForgeUtil;
import com.dfsek.terra.forge.TerraForgePlugin;
import com.dfsek.terra.forge.generation.TerraLevelType;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.feature.Feature;
import net.minecraftforge.common.world.ForgeWorldType;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@ -14,16 +12,9 @@ import net.minecraftforge.fml.common.Mod;
public class RegistryListener {
private static final TerraForgePlugin INSTANCE = TerraForgePlugin.getInstance();
@SubscribeEvent
public static void registerLevels(RegistryEvent.Register<ForgeWorldType> event) {
INSTANCE.logger().info("Registering level types...");
event.getRegistry().register(TerraLevelType.FORGE_WORLD_TYPE);
}
@SubscribeEvent
public static void register(RegistryEvent.Register<Biome> event) {
INSTANCE.setup(); // Setup now because we need the biomes, and this event happens after blocks n stuff
INSTANCE.getConfigRegistry().forEach(pack -> pack.getBiomeRegistry().forEach((id, biome) -> event.getRegistry().register(ForgeUtil.createBiome(biome)))); // Register all Terra biomes.
INSTANCE.logger().info("Registering biomes...");
}
@SubscribeEvent

View File

@ -0,0 +1,21 @@
package com.dfsek.terra.forge.mixin.access;
import net.minecraft.client.gui.screen.BiomeGeneratorTypeScreens;
import net.minecraft.util.text.ITextComponent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.List;
@Mixin(BiomeGeneratorTypeScreens.class)
public interface BiomeGeneratorTypeScreensAccessor {
@Accessor("PRESETS")
static List<BiomeGeneratorTypeScreens> getPresets() {
throw new UnsupportedOperationException();
}
@Mutable
@Accessor
void setDescription(ITextComponent description);
}

View File

@ -0,0 +1,29 @@
package com.dfsek.terra.forge.mixin.init;
import com.dfsek.terra.forge.TerraForgePlugin;
import com.dfsek.terra.forge.generation.TerraGeneratorType;
import com.dfsek.terra.forge.mixin.access.BiomeGeneratorTypeScreensAccessor;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.BiomeGeneratorTypeScreens;
import net.minecraft.resources.ResourcePackList;
import net.minecraft.util.text.StringTextComponent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(Minecraft.class)
public abstract class MinecraftClientMixin {
@Redirect(method = "<init>", at = @At(value = "INVOKE",
target = "Lnet/minecraft/resources/ResourcePackList;reload()V" // sorta arbitrary position, after mod init, before window opens
))
public void injectConstructor(ResourcePackList resourcePackList) {
TerraForgePlugin.getInstance().init(); // Load during MinecraftClient construction, after other mods have registered blocks and stuff
TerraForgePlugin.getInstance().getConfigRegistry().forEach(pack -> {
final BiomeGeneratorTypeScreens generatorType = new TerraGeneratorType(pack);
//noinspection ConstantConditions
((BiomeGeneratorTypeScreensAccessor) generatorType).setDescription(new StringTextComponent("Terra:" + pack.getTemplate().getID()));
BiomeGeneratorTypeScreensAccessor.getPresets().add(1, generatorType);
});
resourcePackList.reload();
}
}

View File

@ -0,0 +1,16 @@
package com.dfsek.terra.forge.mixin.init;
import com.dfsek.terra.forge.TerraForgePlugin;
import net.minecraft.server.Main;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Main.class)
public class MinecraftServerMixin {
@Inject(method = "main([Ljava/lang/String;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/registry/DynamicRegistries;builtin()Lnet/minecraft/util/registry/DynamicRegistries$Impl;"))
private static void injectConstructor(String[] args, CallbackInfo ci) {
TerraForgePlugin.getInstance().init(); // Load during MinecraftServer construction, after other mods have registered blocks and stuff
}
}

View File

@ -6,6 +6,7 @@
"mixins": [
"DimensionGeneratorSettingsMixin",
"access.AbstractSpawnerAccessor",
"access.BiomeGeneratorTypeScreensAccessor",
"implementations.BiomeMixin",
"implementations.ChunkGeneratorMixin",
"implementations.ConfiguredFeatureMixin",
@ -30,7 +31,12 @@
"implementations.world.ServerWorldMixin",
"implementations.world.WorldGenRegionMixin"
],
"client": [
"init.MinecraftClientMixin"
],
"server": [
"init.MinecraftServerMixin"
],
"injectors": {
"defaultRequire": 1