2
0
Fork 0

I don't remember what is in this

frozen
Shinare 2 years ago
parent 0a33756ccd
commit 3f8260cf41

2
.gitignore vendored

@ -1,4 +1,2 @@
shortcut
assets
build
.gradle

Binary file not shown.

@ -928,6 +928,8 @@ public class CinderLoE {
CinderCore.registerItemFallback(Item.getIdFromItem(BreeOutriderSpawnEgg), Item.getIdFromItem(Items.spawn_egg), "cinder_loe", "1.1");
CinderCore.registerItemFallback(Item.getIdFromItem(SauronSpawnEgg), Item.getIdFromItem(Items.spawn_egg), "cinder_loe", "1.1");
CinderCore.registerItemFallback(Item.getIdFromItem(utumnoSlaveSpawnEgg), Item.getIdFromItem(Items.spawn_egg), "cinder_loe", "1.2.1");
CinderCore.registerItemFallback(Item.getIdFromItem(helmetLimwaith), Item.getIdFromItem(LOTRMod.helmetMoredain), "cinder_loe", "1.0");
CinderCore.registerItemFallback(Item.getIdFromItem(bodyLimwaith), Item.getIdFromItem(LOTRMod.bodyMoredain), "cinder_loe", "1.0");
CinderCore.registerItemFallback(Item.getIdFromItem(legsLimwaith), Item.getIdFromItem(LOTRMod.legsMoredain), "cinder_loe", "1.0");
@ -994,6 +996,8 @@ public class CinderLoE {
CinderCore.registerEntityFallback(BreeCaptain.class, LOTREntityBreeMan.class, "cinder_loe", "1.1");
CinderCore.registerEntityFallback(BreeSoldierBannerBearer.class, LOTREntityBreeMan.class, "cinder_loe", "1.1");
CinderCore.registerEntityFallback(BreeOutrider.class, LOTREntityBreeMan.class, "cinder_loe", "1.1");
CinderCore.registerCustomFallback(42, 16, "banner", "cinder_loe", "1.2");
}
// Create unit trade entries here, out of the way of important code

@ -25,12 +25,8 @@ public class LOTRBannerAdder implements IClassTransformer {
public void registerBanners() {
custom_banners = new ArrayList<>();
// Arguments: enum name, texture name, ID, faction name
// register("RED_DWARF", "redDwarf", 42, "DURINS_FOLK");
register("RED_DWARF", "redDwarf", 42, "DURINS_FOLK");
// register("TEST", "test", 43, "GONDOR");
// NOT FUNCTIONAL, DO NOT REGISTER
// Non-compliant clients crash if original banner is unrecognized even if fallback is vanilla
// Most likely something in PacketEntityMetadata
}
@Override

@ -0,0 +1,160 @@
package com.zivilon.cinder_loe.coremod;
import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.IntInsnNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import java.util.List;
import java.util.ArrayList;
public class LOTRShieldAdder implements IClassTransformer {
public static List<BannerInfo> custom_banners = new ArrayList<>();
public void registerShields() {
custom_banners = new ArrayList<>();
// Arguments: enum name, texture name, ID, faction name
register("RED_DWARF", "redDwarf", 42, "DURINS_FOLK");
// register("TEST", "test", 43, "GONDOR");
}
@Override
public byte[] transform(String name, String transformedName, byte[] basicClass) {
if ("lotr.common.LOTRShields".equals(transformedName)) {
registerShields();
// Get class
ClassReader classReader = new ClassReader(basicClass);
ClassNode classNode = new ClassNode();
classReader.accept(classNode, 0);
// Add the new enum constant
for (BannerInfo banner : custom_banners) {
FieldNode newEnumConstant = new FieldNode(
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL + Opcodes.ACC_ENUM,
banner.enum_name,
"Llotr/common/LOTRShields;",
null,
null
);
classNode.fields.add(newEnumConstant);
}
// Locate <clinit>
MethodNode clinit = null;
for (MethodNode method : classNode.methods) {
if ("<clinit>".equals(method.name)) {
clinit = method;
break;
}
}
InsnList insns = clinit.instructions;
AbstractInsnNode constructor_injection_point = null;
for (int i = 0; i < insns.size(); i++) {
AbstractInsnNode insn = insns.get(i);
// Check if the instruction is a BIPUSH
if (insn.getOpcode() == Opcodes.BIPUSH) {
IntInsnNode intInsn = (IntInsnNode) insn;
// Check if the operand is 42, indicating the size of the $VALUES array
if (intInsn.operand == 42) {
// Found the instruction to modify
constructor_injection_point = insn;
// Modify the operand from 42 to 43 to account for the new enum constant
intInsn.operand = 42 + custom_banners.size();
System.out.println("Enum array length set to " + intInsn.operand);
System.out.println("Banner list size: " + custom_banners.size());
break;
}
}
}
// Create the constructor instructions to add new banner
InsnList constructor_injection = new InsnList();
for (BannerInfo banner : custom_banners) {
constructor_injection.add(new TypeInsnNode(Opcodes.NEW, "lotr/common/item/LOTRItemBanner$BannerType"));
constructor_injection.add(new InsnNode(Opcodes.DUP));
System.out.println("Registering with enum " + banner.enum_name);
constructor_injection.add(new LdcInsnNode(banner.enum_name));
System.out.println("Registering with identifier " + banner.identifier);
constructor_injection.add(new LdcInsnNode(banner.identifier));
constructor_injection.add(new FieldInsnNode(Opcodes.GETSTATIC, "lotr/common/fac/LOTRFaction", banner.faction, "Llotr/common/fac/LOTRFaction;"));
constructor_injection.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "lotr/common/item/LOTRItemBanner$BannerType", "<init>", "(Ljava/lang/String;IILjava/lang/String;Llotr/common/fac/LOTRFaction;)V", false));
constructor_injection.add(new FieldInsnNode(Opcodes.PUTSTATIC, "lotr/common/item/LOTRItemBanner$BannerType", banner.enum_name, "Llotr/common/item/LOTRItemBanner$BannerType;"));
}
// Insert the new instructions
if (constructor_injection_point != null) {
insns.insertBefore(constructor_injection_point, constructor_injection);
}
// Modifying the $VALUES array
// Create new instruction list to be injected later
InsnList values_array_injection = new InsnList();
// Add instructions to the instruction list
for (BannerInfo banner : custom_banners) {
values_array_injection.add(new InsnNode(Opcodes.DUP));
values_array_injection.add(new FieldInsnNode(Opcodes.GETSTATIC, "lotr/common/item/LOTRItemBanner$BannerType", banner.enum_name, "Llotr/common/item/LOTRItemBanner$BannerType;"));
values_array_injection.add(new InsnNode(Opcodes.AASTORE));
}
// Find the putstatic instruction for $VALUES
// This is where the fields are injected into a list, we want to inject our instructions before this
AbstractInsnNode values_injection_point = null;
while (constructor_injection_point != null) {
constructor_injection_point = constructor_injection_point.getNext();
if (constructor_injection_point.getOpcode() == Opcodes.PUTSTATIC) {
values_injection_point = constructor_injection_point;
break;
}
}
// Insert the new instructions before the putstatic instruction
if (values_injection_point != null) {
insns.insertBefore(values_injection_point, values_array_injection);
}
// Write the modified class back to a byte array
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
classNode.accept(classWriter);
return classWriter.toByteArray(); // Return the modified class
}
return basicClass; // Return the unmodified class for all other classes
}
public void register(String enum_name, String identifier, int ordinal, String faction) {
System.out.println("Registering banner " + enum_name + " " + identifier);
custom_banners.add(new BannerInfo(enum_name, identifier, ordinal, faction));
}
public class BannerInfo {
String enum_name;
String identifier;
int ordinal;
String faction;
public BannerInfo(String enum_name, String identifier, int ordinal, String faction) {
this.enum_name = enum_name;
this.identifier = identifier;
this.ordinal = ordinal;
this.faction = faction;
}
}
}
Loading…
Cancel
Save