/*
 * Copyright 2018 ImpactDevelopment
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package clientapi.load;

import clientapi.load.transform.ITransformer;
import clientapi.load.transform.impl.ValueAccessorTransformer;
import com.google.common.collect.ImmutableList;
import net.minecraft.launchwrapper.IClassTransformer;
import org.apache.commons.lang3.ArrayUtils;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;

import java.util.List;
import java.util.stream.Collectors;

/**
 * Implementation of {@code IClassTransformer} used to run all {@code ITransformer}s.
 *
 * @author Brady
 * @since 9/15/2017 9:39 PM
 */
public final class ClientTransformer implements IClassTransformer {

    /**
     * {@code ImmutableList} of all transformers.
     */
    private static final ImmutableList<ITransformer> transformers = new ImmutableList.Builder<ITransformer>()
            .add(new ValueAccessorTransformer())
            .build();

    @Override
    public byte[] transform(String name, String transformedName, byte[] basicClass) {
        List<ITransformer> transformers = getTransformers(transformedName);

        if (!transformers.isEmpty()) {
            ClassNode cn = getClassNode(basicClass);
            if (cn == null)
                return basicClass;

            // Run all transformers on the Class
            transformers.forEach(transformer -> transformer.transform(cn));

            // Return transformed class bytecode
            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
            cn.accept(cw);
            return cw.toByteArray();
        }

        return basicClass;
    }

    /**
     * Finds transformers that target the specified class.
     * If a transformer doesn't have any targets, it is assumed
     * that it will accept any class.
     *
     * @param name Target class name
     * @return Valid transformers
     */
    private List<ITransformer> getTransformers(String name) {
        return transformers.stream()
                .filter(transformer -> transformer.getTargets().length == 0 || ArrayUtils.contains(transformer.getTargets(), name))
                .collect(Collectors.toList());
    }

    /**
     * Creates a {@code ClassNode} from specified bytecode
     *
     * @param bytecode Class bytecode
     * @return ClassNode
     */
    private ClassNode getClassNode(byte[] bytecode) {
        if (bytecode == null)
            return null;

        ClassNode cn = new ClassNode();
        new ClassReader(bytecode).accept(cn, 0);
        return cn;
    }
}

@@ -1724,24 +1724,46 @@
 sEmpty()) %7B%0A
+            try %7B%0A    
             
@@ -1811,24 +1811,28 @@
             
+   
+ 
 if (cn == nu
@@ -1827,32 +1827,36 @@
 if (cn == null)%0A
+    
                 
@@ -1883,24 +1883,28 @@
             
+ 
+   
 // Run all t
@@ -1940,16 +1940,20 @@
         
+   
+ 
 transfor
@@ -2017,24 +2017,28 @@
             
+    
 // Return tr
@@ -2070,24 +2070,28 @@
             
+ 
+   
 ClassWriter 
@@ -2179,16 +2179,20 @@
         
+   
+ 
 cn.accep
@@ -2198,16 +2198,20 @@
 pt(cw);%0A
+    
         
@@ -2235,24 +2235,67 @@
 yteArray();%0A
+            %7D catch (Exception ignored) %7B%7D%0A
         %7D%0A%0A 

Put try/catch around transformer apply