// Path: src/main/java/com/techjar/vivecraftforge/util/VivecraftForgeLog.java
// public class VivecraftForgeLog {
// 	public static void info(String message, Object... data) {
// 		FMLRelaunchLog.log("Vivecraft Forge Extensions", Level.INFO, message, data);
// 	}
// 
// 	public static void warning(String message, Object... data) {
// 		FMLRelaunchLog.log("Vivecraft Forge Extensions", Level.WARN, message, data);
// 	}
// 
// 	public static void severe(String message, Object... data) {
// 		FMLRelaunchLog.log("Vivecraft Forge Extensions", Level.ERROR, message, data);
// 	}
// 
// 	public static void debug(String message, Object... data) {
// 		FMLRelaunchLog.log("Vivecraft Forge Extensions", Level.DEBUG, message, data);
// 	}
// }


import java.util.ArrayList;
import java.util.Iterator;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import com.techjar.vivecraftforge.util.VivecraftForgeLog;
package com.techjar.vivecraftforge.core.asm;




public abstract class ASMClassHandler {
	public abstract ClassTuple getDesiredClass();
	public abstract ASMMethodHandler[] getMethodHandlers();
	public abstract boolean getComputeFrames();
	
	public boolean shouldPatchClass() {
		return true;
	}
	
	protected void patchClass(ClassNode node, boolean obfuscated) {
	}
	
	public final byte[] patchClass(byte[] bytes, boolean obfuscated) {
		ClassNode classNode = new ClassNode();
		ClassReader classReader = new ClassReader(bytes);
		classReader.accept(classNode, 0);
		patchClass(classNode, obfuscated);
		ASMMethodHandler[] handlers = getMethodHandlers();
		ArrayList<MethodNode> methodsCopy = new ArrayList<MethodNode>(classNode.methods);
		for (Iterator<MethodNode> methods = methodsCopy.iterator(); methods.hasNext(); ) {
			MethodNode method = methods.next();
			for (ASMMethodHandler handler : handlers) {
				MethodTuple tuple = handler.getDesiredMethod();
				if ((method.name.equals(tuple.methodName) && method.desc.equals(tuple.methodDesc)) || (method.name.equals(tuple.methodNameObf) && method.desc.equals(tuple.methodDescObf))) {
// Path: src/main/java/com/techjar/vivecraftforge/util/VivecraftForgeLog.java
// public class VivecraftForgeLog {
// 	public static void info(String message, Object... data) {
// 		FMLRelaunchLog.log("Vivecraft Forge Extensions", Level.INFO, message, data);
// 	}
// 
// 	public static void warning(String message, Object... data) {
// 		FMLRelaunchLog.log("Vivecraft Forge Extensions", Level.WARN, message, data);
// 	}
// 
// 	public static void severe(String message, Object... data) {
// 		FMLRelaunchLog.log("Vivecraft Forge Extensions", Level.ERROR, message, data);
// 	}
// 
// 	public static void debug(String message, Object... data) {
// 		FMLRelaunchLog.log("Vivecraft Forge Extensions", Level.DEBUG, message, data);
// 	}
// }


// Path: src/main/java/com/techjar/vivecraftforge/core/asm/ASMClassHandler.java
import java.util.ArrayList;
import java.util.Iterator;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import com.techjar.vivecraftforge.util.VivecraftForgeLog;

package com.techjar.vivecraftforge.core.asm;




public abstract class ASMClassHandler {
	public abstract ClassTuple getDesiredClass();
	public abstract ASMMethodHandler[] getMethodHandlers();
	public abstract boolean getComputeFrames();
	
	public boolean shouldPatchClass() {
		return true;
	}
	
	protected void patchClass(ClassNode node, boolean obfuscated) {
	}
	
	public final byte[] patchClass(byte[] bytes, boolean obfuscated) {
		ClassNode classNode = new ClassNode();
		ClassReader classReader = new ClassReader(bytes);
		classReader.accept(classNode, 0);
		patchClass(classNode, obfuscated);
		ASMMethodHandler[] handlers = getMethodHandlers();
		ArrayList<MethodNode> methodsCopy = new ArrayList<MethodNode>(classNode.methods);
		for (Iterator<MethodNode> methods = methodsCopy.iterator(); methods.hasNext(); ) {
			MethodNode method = methods.next();
			for (ASMMethodHandler handler : handlers) {
				MethodTuple tuple = handler.getDesiredMethod();
				if ((method.name.equals(tuple.methodName) && method.desc.equals(tuple.methodDesc)) || (method.name.equals(tuple.methodNameObf) && method.desc.equals(tuple.methodDescObf))) {
					VivecraftForgeLog.debug("Patching method: " + method.name + method.desc + (obfuscated ? " (" + tuple.methodName + tuple.methodDesc + ")" : ""));