Jump to content

Modifying Jar Classes


BlueSpud
 Share

Recommended Posts

I want to modify some of the functions in the jar, but I know installing modified class files is a haste. I thought ASM transformers were what I needed, but I haven't had any luck. If someone could point me in the right direction, that would be greatly appreciated. Thanks.

Link to comment
Share on other sites

EDIT: I was able to make the coremod load by adding a command line load in Eclipse, but I still don't know how I would override functions, so I can change them completely.

 

 

I do need base edits, I'm modifying several functions that Forge can't change. My problem is that the coremod won't load. I'm in eclipse, and here is all my code:

 

Transformer

package DHNCore.asm;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import cpw.mods.fml.common.asm.transformers.AccessTransformer;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.TransformerExclusions;


public class DHNAccessTransformer extends AccessTransformer {
  private static DHNAccessTransformer instance;
      private static List mapFiles = new LinkedList();
      public DHNAccessTransformer() throws IOException {
              super();
              instance = this;
              // add your access transformers here!
              mapFiles.add("DHN_at.cfg");
              Iterator it = mapFiles.iterator();
              while (it.hasNext()) {
                      String file = (String)it.next();
                      this.readMapFile(file);
              }
              
      }
      public static void addTransformerMap(String mapFileName) {
              if (instance == null) {
                      mapFiles.add(mapFileName);
              }
              else {
                      instance.readMapFile(mapFileName);
              }
      }
      private void readMapFile(String name) {
              System.out.println("Adding transformer map: " + name);
              try {
                      // get a method from AccessTransformer
                      Method e = AccessTransformer.class.getDeclaredMethod("readMapFile", new Class[]{String.class});
                      e.setAccessible(true);
                      // run it with the file given.
                      e.invoke(this, new Object[]{name});
                      
              }
              catch (Exception ex) {
                      throw new RuntimeException(ex);
              }
      }
      
}

Loader

package DHNCore.asm;

import java.util.Map;

import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.TransformerExclusions;

@TransformerExclusions({"DHNCore.asm"})
public class DHNLoadingPlugin implements IFMLLoadingPlugin {

@Override
public String[] getLibraryRequestClass() {
	// TODO Auto-generated method stub
	return null;
}

@Override
public String[] getASMTransformerClass() {
	// TODO Auto-generated method stub
	return new String[] {"DHNCore.asm.DHNAccessTransformer"};
}

@Override
public String getModContainerClass() {
	// TODO Auto-generated method stub
	return "DHNCore.asm.DHNModContainer";
}

@Override
public String getSetupClass() {
	// TODO Auto-generated method stub
	return null;
}

@Override
public void injectData(Map<String, Object> data) {
	// TODO Auto-generated method stub

}

}

Mod Container

package DHNCore.asm;

import cpw.mods.fml.common.DummyModContainer;


import java.util.Arrays;
import java.util.Random;


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.FMLServerStartingEvent;

public class DHNModContainer extends DummyModContainer {
        public DHNModContainer() {
                super(new ModMetadata());
                /* ModMetadata is the same as mcmod.info */
                ModMetadata myMeta = super.getMetadata();
                myMeta.authorList = Arrays.asList(new String[] { "BlueSpud" });
                myMeta.description = "Dishonored Core Mod";
                myMeta.modId = "DHNCORE";
                myMeta.version = "1.6.1";
                myMeta.name = "Dishonored Core";
                myMeta.url = "";
        }
        
        public boolean registerBus(EventBus bus, LoadController controller) {
        bus.register(this);
        return true;
        }
        /* 
         * Use this in place of @Init, @Preinit, @Postinit in the file.
         */
        @Subscribe                 /* Remember to use the right event! */
        public void onServerStarting(FMLServerStartingEvent ev) {
                ev.getServer().worldServerForDimension(0).spawnHostileMobs = false;
                System.out.printf("DHNCore has Loaded%n");
        }
        
}

for the config I just copied the tutorial on the wiki

 

# Tutorial Access Transformers.
########### THESE ARE DIFFERENT IN 1.4 ################
# Lines starting with a '#' are comments and aren't needed, although it's a good idea to label them so you know what changes what.

# World
# So to make a field public, put something like this:
public abr.E # spawnHostileMobs
# In 1.4, the above line would be "public xe.F"

Manifest

Manifest-Version: 1.0
FMLCorePlugin: DHNCORE.asm.DHNLoadingPlugin

Link to comment
Share on other sites

1) ASM should ALWAYS be a last resort, so what are you trying to do?

2) Your transformer is a lot more cplicated then it needs to be...

This is Forge's

public class ForgeAccessTransformer extends AccessTransformer
{
    public ForgeAccessTransformer() throws IOException
    {
        super("forge_at.cfg");
    }
}

And for as to why your coremod isnt loading, you need to pass in the proper environment parameters. fml.coreMods.load

I do Forge for free, however the servers to run it arn't free, so anything is appreciated.
Patreon: http://www.patreon.com/lexmanos
Paypal: http://paypal.me/LexManos

BitCoin: 1Q8rWvUNMM2T1ZfDaFeeYQyVXtYoeT6tTn

Link to comment
Share on other sites

1) ASM should ALWAYS be a last resort, so what are you trying to do?

2) Your transformer is a lot more cplicated then it needs to be...

This is Forge's

public class ForgeAccessTransformer extends AccessTransformer
{
    public ForgeAccessTransformer() throws IOException
    {
        super("forge_at.cfg");
    }
}

And for as to why your coremod isnt loading, you need to pass in the proper environment parameters. fml.coreMods.load

 

After looking around more, I found I needed to add the environment parameters. I also found a tutorial, but I'm having trouble replacing the instructions. Here is the link: http://www.minecraftforum.net/topic/1854988-tutorial-152161-changing-vanilla-without-editing-base-classes-coremods-and-events-very-advanced/ If you could help, that would still be great. (PS I downloaded the bytecode addon for eclipse, but after a bit of trying, I haven't' had any luck :( )

I also changed my code from above, and here it is:

package DHNCore.asm;

import static org.objectweb.asm.Opcodes.FDIV;

import java.io.IOException;
import java.util.Iterator;

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.MethodNode;
import org.omg.CORBA.portable.InputStream;


public class DHNTransformer implements net.minecraft.launchwrapper.IClassTransformer {
public byte[] patch (String name, byte[] bytes, String obfname, String iFile, String rname) throws IOException
{
	ClassNode cn = new ClassNode();
	ClassReader cr = new ClassReader(bytes);

	java.io.InputStream in = DHNTransformer.class.getResourceAsStream("/DHNCore/asm/Methods.class");
	ClassNode cnr = new ClassNode();
	ClassReader crr = new ClassReader(in);
	crr.accept(cnr, 0);
	cr.accept(cn, 0);
	Iterator<MethodNode> methods = cn.methods.iterator();
	Iterator<MethodNode> methodsr = cnr.methods.iterator();
	MethodNode mnr = null;
	while (methodsr.hasNext())
	{
		MethodNode temp = methodsr.next();
		System.out.printf("Methods that can be used to replaced are: %s %n", temp.name);
		if (temp.name.equals("rname"))
		{
			mnr = temp;
		}
	}

	while(methods.hasNext())
	{
		MethodNode mn = methods.next();
		System.out.printf("METHOD FOUND: %s %n",mn.name);
		if (mn.name.equals(name) || mn.name.equals(obfname))
			{
			//begin patching
			System.out.printf("Beginning the patching of the method %s %n",name);
			//patching jargin here
			mn.instructions = mnr.instructions;
			System.out.printf("Pathcing has been completed %n");
			}
	}
	ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
	cn.accept(cw);

	return cw.toByteArray();

}
@Override
public byte[] transform(String arg0, String arg1, byte[] arg2) 
{
	if (arg0.equals("bgy")) {
		System.out.println("Doing RenderPlayer transformers in a obfuscated environment");

		}

		if (arg0.equals("net.minecraft.client.renderer.entity.RenderPlayer")) {
		System.out.println("Doing RenderPlayer transformers in a de-obfuscated environment");
		try {
			return patch("renderFirstPersonArm", arg2, "","","renderFirstPersonArm");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		}
	return arg2;

}


}

 

Link to comment
Share on other sites

As the topic you found states this is a quite advanced topic. I don't suggest trying to write a ClassTransformer if you're not at least a bit familar with how java works internally (understandings of what bytecode even is and how it works).

 

You won't get around reading up about that and learning it.

 

Again: Please tell us your end-goal, it may be achieved much easier.

Link to comment
Share on other sites

I did some reading up, and I figured out the problem. My end goal was to replace a function in the jar with a function I can write anywhere in the rest of my mod. I achieved exactly what I needed to, thank you for all your help.

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
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.

 Share



×
×
  • Create New...

Important Information

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