Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CubicChunks 1271 and MixinBooter #34

Merged
merged 2 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ dependencies {
compileOnly rfg.deobf( "curse.maven:bewitchment-285439:3256343" )
compileOnly rfg.deobf( "curse.maven:compact-machines-224218:2707509")

compileOnly rfg.deobf( "curse.maven:CubicChunks-292243:3546640" )
compileOnly rfg.deobf( "curse.maven:CubicChunks-292243:5135427" )
compileOnly rfg.deobf( "curse.maven:RTGU-648514:4396319" )

}
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/dimdev/jeid/JEID.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@

@Mod(modid = "jeid",
name = "JustEnoughIDs",
updateJSON = "https://gist.githubusercontent.com/Runemoro/67b1d8d31af58e9d35410ef60b2017c3/raw/1fe08a6c45a1f481a8a2a8c71e52d4245dcb7713/jeid_update.json")
updateJSON = "https://gist.githubusercontent.com/Runemoro/67b1d8d31af58e9d35410ef60b2017c3/raw/1fe08a6c45a1f481a8a2a8c71e52d4245dcb7713/jeid_update.json",
dependencies = "required:mixinbooter@[7.1,)")
public class JEID {
private static final boolean DEBUG_BLOCK_IDS = false;
private static final boolean DEBUG_ITEM_IDS = false;
Expand Down
19 changes: 9 additions & 10 deletions src/main/java/org/dimdev/jeid/JEIDLoadingPlugin.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
package org.dimdev.jeid;

import com.google.common.collect.ImmutableList;
import net.minecraftforge.common.ForgeVersion;
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
import org.spongepowered.asm.launch.MixinBootstrap;
import org.spongepowered.asm.mixin.Mixins;
import zone.rong.mixinbooter.IEarlyMixinLoader;
import zone.rong.mixinbooter.ILateMixinLoader;

import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;

@IFMLLoadingPlugin.MCVersion(ForgeVersion.mcVersion)
@IFMLLoadingPlugin.SortingIndex(-7500)
@IFMLLoadingPlugin.Name("JustEnoughIDs Extension Plugin")
//@IFMLLoadingPlugin.TransformerExclusions("org.dimdev.jeid.")
public class JEIDLoadingPlugin implements IFMLLoadingPlugin {

public JEIDLoadingPlugin() {
MixinBootstrap.init();
Utils.LOGGER.info("Initializing JustEnoughIDs core mixins");
Mixins.addConfiguration("mixins.jeid.core.json");
Utils.LOGGER.info("Initializing JustEnoughIDs initialization mixins");
Mixins.addConfiguration("mixins.jeid.init.json");
}

public class JEIDLoadingPlugin implements IFMLLoadingPlugin, IEarlyMixinLoader {
@Override public String[] getASMTransformerClass() { Obf.loadData(); return new String[]{ "org.dimdev.jeid.JEIDTransformer" }; }
@Override public String getModContainerClass() { return null; }
@Nullable @Override public String getSetupClass() { return null; }
@Override public void injectData(Map<String, Object> data) {}
@Override public String getAccessTransformerClass() { return null; }

public List<String> getMixinConfigs() {
return ImmutableList.of("mixins.jeid.core.json");
}
}
153 changes: 72 additions & 81 deletions src/main/java/org/dimdev/jeid/mixin/init/JEIDMixinLoader.java
Original file line number Diff line number Diff line change
@@ -1,92 +1,83 @@
package org.dimdev.jeid.mixin.init;

import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.ModClassLoader;
import net.minecraftforge.fml.common.ModContainer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.MixinEnvironment;
import org.spongepowered.asm.mixin.Mixins;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.transformer.ext.Extensions;
import zone.rong.mixinbooter.ILateMixinLoader;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;

@Mixin(Loader.class)
public class JEIDMixinLoader {
@Shadow
private List<ModContainer> mods;
@Shadow private ModClassLoader modClassLoader;

/**
* @reason Load all mods now and load mod support mixin configs. This can't be done later
* since constructing mods loads classes from them.
*/
@Inject(method = "loadMods", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/common/LoadController;transition(Lnet/minecraftforge/fml/common/LoaderState;Z)V", ordinal = 1), remap = false)
private void beforeConstructingMods(List<String> nonMod, CallbackInfo ci) {
// Add all mods to class loader
for (ModContainer mod : mods) {
try {
modClassLoader.addFile(mod.getSource());
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}

// Add and reload mixin configs
Mixins.addConfiguration("mixins.jeid.modsupport.json");
Mixins.addConfiguration("mixins.jeid.twilightforest.json");
public class JEIDMixinLoader implements ILateMixinLoader {
public List<String> getMixinConfigs() {
List<String> configs = new ArrayList<String>();

try {
// This will very likely break on the next major mixin release.
Class<?> proxyClass = Class.forName("org.spongepowered.asm.mixin.transformer.Proxy");
Field transformerField = proxyClass.getDeclaredField("transformer");
transformerField.setAccessible(true);
Object transformer = transformerField.get(null);

Class<?> mixinTransformerClass = Class.forName("org.spongepowered.asm.mixin.transformer.MixinTransformer");
Field processorField = mixinTransformerClass.getDeclaredField("processor");
processorField.setAccessible(true);
Object processor = processorField.get(transformer);

Class<?> mixinProcessorClass = Class.forName("org.spongepowered.asm.mixin.transformer.MixinProcessor");

Field extensionsField = mixinProcessorClass.getDeclaredField("extensions");
extensionsField.setAccessible(true);
Object extensions = extensionsField.get(processor);

Method selectConfigsMethod = mixinProcessorClass.getDeclaredMethod("selectConfigs", MixinEnvironment.class);
selectConfigsMethod.setAccessible(true);
selectConfigsMethod.invoke(processor, MixinEnvironment.getCurrentEnvironment());

// Mixin 0.8.4+
try {
Method prepareConfigs = mixinProcessorClass.getDeclaredMethod("prepareConfigs", MixinEnvironment.class, Extensions.class);
prepareConfigs.setAccessible(true);
prepareConfigs.invoke(processor, MixinEnvironment.getCurrentEnvironment(), extensions);
return;
} catch (NoSuchMethodException ex) {
// no-op
}

// Mixin 0.8+
try {
Method prepareConfigs = mixinProcessorClass.getDeclaredMethod("prepareConfigs", MixinEnvironment.class);
prepareConfigs.setAccessible(true);
prepareConfigs.invoke(processor, MixinEnvironment.getCurrentEnvironment());
return;
} catch (NoSuchMethodException ex) {
// no-op
}

throw new UnsupportedOperationException("Unsupported Mixin");
} catch (Exception ex) {
throw new RuntimeException(ex);
if (Loader.isModLoaded("abyssalcraft")) {
configs.add("mixins.jeid.abyssalcraft.json");
}
if (Loader.isModLoaded("advancedrocketry")) {
configs.add("mixins.jeid.advancedrocketry.json");
}
if (Loader.isModLoaded("bewitchment")) {
configs.add("mixins.jeid.bewitchment.json");
}
if (Loader.isModLoaded("biomesoplenty")) {
configs.add("mixins.jeid.biomesoplenty.json");
}
if (Loader.isModLoaded("biometweaker")) {
configs.add("mixins.jeid.biometweaker.json");
}
if (Loader.isModLoaded("bookeshelf")) {
configs.add("mixins.jeid.bookshelf.json");
}
if (Loader.isModLoaded("compactmachines")) {
configs.add("mixins.jeid.compactmachines.json");
}
if (Loader.isModLoaded("creepingnether")) {
configs.add("mixins.jeid.creepingnether.json");
}
if (Loader.isModLoaded("cubicchunks")) {
configs.add("mixins.jeid.cubicchunks.json");
}
if (Loader.isModLoaded("cyclopscore")) {
configs.add("mixins.jeid.cyclopscore.json");
}
if (Loader.isModLoaded("extrautils2")) {
configs.add("mixins.jeid.extrautils2.json");
}
if (Loader.isModLoaded("gaiadimension")) {
configs.add("mixins.jeid.gaiadimension.json");
}
if (Loader.isModLoaded("geographicraft")) {
configs.add("mixins.jeid.geographicraft.json");
}
if (Loader.isModLoaded("hammercore")) {
configs.add("mixins.jeid.hammercore.json");
}
if (Loader.isModLoaded("journeymap")) {
configs.add("mixins.jeid.journeymap.json");
}
if (Loader.isModLoaded("mystcraft")) {
configs.add("mixins.jeid.mystcraft.json");
}
if (Loader.isModLoaded("thaumcraft")) {
configs.add("mixins.jeid.thaumcraft.json");
}
if (Loader.isModLoaded("thebetweenlands")) {
configs.add("mixins.jeid.thebetweenlands.json");
}
if (Loader.isModLoaded("tofucraft")) {
configs.add("mixins.jeid.tofucraft.json");
}
if (Loader.isModLoaded("tropicraft")) {
configs.add("mixins.jeid.tropicraft.json");
}
if (Loader.isModLoaded("twilightforest")) {
configs.add("mixins.jeid.twilightforest.json");
}
if (Loader.isModLoaded("worldedit")) {
configs.add("mixins.jeid.worldedit.json");
}

return configs;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,59 +12,59 @@

import org.dimdev.jeid.JEID;
import org.dimdev.jeid.modsupport.cubicchunks.INewCube;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.ModifyVariable;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

@Pseudo
@Mixin(Cube.class)
public abstract class MixinCube implements INewCube {
@Implements(@Interface(iface = INewCube.class, prefix = "int$"))
public abstract class MixinCube {
@Shadow @Final @Nonnull private World world;

@Shadow
public abstract <T extends Chunk & IColumn> T getColumn();


private static final byte errorBiomeID = (byte) Biome.REGISTRY.getIDForObject(JEID.errorBiome);
@Nullable private int[] intBlockBiomeArray = null;
@Nullable private int[] blockBiomeArray;

@Nullable
@Override
public int[] getIntBiomeArray() {
return this.intBlockBiomeArray;
}

@Override
public void setIntBiomeArray(int[] intBiomeArray) {
if (this.intBlockBiomeArray == null)
this.intBlockBiomeArray = intBiomeArray;
if (this.intBlockBiomeArray.length != intBiomeArray.length)
CubicChunks.LOGGER.warn("Could not set level cube biomes, array length is {} instead of {}", Integer.valueOf(intBiomeArray.length),
Integer.valueOf(this.intBlockBiomeArray.length));
System.arraycopy(intBiomeArray, 0, this.intBlockBiomeArray, 0, this.intBlockBiomeArray.length);
}

@Overwrite(remap = false)
public Biome getBiome(BlockPos pos) {
if (this.intBlockBiomeArray == null)
if (this.blockBiomeArray == null)
return this.getColumn().getBiome(pos, world.getBiomeProvider());
int biomeX = Coords.blockToBiome(pos.getX());
int biomeZ = Coords.blockToBiome(pos.getZ());
int biomeId = this.intBlockBiomeArray[AddressTools.getBiomeAddress(biomeX, biomeZ)] & 255;
Biome biome = Biome.getBiome(biomeId);
return biome;

int biomeX = Coords.blockToLocalBiome3d(pos.getX());
int biomeY = Coords.blockToLocalBiome3d(pos.getY());
int biomeZ = Coords.blockToLocalBiome3d(pos.getZ());
int biomeId = this.blockBiomeArray[AddressTools.getBiomeAddress3d(biomeX, biomeY, biomeZ)];
return Biome.getBiome(biomeId);
}

@Overwrite(remap = false)
public void setBiome(int localBiomeX, int localBiomeZ, Biome biome) {
if (this.intBlockBiomeArray == null)
this.intBlockBiomeArray = new int[64];
public void setBiome(int localBiomeX, int localBiomeY, int localBiomeZ, Biome biome) {
if (this.blockBiomeArray == null)
this.blockBiomeArray = new int[64];

this.blockBiomeArray[AddressTools.getBiomeAddress3d(localBiomeX, localBiomeY, localBiomeZ)] = Biome.REGISTRY.getIDForObject(biome);
}

@Nullable
public int[] int$getBiomeArray() {
return this.blockBiomeArray;
}

public void int$setBiomeArray(int[] biomeArray) {
if (this.blockBiomeArray == null)
this.blockBiomeArray = biomeArray;

this.intBlockBiomeArray[AddressTools.getBiomeAddress(localBiomeX, localBiomeZ)] = Biome.REGISTRY.getIDForObject(biome);
if (this.blockBiomeArray.length != biomeArray.length) {
CubicChunks.LOGGER.warn("Could not set level cube biomes, array length is {} instead of {}", biomeArray.length, this.blockBiomeArray.length);
} else {
System.arraycopy(biomeArray, 0, this.blockBiomeArray, 0, this.blockBiomeArray.length);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.github.opencubicchunks.cubicchunks.api.util.Coords;
import io.github.opencubicchunks.cubicchunks.core.server.chunkio.IONbtReader;
import io.github.opencubicchunks.cubicchunks.core.util.AddressTools;
import io.github.opencubicchunks.cubicchunks.core.world.cube.Cube;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
Expand All @@ -12,28 +13,11 @@
import org.dimdev.jeid.INewBlockStateContainer;
import org.dimdev.jeid.INewChunk;
import org.dimdev.jeid.modsupport.cubicchunks.INewCube;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.*;

@Pseudo
@Mixin(IONbtReader.class)
public class MixinIONbtReader {

@Overwrite
private static void readBiomes(NBTTagCompound nbt, Chunk column) {// column biomes
System.arraycopy(nbt.getIntArray("Biomes"), 0, ((INewChunk)column).getIntBiomeArray(), 0, Cube.SIZE * Cube.SIZE);
}

@Overwrite
private static void readBiomes(Cube cube, NBTTagCompound nbt) {// cube biomes
if (nbt.hasKey("Biomes"))
{
INewCube newCube = (INewCube) cube;
newCube.setIntBiomeArray(nbt.getIntArray("Biomes"));
}
}

@Overwrite
private static void readBlocks(NBTTagCompound nbt, World world, Cube cube) {
boolean isEmpty = !nbt.hasKey("Sections");// is this an empty cube?
Expand All @@ -54,7 +38,6 @@ private static void readBlocks(NBTTagCompound nbt, World world, Cube cube) {
ebs.getData().setDataFromNBT(abyte, data, add);

ebs.setBlockLight(new NibbleArray(nbt.getByteArray("BlockLight")));

if (world.provider.hasSkyLight()) {
ebs.setSkyLight(new NibbleArray(nbt.getByteArray("SkyLight")));
}
Expand All @@ -64,4 +47,36 @@ private static void readBlocks(NBTTagCompound nbt, World world, Cube cube) {
}
}

@Overwrite
private static void readBiomes(NBTTagCompound nbt, Chunk column) {// column biomes
System.arraycopy(nbt.getIntArray("Biomes"), 0, ((INewChunk)column).getIntBiomeArray(), 0, Cube.SIZE * Cube.SIZE);
}

@Overwrite
private static void readBiomes(Cube cube, NBTTagCompound nbt) {// cube biomes
if (nbt.hasKey("Biomes3D")) {
((INewCube) cube).setBiomeArray(nbt.getIntArray("Biomes3D"));
}
if (nbt.hasKey("Biomes"))
{
((INewCube) cube).setBiomeArray(convertFromOldCubeBiomes(nbt.getIntArray("Biomes")));
}
}

private static int[] convertFromOldCubeBiomes(int[] biomes) {
int[] newBiomes = new int[64];

for(int x = 0; x < 4; ++x) {
for(int y = 0; y < 4; ++y) {
for(int z = 0; z < 4; ++z) {
newBiomes[AddressTools.getBiomeAddress3d(x, y, z)] = biomes[getOldBiomeAddress(x << 1 | y & 1, z << 1 | y >> 1 & 1)];
}
}
}

return newBiomes;
}

@Shadow
public static int getOldBiomeAddress(int biomeX, int biomeZ) { return biomeX << 3 | biomeZ; }
}
Loading
Loading