Jump to content

Reflection or ASM


coolboy4531

Recommended Posts

Which would would be better if I were to change the enchantment level caps on all enchantments?

Such as Protection 5 to Protection (insert number).

 

Would Reflection be a solid choice and would that work?

Or am I forced to use ASM?

 

Also, where do I find the location of obfuscated field names/class names such as it used to be fields.csv (a long time ago) and notch-mcp.srg (dunno where I last saw this)?

Link to comment
Share on other sites

For some strange reason, the mod won't run outside of Eclipse environment.

It doesn't initialize and the mod won't run.

 

Code:

 

FMLLoadingPlugin

package com.sec;

import java.util.Map;

import cpw.mods.fml.common.Mod;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion;

@MCVersion(value = "1.7.10")
public class SEFMLLoadingPlugin implements IFMLLoadingPlugin {

@Override
public String[] getASMTransformerClass() {
	return new String[]{ SEClassTransformer.class.getName() };
}

@Override
public String getModContainerClass() {
	return SEContainer.class.getName();
}

@Override
public String getSetupClass() {
	return null;
}

@Override
public void injectData(Map<String, Object> data) {

}

@Override
public String getAccessTransformerClass() {
	return null;
}
}

 

Container

package com.sec;

import java.util.Arrays;

import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;

import cpw.mods.fml.common.DummyModContainer;
import cpw.mods.fml.common.LoadController;
import cpw.mods.fml.common.ModMetadata;
import cpw.mods.fml.common.event.FMLConstructionEvent;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;

public class SEContainer extends DummyModContainer {

public SEContainer() {
	super(new ModMetadata());
	ModMetadata meta = getMetadata();
	meta.modId = "se";
	meta.name = "EnchantmentCapIncreaser";
	meta.version = "0.1";
	meta.credits = "";
	meta.authorList = Arrays.asList("coolboy4531");
	meta.description = "Modifies vanilla enchantments to have a higher enchantment cap.";
	meta.url = "";
	meta.updateUrl = "";
	meta.screenshots = new String[0];
	meta.logoFile = "";
}

@Override
public boolean registerBus(EventBus bus, LoadController controller)  {
	bus.register(this);
	return true;
}

@Subscribe
public void modConstruction(FMLConstructionEvent e) {

}

@Subscribe
public void preInit(FMLPreInitializationEvent e) {

}

@Subscribe
public void init(FMLInitializationEvent e) {

}

@Subscribe
public void postInit(FMLPostInitializationEvent e) {

}
}

 

ClassTransformer:

package com.sec;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;

import net.minecraft.launchwrapper.IClassTransformer;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentArrowDamage;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.IntInsnNode;
import org.objectweb.asm.tree.MethodNode;

public class SEClassTransformer implements IClassTransformer {

private static final HashMap<Integer, Integer> intCodes = new HashMap();

private static ArrayList<String> unobfList = new ArrayList(Arrays.asList(new String[] { 
		"net.minecraft.enchantment.EnchantmentArrowDamage", 
		"net.minecraft.enchantment.EnchantmentArrowFire", 
		"net.minecraft.enchantment.EnchantmentArrowInfinite", 
		"net.minecraft.enchantment.EnchantmentArrowKnockback", 
		"net.minecraft.enchantment.EnchantmentDamage", 
		"net.minecraft.enchantment.EnchantmentDurability", 
		"net.minecraft.enchantment.EnchantmentDigging", 
		"net.minecraft.enchantment.EnchantmentFireAspect", 
		"net.minecraft.enchantment.EnchantmentKnockback", 
		"net.minecraft.enchantment.EnchantmentLootBonus", 
		"net.minecraft.enchantment.EnchantmentOxygen", 
		"net.minecraft.enchantment.EnchantmentProtection",
		 "net.minecraft.enchantment.EnchantmentThorns", 
		"net.minecraft.enchantment.EnchantmentUntouching", 
		"net.minecraft.enchantment.EnchantmentWaterWorker"
	 }));	

private static int[] vanillaLevels = { 5, 1, 1, 2, 5, 3, 5, 2, 2, 3, 3, 4, 3, 1, 1 };

private static int[] seLevels = { 10, 1, 1, 5, 10, 5, 10, 5, 5, 5, 3, 10, 5, 1, 1 };

public byte[] transform(String classname, String arg1, byte[] bytearray)
{
	int e_index = 0;

	if (unobfList.contains(arg1))
	{
		e_index = unobfList.indexOf(classname);
		System.out.println("Ready to transform: " + classname);
		return patchClassASM(classname, bytearray, false, e_index);
	}
	return bytearray;
}

public byte[] patchClassASM(String name, byte[] b, boolean obf, int e_index)
{
	String methodName = "";

	if (obf == true)
		methodName = "b";
			else
				methodName = "getMaxLevel";

	ClassNode cn = new ClassNode();
	ClassReader cr = new ClassReader(b);
	cr.accept(cn, 0);
	Iterator methods = cn.methods.iterator();

	while (methods.hasNext())
	{
		MethodNode mn = (MethodNode)methods.next();
		int fdiv_index = -1;

		if ((mn.name.equals(methodName)) && (mn.desc.equals("()I")))
		{
			AbstractInsnNode newinst;
			AbstractInsnNode currentNode = null;
			AbstractInsnNode targetNode = null;
			Iterator it = mn.instructions.iterator();
			int index = -1;

			while (it.hasNext())
			{
				index++;
				currentNode = (AbstractInsnNode)it.next();

				if (currentNode.getOpcode() != ((Integer)intCodes.get(Integer.valueOf(vanillaLevels[e_index]))).intValue())
					continue;
				System.out.println("Bytecode verified [" + currentNode.getOpcode() + "]");
				targetNode = currentNode;
				fdiv_index = index;
			}

			if (targetNode == null)
			{
				return b;
			}

			if (fdiv_index == -1)
			{
				return b;
			}

			AbstractInsnNode ourNode = mn.instructions.get(fdiv_index);

			if (vanillaLevels[e_index] == seLevels[e_index])
				break;
			System.out.println("Changing enchantment level cap.");
			if (seLevels[e_index] > 5)
				newinst = new IntInsnNode(((Integer)intCodes.get(Integer.valueOf(seLevels[e_index]))).intValue(), seLevels[e_index]);
			else
				newinst = new InsnNode(((Integer)intCodes.get(Integer.valueOf(seLevels[e_index]))).intValue());

			mn.instructions.set(ourNode, newinst);
			System.out.println("Finished patching successfully."); 
				break;
		}
	}

	ClassWriter writer = new ClassWriter(3);
	cn.accept(writer);
	return writer.toByteArray();
}
static {
	intCodes.put(Integer.valueOf(1), Integer.valueOf(4));
    intCodes.put(Integer.valueOf(2), Integer.valueOf(5));
    intCodes.put(Integer.valueOf(3), Integer.valueOf(6));
    intCodes.put(Integer.valueOf(4), Integer.valueOf(7));
    intCodes.put(Integer.valueOf(5), Integer.valueOf();
    intCodes.put(Integer.valueOf(10), Integer.valueOf(16));
}
}

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.