mirror of
https://github.com/GTMEGA/EndlessIDs.git
synced 2026-11-12 21:17:37 +00:00
Fixed the registry lag
This commit is contained in:
4 files changed
+146
-16
No files matched your search
@@ -2,13 +2,18 @@ package com.falsepattern.endlessids.asm;
|
||||
|
||||
import com.falsepattern.endlessids.asm.transformer.ChunkProviderSuperPatcher;
|
||||
import com.falsepattern.endlessids.asm.transformer.FmlRegistry;
|
||||
import com.falsepattern.endlessids.asm.transformer.GameDataAccelerator;
|
||||
import com.falsepattern.endlessids.asm.transformer.SpaceCoreModInfoGenerator;
|
||||
import com.falsepattern.endlessids.config.GeneralConfig;
|
||||
import lombok.val;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public enum ClassEdit {
|
||||
ChunkProviderSuperPatcher(new ChunkProviderSuperPatcher(), () -> GeneralConfig.extendBiome),
|
||||
@@ -17,15 +22,17 @@ public enum ClassEdit {
|
||||
"cpw.mods.fml.common.registry.GameData",
|
||||
"cpw.mods.fml.common.registry.FMLControlledNamespacedRegistry"),
|
||||
SpaceCoreModInfoGenerator(new SpaceCoreModInfoGenerator(), () -> true,
|
||||
"com.spacechase0.minecraft.spacecore.mcp.ModInfoGenerator");
|
||||
"com.spacechase0.minecraft.spacecore.mcp.ModInfoGenerator"),
|
||||
GameDataAccelerator(new GameDataAccelerator(), () -> true, "cpw.mods.fml.common.registry.GameData"),
|
||||
;
|
||||
|
||||
private static final Map<String, ClassEdit> editMap;
|
||||
private static final Map<String, List<ClassEdit>> editMap;
|
||||
|
||||
static {
|
||||
editMap = new HashMap<>();
|
||||
for (final ClassEdit edit : values()) {
|
||||
for (final String name : edit.classNames) {
|
||||
ClassEdit.editMap.put(name, edit);
|
||||
ClassEdit.editMap.computeIfAbsent(name, (ignored) -> new ArrayList<>()).add(edit);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,9 +47,14 @@ public enum ClassEdit {
|
||||
this.classNames = classNames;
|
||||
}
|
||||
|
||||
public static ClassEdit get(final String className) {
|
||||
val ret = ClassEdit.editMap.get(className);
|
||||
return ret != null && ret.cond.getAsBoolean() ? ret : null;
|
||||
public static List<ClassEdit> get(final String className) {
|
||||
val edit = ClassEdit.editMap.get(className);
|
||||
if (edit == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return edit.stream()
|
||||
.filter(r -> r.cond.getAsBoolean())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.falsepattern.endlessids.asm;
|
||||
|
||||
import lombok.var;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Collections;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
public class GameDataHooks {
|
||||
private static final WeakHashMap<Block, WeakReference<ItemBlock>> itemBlockCache = new WeakHashMap<>();
|
||||
|
||||
public static void cacheItemBlock(ItemBlock itemBlock) {
|
||||
itemBlockCache.put(itemBlock.field_150939_a, new WeakReference<>(itemBlock));
|
||||
}
|
||||
|
||||
public static ItemBlock fetchCachedItemBlock(Block block) {
|
||||
var weakItem = itemBlockCache.get(block);
|
||||
if (weakItem != null) {
|
||||
return weakItem.get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Iterable<Item> fakeIterable() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import com.falsepattern.endlessids.Tags;
|
||||
import com.falsepattern.endlessids.asm.transformer.ChunkProviderSuperPatcher;
|
||||
import com.falsepattern.endlessids.asm.transformer.DevFixer;
|
||||
import lombok.val;
|
||||
import lombok.var;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
@@ -37,8 +38,7 @@ public class IETransformer implements IClassTransformer {
|
||||
if (blacklist.contains(transformedName)) {
|
||||
return bytes;
|
||||
}
|
||||
ClassEdit[] edits = new ClassEdit[2];
|
||||
edits[0] = ClassEdit.get(transformedName);
|
||||
var edits = new ArrayList<ClassEdit>(ClassEdit.get(transformedName));
|
||||
ClassNode cn = new ClassNode(Opcodes.ASM5);
|
||||
{
|
||||
val reader = new ClassReader(bytes);
|
||||
@@ -52,20 +52,15 @@ public class IETransformer implements IClassTransformer {
|
||||
val reader = new ClassReader(bytes);
|
||||
reader.accept(cn, ClassReader.EXPAND_FRAMES);
|
||||
}
|
||||
if (edits[0] == null) {
|
||||
edits[0] = ClassEdit.ChunkProviderSuperPatcher;
|
||||
} else {
|
||||
edits[1] = ClassEdit.ChunkProviderSuperPatcher;
|
||||
}
|
||||
edits.add(ClassEdit.ChunkProviderSuperPatcher);
|
||||
}
|
||||
if (edits[0] == null) {
|
||||
if (edits.size() == 0) {
|
||||
return isObfuscated ? bytes : DevFixer.fixDev(bytes);
|
||||
}
|
||||
if (!isObfuscated) {
|
||||
DevFixer.transform(cn);
|
||||
}
|
||||
for (int i = 0; i < edits.length; i++) {
|
||||
val edit = edits[i];
|
||||
for (final ClassEdit edit : edits) {
|
||||
if (edit == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.falsepattern.endlessids.asm.transformer;
|
||||
|
||||
import com.falsepattern.endlessids.asm.IClassNodeTransformer;
|
||||
import com.falsepattern.endlessids.asm.IETransformer;
|
||||
import lombok.val;
|
||||
import lombok.var;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldInsnNode;
|
||||
import org.objectweb.asm.tree.InsnNode;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import org.objectweb.asm.tree.VarInsnNode;
|
||||
|
||||
public class GameDataAccelerator implements IClassNodeTransformer {
|
||||
private static final int MASK_REGISTER_BLOCK = 0b1;
|
||||
private static final int MASK_REGISTER_ITEM = 0b10;
|
||||
@Override
|
||||
public void transform(ClassNode classNode, boolean obfuscated) {
|
||||
int tweaksLeft = MASK_REGISTER_BLOCK | MASK_REGISTER_ITEM;
|
||||
for (val method: classNode.methods) {
|
||||
if ((tweaksLeft & MASK_REGISTER_BLOCK) != 0 &&
|
||||
method.name.equals("registerBlock") &&
|
||||
method.desc.equals("(Lnet/minecraft/block/Block;Ljava/lang/String;I)I")) {
|
||||
transformRegisterBlock(method);
|
||||
tweaksLeft &= ~MASK_REGISTER_BLOCK;
|
||||
}
|
||||
if ((tweaksLeft & MASK_REGISTER_ITEM) != 0 &&
|
||||
method.name.equals("registerItem") &&
|
||||
method.desc.equals("(Lnet/minecraft/item/Item;Ljava/lang/String;I)I")) {
|
||||
transformRegisterItem(method);
|
||||
tweaksLeft &= ~MASK_REGISTER_ITEM;
|
||||
}
|
||||
if (tweaksLeft == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tweaksLeft != 0) {
|
||||
IETransformer.logger.error("Could not accelerate block registration!");
|
||||
}
|
||||
}
|
||||
|
||||
private void transformRegisterItem(MethodNode method) {
|
||||
var iter = method.instructions.iterator();
|
||||
while (iter.hasNext()) {
|
||||
var insn = iter.next();
|
||||
if (!(insn instanceof FieldInsnNode))
|
||||
continue;
|
||||
var typeInsn = (FieldInsnNode) insn;
|
||||
if (!(typeInsn.owner.equals("net/minecraft/item/ItemBlock") &&
|
||||
typeInsn.name.equals("field_150939_a") &&
|
||||
typeInsn.desc.equals("Lnet/minecraft/block/Block;")))
|
||||
continue;
|
||||
iter.previous();
|
||||
iter.add(new InsnNode(Opcodes.DUP));
|
||||
iter.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "com/falsepattern/endlessids/asm/GameDataHooks", "cacheItemBlock", "(Lnet/minecraft/item/ItemBlock;)V", false));
|
||||
return;
|
||||
}
|
||||
transformError(method);
|
||||
}
|
||||
|
||||
private static void transformError(MethodNode method) {
|
||||
IETransformer.logger.error("Could not add caching code to GameData." + method.name + method.desc);
|
||||
}
|
||||
|
||||
private void transformRegisterBlock(MethodNode method) {
|
||||
var iter = method.instructions.iterator();
|
||||
while (iter.hasNext()) {
|
||||
var insn = iter.next();
|
||||
if (!(insn instanceof FieldInsnNode))
|
||||
continue;
|
||||
var fieldInsn = (FieldInsnNode) insn;
|
||||
if (!(fieldInsn.owner.equals("cpw/mods/fml/common/registry/GameData") &&
|
||||
fieldInsn.name.equals("iItemRegistry") &&
|
||||
fieldInsn.desc.equals("Lcpw/mods/fml/common/registry/FMLControlledNamespacedRegistry;")))
|
||||
continue;
|
||||
iter.previous();
|
||||
iter.previous();
|
||||
iter.remove();
|
||||
iter.next();
|
||||
iter.remove();
|
||||
iter.next();
|
||||
iter.remove();
|
||||
iter.add(new VarInsnNode(Opcodes.ALOAD, 1));
|
||||
iter.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "com/falsepattern/endlessids/asm/GameDataHooks", "fetchCachedItemBlock", "(Lnet/minecraft/block/Block;)Lnet/minecraft/item/ItemBlock;", false));
|
||||
iter.add(new VarInsnNode(Opcodes.ASTORE, 4));
|
||||
iter.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "com/falsepattern/endlessids/asm/GameDataHooks", "fakeIterable", "()Ljava/lang/Iterable;", false));
|
||||
return;
|
||||
}
|
||||
transformError(method);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user