Skip to content

Commit

Permalink
Fix Granite ID Shift (#1549)
Browse files Browse the repository at this point in the history
* Add DataFixers
* Add deterministic MetaBlocks generation
* Upgrade of old Metablocks to new format
  • Loading branch information
dan authored May 8, 2021
1 parent 0983830 commit f556ca8
Show file tree
Hide file tree
Showing 27 changed files with 1,491 additions and 29 deletions.
4 changes: 4 additions & 0 deletions src/main/java/gregtech/GregTechVersion.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package gregtech;

import gregtech.api.util.Version;

public final class GregTechVersion {

public static final int MAJOR = 1;
Expand All @@ -10,6 +12,8 @@ public final class GregTechVersion {
//This number is incremented every build, and never reset. Should always be 0 in the repo code.
public static final int BUILD = 0;

public static final Version VERSION = new Version(MAJOR, MINOR, REVISION, BUILD);

private GregTechVersion() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public static void register() {
private static final long EXT_METAL = STD_METAL | GENERATE_ROD | GENERATE_BOLT_SCREW | GENERATE_LONG_ROD;
private static final long EXT2_METAL = EXT_METAL | GENERATE_GEAR | GENERATE_FOIL | GENERATE_FINE_WIRE;

public static MarkerMaterial _NULL = new MarkerMaterial("_null");
public static final MarkerMaterial _NULL = new MarkerMaterial("_null");

/**
* Direct Elements
Expand Down
71 changes: 71 additions & 0 deletions src/main/java/gregtech/api/util/Version.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package gregtech.api.util;

import java.util.Arrays;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class Version implements Comparable<Version> {

private final int[] nums;

public Version(int... nums) {
if (nums.length == 0) {
throw new IllegalArgumentException("Must be at least one version number!");
}
for (int num : nums) {
if (num < 0) {
throw new IllegalArgumentException("Version numbers must be positive!");
}
}
this.nums = nums;
}

public static Version parse(String vStr) {
return new Version(Arrays.stream(vStr.split(Pattern.quote("."))).mapToInt(Integer::parseInt).toArray());
}

public int getNumber(int index) {
if (index < 0) {
throw new IndexOutOfBoundsException("Index must be nonnegative!");
}
return index < nums.length ? nums[index] : 0;
}

@Override
public int compareTo(Version o) {
int numBound = Math.max(nums.length, o.nums.length);
for (int i = 0; i < numBound; i++) {
int cmp = Integer.compare(getNumber(i), o.getNumber(i));
if (cmp != 0) {
return cmp;
}
}
return 0;
}

@Override
public boolean equals(Object obj) {
return obj instanceof Version && compareTo((Version) obj) == 0;
}

@Override
public int hashCode() {
int hash = 0;
for (int i = 0; i < nums.length; i++) {
hash ^= Integer.rotateLeft(nums[i], i * 7);
}
return hash;
}

@Override
public String toString() {
return toString(nums.length);
}

public String toString(int sigPlaces) {
return Arrays.stream(nums, 0, Math.min(sigPlaces, nums.length))
.mapToObj(Integer::toString)
.collect(Collectors.joining("."));
}

}
6 changes: 3 additions & 3 deletions src/main/java/gregtech/common/CommonProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import gregtech.common.blocks.wood.BlockGregLeaves;
import gregtech.common.blocks.wood.BlockGregLog;
import gregtech.common.blocks.wood.BlockGregSapling;
import gregtech.common.datafix.GregTechDataFixers;
import gregtech.common.items.MetaItems;
import gregtech.common.items.potions.PotionFluids;
import gregtech.common.pipelike.cable.ItemBlockCable;
Expand Down Expand Up @@ -235,12 +236,11 @@ public void onPreLoad() {
}

public void onLoad() {

GregTechDataFixers.init();
}

public void onPostLoad() {
WoodMachineRecipes.postInit();
}


}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package gregtech.common.asm;

import gregtech.common.asm.util.ObfMapping;
import gregtech.common.asm.util.SafeMethodVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class CompoundDataFixerGetVersionVisitor extends SafeMethodVisitor {

public static final String TARGET_CLASS_NAME = "net/minecraftforge/common/util/CompoundDataFixer$1";
public static final ObfMapping TARGET_METHOD = new ObfMapping(TARGET_CLASS_NAME, "getVersion", "(Ljava/lang/String;)I");

private static final String WORLD_DATA_HOOKS_OWNER = "gregtech/common/datafix/fixes/metablockid/WorldDataHooks";
private static final String WORLD_DATA_HOOKS_METHOD_NAME = "getFallbackModVersion";
private static final String WORLD_DATA_HOOKS_SIGNATURE = "(Ljava/lang/String;)I";

public CompoundDataFixerGetVersionVisitor(MethodVisitor mv) {
super(Opcodes.ASM5, mv);
}

@Override
public void visitInsn(int opcode) {
if (opcode == Opcodes.ICONST_M1) {
markPatchedSuccessfully();
super.visitVarInsn(Opcodes.ALOAD, 1);
super.visitMethodInsn(Opcodes.INVOKESTATIC, WORLD_DATA_HOOKS_OWNER,
WORLD_DATA_HOOKS_METHOD_NAME, WORLD_DATA_HOOKS_SIGNATURE, false);
} else {
super.visitInsn(opcode);
}
}

@Override
protected String getInjectTargetString() {
return String.format("Patch target: %s; (point not found)", TARGET_METHOD);
}

}
15 changes: 13 additions & 2 deletions src/main/java/gregtech/common/asm/GTCETransformer.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package gregtech.common.asm;

import gregtech.common.asm.util.TargetClassVisitor;
import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;

import gregtech.common.asm.util.*;

public class GTCETransformer implements IClassTransformer, Opcodes {

@Override
Expand Down Expand Up @@ -36,6 +35,18 @@ public byte[] transform(String name, String transformedName, byte[] basicClass)
classReader.accept(new TargetClassVisitor(classWriter, JEIVisitor.TARGET_METHOD, JEIVisitor::new), 0);
return classWriter.toByteArray();
}
if (internalName.equals(SaveFormatOldLoadVisitor.TARGET_CLASS_NAME)) {
ClassReader classReader = new ClassReader(basicClass);
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
classReader.accept(new TargetClassVisitor(classWriter, SaveFormatOldLoadVisitor.TARGET_METHOD, SaveFormatOldLoadVisitor::new), 0);
return classWriter.toByteArray();
}
if (internalName.equals(CompoundDataFixerGetVersionVisitor.TARGET_CLASS_NAME)) {
ClassReader classReader = new ClassReader(basicClass);
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
classReader.accept(new TargetClassVisitor(classWriter, CompoundDataFixerGetVersionVisitor.TARGET_METHOD, CompoundDataFixerGetVersionVisitor::new), 0);
return classWriter.toByteArray();
}
return basicClass;
}
}
59 changes: 59 additions & 0 deletions src/main/java/gregtech/common/asm/SaveFormatOldLoadVisitor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package gregtech.common.asm;

import gregtech.common.asm.util.ObfMapping;
import gregtech.common.asm.util.SafeMethodVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class SaveFormatOldLoadVisitor extends SafeMethodVisitor {

public static final String TARGET_CLASS_NAME = "net/minecraft/world/storage/SaveFormatOld";
public static final ObfMapping TARGET_METHOD = new ObfMapping(TARGET_CLASS_NAME, "loadAndFix", // forge method
"(Ljava/io/File;Lnet/minecraft/util/datafix/DataFixer;Lnet/minecraft/world/storage/SaveHandler;)Lnet/minecraft/world/storage/WorldInfo;");

private static final String LOAD_COMPRESSED_OWNER = "net/minecraft/nbt/CompressedStreamTools";
private static final ObfMapping LOAD_COMPRESSED_METHOD = new ObfMapping(LOAD_COMPRESSED_OWNER, "func_74796_a",
"(Ljava/io/InputStream;)Lnet/minecraft/nbt/NBTTagCompound;").toRuntime();

private static final String WORLD_DATA_HOOKS_OWNER = "gregtech/common/datafix/fixes/metablockid/WorldDataHooks";
private static final String WORLD_DATA_HOOKS_METHOD_NAME = "onWorldLoad";
private static final String WORLD_DATA_HOOKS_SIGNATURE = "(Lnet/minecraft/world/storage/SaveHandler;Lnet/minecraft/nbt/NBTTagCompound;)V";

private State state = State.WAITING_FOR_READ;

public SaveFormatOldLoadVisitor(MethodVisitor mv) {
super(Opcodes.ASM5, mv);
}

@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
super.visitMethodInsn(opcode, owner, name, desc, itf);
if (state == State.WAITING_FOR_READ && opcode == Opcodes.INVOKESTATIC
&& owner.equals(LOAD_COMPRESSED_OWNER) && LOAD_COMPRESSED_METHOD.matches(name, desc)) {
state = State.WAITING_FOR_VAR;
}
}

@Override
public void visitVarInsn(int opcode, int var) {
super.visitVarInsn(opcode, var);
if (state == State.WAITING_FOR_VAR && opcode == Opcodes.ASTORE) {
state = State.DONE;
markPatchedSuccessfully();
super.visitVarInsn(Opcodes.ALOAD, 2);
super.visitVarInsn(Opcodes.ALOAD, var);
super.visitMethodInsn(Opcodes.INVOKESTATIC, WORLD_DATA_HOOKS_OWNER,
WORLD_DATA_HOOKS_METHOD_NAME, WORLD_DATA_HOOKS_SIGNATURE, false);
}
}

@Override
protected String getInjectTargetString() {
return String.format("Patch target: %s; (point not found)", TARGET_METHOD);
}

private enum State {
WAITING_FOR_READ, WAITING_FOR_VAR, DONE
}

}
58 changes: 36 additions & 22 deletions src/main/java/gregtech/common/blocks/MetaBlocks.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gregtech.common.blocks;

import com.google.common.collect.ImmutableMap;
import gnu.trove.map.TIntObjectMap;
import gregtech.api.GTValues;
import gregtech.api.GregTechAPI;
import gregtech.api.block.machines.BlockMachine;
Expand Down Expand Up @@ -168,10 +169,13 @@ public static void init() {

StoneType.init();

createGeneratedBlock(material -> material instanceof DustMaterial &&
!OrePrefix.block.isIgnored(material), MetaBlocks::createCompressedBlock);
createGeneratedBlock(material -> material instanceof IngotMaterial &&
material.hasFlag(MatFlags.GENERATE_ORE), MetaBlocks::createSurfaceRockBlock);
createGeneratedBlock(
material -> material instanceof DustMaterial && !OrePrefix.block.isIgnored(material),
MetaBlocks::createCompressedBlock);

createGeneratedBlock(
material -> material instanceof IngotMaterial && material.hasFlag(MatFlags.GENERATE_ORE),
MetaBlocks::createSurfaceRockBlock);

for (Material material : Material.MATERIAL_REGISTRY) {
if (material instanceof DustMaterial &&
Expand Down Expand Up @@ -203,29 +207,39 @@ public static void init() {
Blocks.FIRE.setFireInfo(LEAVES, 30, 60);
}

private static int createGeneratedBlock(Predicate<Material> materialPredicate, BiConsumer<Material[], Integer> blockGenerator) {
Material[] materialBuffer = new Material[16];
Arrays.fill(materialBuffer, Materials._NULL);
int currentGenerationIndex = 0;
for (Material material : Material.MATERIAL_REGISTRY) {
if (materialPredicate.test(material)) {
if (currentGenerationIndex > 0 && currentGenerationIndex % 16 == 0) {
blockGenerator.accept(materialBuffer, currentGenerationIndex / 16 - 1);
Arrays.fill(materialBuffer, Materials._NULL);
/**
* Deterministically populates a category of MetaBlocks based on the unique registry ID of each qualifying Material.
*
* @param materialPredicate a filter for determining if a Material qualifies for generation in the category.
* @param blockGenerator a function which accepts a Materials set to pack into a MetaBlock, and the ordinal this
* MetaBlock should have within its category.
*/
protected static void createGeneratedBlock(Predicate<Material> materialPredicate,
BiConsumer<Material[], Integer> blockGenerator) {

Map<Integer, Material[]> blocksToGenerate = new TreeMap<>();

for(Material material : Material.MATERIAL_REGISTRY)
if(materialPredicate.test(material)) {
int id = Material.MATERIAL_REGISTRY.getIDForObject(material);
int metaBlockID = id / 16;
int subBlockID = id % 16;

if (!blocksToGenerate.containsKey(metaBlockID)) {
Material[] materials = new Material[16];
Arrays.fill(materials, Materials._NULL);
blocksToGenerate.put(metaBlockID, materials);
}
materialBuffer[currentGenerationIndex % 16] = material;
currentGenerationIndex++;

blocksToGenerate.get(metaBlockID)[subBlockID] = material;
}
}
if (materialBuffer[0] != Materials._NULL) {
blockGenerator.accept(materialBuffer, currentGenerationIndex / 16);
}
return (currentGenerationIndex / 16) + 1;

blocksToGenerate.forEach((key, value) -> blockGenerator.accept(value, key));
}

private static void createSurfaceRockBlock(Material[] materials, int index) {
BlockSurfaceRockDeprecated block = new BlockSurfaceRockDeprecated(materials);
block.setRegistryName("surface_rock_" + index);
block.setRegistryName("meta_block_surface_rock_" + index);
for (Material material : materials) {
if (material instanceof IngotMaterial) {
SURFACE_ROCKS.put((IngotMaterial) material, block);
Expand All @@ -235,7 +249,7 @@ private static void createSurfaceRockBlock(Material[] materials, int index) {

private static void createCompressedBlock(Material[] materials, int index) {
BlockCompressed block = new BlockCompressed(materials);
block.setRegistryName("compressed_" + index);
block.setRegistryName("meta_block_compressed_" + index);
for (Material material : materials) {
if (material instanceof DustMaterial) {
COMPRESSED.put((DustMaterial) material, block);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static void init() {
}

private BlockCompressedFactory() {
super("compressed_block", "compressed_");
super("compressed_block", "meta_block_compressed_");
}

@Override
Expand Down
Loading

0 comments on commit f556ca8

Please sign in to comment.