Browse Source

update to 1.14, test event

Kajetan Johannes Hammerle 4 years ago
parent
commit
1b0264934b

+ 2 - 0
.gitignore

@@ -7,3 +7,5 @@ gradlew
 /.gradle
 /.nb-gradle
 .nb-gradle-properties
+runClient.launch
+runServer.launch

+ 0 - 36
src/main/java/me/ktcm/KajetansLoadingPlugin.java

@@ -1,36 +0,0 @@
-package me.ktcm;
-
-import java.util.Map;
-import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
-
-public class KajetansLoadingPlugin implements IFMLLoadingPlugin
-{        
-    @Override
-    public String[] getASMTransformerClass() 
-    {
-        return new String[] {KajetansTransformer.class.getName()};
-    }
-
-    @Override
-    public String getModContainerClass() 
-    {
-        return null; //KajetansModContainer.class.getName();
-    }
-
-    @Override
-    public String getSetupClass() 
-    {
-        return null;//KajetansHooks.class.getName();
-    }
-
-    @Override
-    public void injectData(Map<String, Object> data) 
-    {
-    }
-
-    @Override
-    public String getAccessTransformerClass() 
-    {
-        return null;
-    }
-}

+ 10 - 23
src/main/java/me/ktcm/KajetansTextCoreMod.java

@@ -1,30 +1,17 @@
 package me.ktcm;
 
+import net.minecraft.util.text.StringTextComponent;
+import net.minecraftforge.event.ServerChatEvent;
+import net.minecraftforge.eventbus.api.SubscribeEvent;
 import net.minecraftforge.fml.common.Mod;
-import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
 
-@Mod(modid = KajetansTextCoreMod.MODID, version = KajetansTextCoreMod.VERSION, name = KajetansTextCoreMod.NAME, acceptableRemoteVersions = "*")
-public class KajetansTextCoreMod 
+@Mod.EventBusSubscriber
+@Mod("ktcm")
+public class KajetansTextCoreMod
 {
-    public static final String MODID = "ktcm";
-    public static final String NAME = "Kajetans Text Core Mod";
-    public static final String VERSION = "0.0.1";
-    
-    @Mod.EventHandler
-    public void preInit(FMLPreInitializationEvent e) 
+    @SubscribeEvent
+    public static void beforeStart(ServerChatEvent e) 
     {
-        System.out.println(NAME + " is loading!");
-        /*net.minecraftforge.common.MinecraftForge.EVENT_BUS.register(new Object()
-            {
-                @net.minecraftforge.fml.common.eventhandler.SubscribeEvent
-                public void wusi(ServerChatEvent e) 
-                {
-                    e.setComponent(new TextComponentString(
-                            "§0█§1█§2█§3█§4█§5█§6█§7█§8█§9█§a█§b█§c█§d█§e█§f█" + 
-                            "§g█§h█§i█§j█§p█§q█§s█§t█§u█§v█§w█§x█§y█§z█" + 
-                            "§0D§1a§2s §3i§4s§5t §6e§7i§8n §9S§ac§bh§cr§di§ef§ft" + 
-                            "§gt§he§is§jt §pH§qa§sl§tl§uo§vo§wo§xo§yo§zo"));
-                }
-            });*/
+        e.setComponent(new StringTextComponent(e.getMessage().replace("&", "§")));
     }
-}
+}

+ 0 - 198
src/main/java/me/ktcm/KajetansTransformer.java

@@ -1,198 +0,0 @@
-package me.ktcm;
-
-import net.minecraft.launchwrapper.IClassTransformer;
-import net.minecraft.launchwrapper.Launch;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.tree.AbstractInsnNode;
-import org.objectweb.asm.tree.ClassNode;
-import org.objectweb.asm.tree.FieldInsnNode;
-import org.objectweb.asm.tree.FrameNode;
-import org.objectweb.asm.tree.InsnList;
-import org.objectweb.asm.tree.InsnNode;
-import org.objectweb.asm.tree.LineNumberNode;
-import org.objectweb.asm.tree.MethodInsnNode;
-import org.objectweb.asm.tree.MethodNode;
-import org.objectweb.asm.tree.VarInsnNode;
-
-public class KajetansTransformer implements IClassTransformer
-{
-    private final boolean obfuscated;
-    
-    public KajetansTransformer() 
-    {
-        Boolean ldev = (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment");
-        if(ldev == null)
-        {
-            obfuscated = true;
-        }
-        else
-        {
-            obfuscated = !ldev;
-        }
-    }
-    
-    @Override
-    public byte[] transform(String old, String searge, byte[] bytes)
-    {
-        if(searge.equals("net.minecraft.client.gui.FontRenderer"))
-        {
-            //net.minecraft.client.gui.FontRenderer;
-            System.out.println("|‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾");
-            System.out.println("| Patching net.minecraft.client.gui.FontRenderer");
-            System.out.println("|___________________________________________________");
-            return patchColorHook(old, bytes);
-        }
-        return bytes;
-    }
-
-    public byte[] patchColorHook(String c, byte[] bytes)
-    {
-        try
-        {
-            ClassNode classNode = new ClassNode();
-            ClassReader classReader = new ClassReader(bytes);
-            classReader.accept(classNode, 0);
-            
-            // net/minecraft/client/gui/FontRenderer bip
-            // func_78255_a renderStringAtPos  Render a single line string at the current (posX,posY) and update posX
-            // MD: net/minecraft/client/gui/FontRenderer/renderStringAtPos (Ljava/lang/String;Z)V bip/a (Ljava/lang/String;Z)V
-            MethodNode mn;
-            if(obfuscated)
-            {
-                mn = classNode.methods.stream().filter(me -> me.name.equals("a")).filter(me -> "(Ljava/lang/String;Z)V".equals(me.desc)).findAny().get();
-            }
-            else
-            {
-                mn = classNode.methods.stream().filter(me -> me.name.equals("renderStringAtPos")).findAny().get();
-            }
-            
-            InsnList ins = mn.instructions;
-            int index = 0; 
-            boolean found = false;
-            AbstractInsnNode next;
-            while(index < ins.size())
-            {
-                next = ins.get(index);
-                if(next instanceof MethodInsnNode)
-                {
-                    MethodInsnNode mnode = (MethodInsnNode) next;
-                    if(mnode.name.equals("valueOf") && mnode.desc.equals("(C)Ljava/lang/String;"))
-                    {
-                        found = true;
-            
-                        // LdcInsnNode  18  9  - loading of string constant "0123456789abcdefklmnor", must be removed
-                        // VarInsnNode  25  2  1
-                        // VarInsnNode  21  2  3
-                        // InsnNode  4  0  
-                        // InsnNode  96  0  
-                        // MethodInsnNode  182  5  (I)C false charAt java/lang/String
-                        // insert new instruction here
-                        // MethodInsnNode  184  5  (C)Ljava/lang/String; false valueOf java/lang/String - search for this instruction, its not obfuscated
-                        // FieldInsnNode  178  4  Ljava/util/Locale; ROOT java/util/Locale - must be removed
-                        // MethodInsnNode  182  5  (Ljava/util/Locale;)Ljava/lang/String; false toLowerCase java/lang/String - must be removed
-                        // InsnNode  3  0  - must be removed
-                        // MethodInsnNode  182  5  (I)C false charAt java/lang/String - must be removed
-                        // MethodInsnNode  182  5  (I)I false indexOf java/lang/String - must be removed
-                        // VarInsnNode  54  2  5
-                        // LabelNode  -1  8  
-            
-                        index--;
-                        ins.remove(ins.get(index - 5)); // remove "0123456789abcdefklmnor"
-                        ins.remove(ins.get(index));
-                        ins.remove(ins.get(index));
-                        ins.remove(ins.get(index));
-                        ins.remove(ins.get(index));
-                        ins.remove(ins.get(index));
-                        ins.remove(ins.get(index));
-                        ins.insert(ins.get(index - 1), new MethodInsnNode(Opcodes.INVOKESTATIC, "me/ktcm/events/Hooks", "onColorCodeChosen", "(CZ)I", false));
-                        ins.insert(ins.get(index - 1), new VarInsnNode(Opcodes.ILOAD, 2)); // push boolean shadow on the stack, inverted order
-                        break;
-                    }
-                }
-                index++;
-            }
-            
-            if(!found)
-            {
-                System.out.println("Start of color hook was not found");
-                return bytes;
-            }
-            
-            /*java.util.ListIterator<AbstractInsnNode> list = ins.iterator();
-            while(list.hasNext())
-            {
-                System.out.println(getString(list.next()));
-            }*/
-
-            ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
-            classNode.accept(writer);
-            return writer.toByteArray();
-        }
-        catch(Exception ex)
-        {
-            ex.printStackTrace();
-        }       
-        return bytes;
-    }
-    
-    public String getString(AbstractInsnNode node)
-    {
-        StringBuilder sb = new StringBuilder();
-        sb.append(node.getClass().getSimpleName());
-        sb.append("  ");
-        sb.append(node.getOpcode());
-        sb.append("  ");
-        sb.append(node.getType());
-        sb.append("  ");
-        if(node instanceof LineNumberNode)
-        {
-            LineNumberNode n = (LineNumberNode) node;
-            sb.append(n.line);
-            sb.append(" ");
-            sb.append(n.start);
-        }
-        else if(node instanceof VarInsnNode)
-        {
-            VarInsnNode n = (VarInsnNode) node;
-            sb.append(n.var);
-        }
-        else if(node instanceof MethodInsnNode)
-        {
-            MethodInsnNode n = (MethodInsnNode) node;
-            sb.append(n.desc);
-            sb.append(" ");
-            sb.append(n.itf);
-            sb.append(" ");
-            sb.append(n.name);
-            sb.append(" ");
-            sb.append(n.owner);
-        }
-        else if(node instanceof FrameNode)
-        {
-            FrameNode n = (FrameNode) node;
-            if(n.local != null)
-            {
-                n.local.forEach(s -> {sb.append(s); sb.append(" ");});
-            }
-            if(n.stack != null)
-            {
-                n.stack.forEach(s -> {sb.append(s); sb.append(" ");});
-            }
-        }
-        else if(node instanceof InsnNode)
-        {
-        }
-        else if(node instanceof FieldInsnNode)
-        {
-            FieldInsnNode n = (FieldInsnNode) node;
-            sb.append(n.desc);
-            sb.append(" ");
-            sb.append(n.name);
-            sb.append(" ");
-            sb.append(n.owner);
-        }
-        return sb.toString();
-    }
-}

+ 0 - 165
src/main/java/me/ktcm/events/Hooks.java

@@ -1,165 +0,0 @@
-package me.ktcm.events;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import net.minecraft.client.Minecraft;
-import net.minecraftforge.fml.relauncher.ReflectionHelper;
-import net.minecraft.client.gui.FontRenderer;
-
-public class Hooks 
-{
-    public static int onColorCodeChosen(char c, boolean shadow)
-    {
-        switch(c)
-        {
-            case '0': return 0;
-            case '1': return 1;
-            case '2': return 2;
-            case '3': return 3;
-            case '4': return 4;
-            case '5': return 5;
-            case '6': return 6;
-            case '7': return 7;
-            case '8': return 8;
-            case '9': return 9;
-            case 'a': return 10;
-            case 'b': return 11;
-            case 'c': return 12;
-            case 'd': return 13;
-            case 'e': return 14;
-            case 'f': return 15;
-            case 'k': return 16;
-            case 'l': return 17;
-            case 'm': return 18;
-            case 'n': return 19;
-            case 'o': return 20;
-            case 'r': return 21;
-            case 'A': return 10;
-            case 'B': return 11;
-            case 'C': return 12;
-            case 'D': return 13;
-            case 'E': return 14;
-            case 'F': return 15;
-            case 'K': return 16;
-            case 'L': return 17;
-            case 'M': return 18;
-            case 'N': return 19;
-            case 'O': return 20;
-            case 'R': return 21;
-            
-            // brown
-            case 'g': 
-            case 'G': setColor(shadow, 0.4f, 0.2f, 0.0f, 0.1f, 0.05f, 0.0f); return 22;
-            case 'h': 
-            case 'H': setColor(shadow, 0.6f, 0.4f, 0.2f, 0.15f, 0.1f, 0.05f); return 22;
-            
-            // blue
-            case 'i': 
-            case 'I': setColor(shadow, 0.0f, 0.2f, 0.4f, 0.0f, 0.05f, 0.1f); return 22;
-            case 'j': 
-            case 'J': setColor(shadow, 0.0f, 0.4f, 0.6f, 0.0f, 0.1f, 0.15f); return 22;
-            
-            // green
-            case 'p': 
-            case 'P': setColor(shadow, 0.4f, 0.6f, 0.0f, 0.1f, 0.15f, 0.0f); return 22;
-            case 'q': 
-            case 'Q': setColor(shadow, 0.6f, 0.8f, 0.0f, 0.15f, 0.2f, 0.0f); return 22;
-            
-            // cyan
-            case 's': 
-            case 'S': setColor(shadow, 0.0f, 0.6f, 1.0f, 0.0f, 0.15f, 0.25f); return 22;
-            case 't': 
-            case 'T': setColor(shadow, 0.4f, 0.8f, 1.0f, 0.1f, 0.2f, 0.25f); return 22;
-            
-            // red
-            case 'u': 
-            case 'U': setColor(shadow, 0.6f, 0.2f, 0.0f, 0.15f, 0.05f, 0.0f); return 22;
-            case 'v': 
-            case 'V': setColor(shadow, 0.8f, 0.4f, 0.0f, 0.2f, 0.1f, 0.0f); return 22;
-            
-            
-            // violet
-            case 'w': 
-            case 'W': setColor(shadow, 0.4f, 0.0f, 0.4f, 0.1f, 0.0f, 0.1f); return 22;
-            case 'x': 
-            case 'X': setColor(shadow, 0.6f, 0.0f, 0.8f, 0.15f, 0.0f, 0.2f); return 22;
-            
-            // yellow
-            case 'y': 
-            case 'Y': setColor(shadow, 0.8f, 0.6f, 0.0f, 0.2f, 0.15f, 0.0f); return 22;
-            case 'z': 
-            case 'Z': setColor(shadow, 1.0f, 0.8f, 0.0f, 0.25f, 0.2f, 0.0f); return 22;
-        }
-        return -1;
-    }
-    
-    private static void setColor(boolean shadow, float r, float g, float b, float dr, float dg, float db)
-    {
-        if(shadow)
-        {
-            setColor(dr, dg, db);
-        }
-        else
-        {
-            setColor(r, g, b);
-        }
-    }
-    
-    private static Method getMethod(Class c, String name, String oName, Class... classes)
-    {
-        try
-        {
-            return ReflectionHelper.findMethod(c, name, oName, classes);
-        }
-        catch(SecurityException | ReflectionHelper.UnableToFindFieldException ex)
-        {
-            System.out.println(name + " - " + oName + " - " + ex);
-        }
-        return null;
-    }
-    
-    private static Field getField(Class c, String... field)
-    {
-        try
-        {
-            return ReflectionHelper.findField(c, field);
-        }
-        catch(SecurityException | ReflectionHelper.UnableToFindFieldException ex)
-        {
-            System.out.println(String.join(" - ", field) + " - " + ex);
-        }
-        return null;
-    }
-    
-    private final static FontRenderer FONT = Minecraft.getMinecraft().fontRenderer;
-    // /home/kajetan/.gradle/caches/minecraft/de/oceanlabs/mcp/mcp_snapshot/20171003/1.12.2/srgs/mcp-srg.srg
-    // FD: net/minecraft/client/gui/FontRenderer/alpha net/minecraft/client/gui/FontRenderer/field_78305_q
-    private final static Field ALPHA = getField(FontRenderer.class, "field_78305_q", "alpha");
-    
-    public static float getAlpha()
-    {
-        try
-        {
-            return ALPHA.getFloat(FONT);
-        }
-        catch(SecurityException | IllegalAccessException | IllegalArgumentException ex)
-        {
-            return 1;
-        }
-    }
-    
-    private final static Method SET_COLOR = getMethod(FontRenderer.class, "setColor", null, float.class, float.class, float.class, float.class);
-    
-    public static void setColor(float r, float g, float b)
-    {
-        try
-        {
-            SET_COLOR.invoke(FONT, r, g, b, getAlpha());
-        }
-        catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException ex)
-        {
-            ex.printStackTrace();
-        }
-    }
-}

+ 115 - 0
src/main/java/me/ktcm/text/ModTextFormatting.java

@@ -0,0 +1,115 @@
+package me.ktcm.text;
+
+import java.util.Locale;
+import javax.annotation.Nullable;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+
+public enum ModTextFormatting
+{
+    BLACK("BLACK", '0', 0, 0),
+    DARK_BLUE("DARK_BLUE", '1', 1, 170),
+    DARK_GREEN("DARK_GREEN", '2', 2, 43520),
+    DARK_AQUA("DARK_AQUA", '3', 3, 43690),
+    DARK_RED("DARK_RED", '4', 4, 11141120),
+    DARK_PURPLE("DARK_PURPLE", '5', 5, 11141290),
+    GOLD("GOLD", '6', 6, 16755200),
+    GRAY("GRAY", '7', 7, 11184810),
+    DARK_GRAY("DARK_GRAY", '8', 8, 5592405),
+    BLUE("BLUE", '9', 9, 5592575),
+    GREEN("GREEN", 'a', 10, 5635925),
+    AQUA("AQUA", 'b', 11, 5636095),
+    RED("RED", 'c', 12, 16733525),
+    LIGHT_PURPLE("LIGHT_PURPLE", 'd', 13, 16733695),
+    YELLOW("YELLOW", 'e', 14, 16777045),
+    WHITE("WHITE", 'f', 15, 16777215),
+    // start of new colors
+    // http://chir.ag/projects/name-that-color/
+    DARK_BROWN("DARK_BROWN", 'g', 16, buildColor(0.4f, 0.2f, 0.0f)),
+    LIGHT_BROWN("LIGHT_BROWN", 'h', 17, buildColor(0.6f, 0.4f, 0.2f)),
+    MIDNIGHT_BLUE("MIDNIGHT_BLUE", 'i', 18, buildColor(0.0f, 0.2f, 0.4f)),
+    BAHAMA_BLUE("BAHAMA_BLUE", 'j', 19, buildColor(0.0f, 0.4f, 0.6f)),
+    LIMEADE("LIMEADE", 'p', 20, buildColor(0.4f, 0.6f, 0.0f)),
+    PISTACHIO("PISTACHIO", 'q', 21, buildColor(0.6f, 0.8f, 0.0f)),
+    AZURE_RADIANCE("AZURE_RADIANCE", 's', 22, buildColor(0.0f, 0.6f, 1.0f)),
+    MALIBU("MALIBU", 't', 23, buildColor(0.4f, 0.8f, 1.0f)),
+    OREGON("OREGON", 'u', 24, buildColor(0.6f, 0.2f, 0.0f)),
+    TENN("TENN", 'v', 25, buildColor(0.8f, 0.4f, 0.0f)),
+    BUDDHA_GOLD("BUDDHA_GOLD", 'w', 26, buildColor(0.4f, 0.0f, 0.4f)),
+    SUPERNOVA("SUPERNOVA", 'x', 27, buildColor(0.6f, 0.0f, 0.8f)),
+    POMPADOUR("POMPADOUR", 'y', 28, buildColor(0.8f, 0.6f, 0.0f)),
+    ELECTRIC_VIOLET("ELECTRIC_VIOLET", 'z', 29, buildColor(1.0f, 0.8f, 0.0f)),
+    // end of new colors
+    OBFUSCATED("OBFUSCATED", 'k', true),
+    BOLD("BOLD", 'l', true),
+    STRIKETHROUGH("STRIKETHROUGH", 'm', true),
+    UNDERLINE("UNDERLINE", 'n', true),
+    ITALIC("ITALIC", 'o', true),
+    RESET("RESET", 'r', -1, null);
+    
+    private static int buildColor(float r, float g, float b)
+    {
+        int ir = (int) (255 * r);
+        int ig = (int) (255 * g);
+        int ib = (int) (255 * b);
+        return (ir << 16) | (ig << 8) | (ib);
+    }
+
+    private final String name;
+    private final char formattingCode;
+    private final boolean fancyStyling;
+    private final String controlString;
+    private final int colorIndex;
+    @Nullable
+    private final Integer color;
+
+    private ModTextFormatting(String formattingName, char formattingCodeIn, int index, @Nullable Integer colorCode)
+    {
+        this(formattingName, formattingCodeIn, false, index, colorCode);
+    }
+
+    private ModTextFormatting(String formattingName, char formattingCodeIn, boolean fancyStylingIn)
+    {
+        this(formattingName, formattingCodeIn, fancyStylingIn, -1, (Integer) null);
+    }
+
+    private ModTextFormatting(String formattingName, char formattingCodeIn, boolean fancyStylingIn, int index, @Nullable Integer colorCode)
+    {
+        this.name = formattingName;
+        this.formattingCode = formattingCodeIn;
+        this.fancyStyling = fancyStylingIn;
+        this.colorIndex = index;
+        this.color = colorCode;
+        this.controlString = "\u00a7" + formattingCodeIn;
+    }
+
+    @Nullable
+    @OnlyIn(Dist.CLIENT)
+    public Integer getColor()
+    {
+        return this.color;
+    }
+
+    @OnlyIn(Dist.CLIENT)
+    public boolean isNormalStyle()
+    {
+        return !this.fancyStyling;
+    }
+
+    @Nullable
+    @OnlyIn(Dist.CLIENT)
+    public static ModTextFormatting fromFormattingCode(char formattingCodeIn)
+    {
+        char c0 = Character.toString(formattingCodeIn).toLowerCase(Locale.ROOT).charAt(0);
+
+        for(ModTextFormatting textformatting : values())
+        {
+            if(textformatting.formattingCode == c0)
+            {
+                return textformatting;
+            }
+        }
+
+        return null;
+    }
+}

+ 3 - 0
src/main/resources/META-INF/coremods.json

@@ -0,0 +1,3 @@
+{
+    "Font Renderer Transformer": "class_transformer/font_renderer.js"
+}

+ 12 - 0
src/main/resources/META-INF/mods.toml

@@ -0,0 +1,12 @@
+modLoader="javafml"
+loaderVersion="[26,)"
+[[mods]]
+modId="ktcm"
+version="0.0.1"
+side="CLIENT"
+displayName="Kajetans Text Core Mod"
+credits="kajetanjohannes"
+authors="kajetanjohannes"
+description='''
+Kajetans Text Core Mod for Mundus Crassus
+'''

+ 54 - 0
src/main/resources/class_transformer/font_renderer.js

@@ -0,0 +1,54 @@
+var transformerName = "Font Renderer Transformer";
+var ASMAPI = Java.type('net.minecraftforge.coremod.api.ASMAPI');
+var Opcodes = Java.type('org.objectweb.asm.Opcodes');
+var MethodInsnNode = Java.type("org.objectweb.asm.tree.MethodInsnNode");
+var FieldInsnNode = Java.type("org.objectweb.asm.tree.FieldInsnNode");
+
+function initializeCoreMod() {
+    return {
+        transformerName: {
+            'target': {
+                'type': 'CLASS',
+                'name': 'net.minecraft.client.gui.FontRenderer'
+            },
+            'transformer': function (classNode) {
+                var methods = classNode.methods;
+                
+                var targetMethodName = ASMAPI.mapMethod("func_211843_b"); // renderStringAtPos
+                var targetMethodDesc = "(Ljava/lang/String;FFIZ)F";                
+
+                for (var i in methods)
+                {
+                    var method = methods[i];
+                    if (method.name.equals(targetMethodName) && method.desc.equals(targetMethodDesc))
+                    {
+                        transform(method);
+                        break;
+                    }
+                }
+                return classNode;
+            }
+        }
+    };
+}
+
+function transform(method)
+{
+    var instrList = method.instructions;
+    
+    for (var i = 0; i < instrList.size(); ++i) {
+        var instr = instrList.get(i);
+        if(instr instanceof MethodInsnNode && instr.owner.equals("net/minecraft/util/text/TextFormatting"))
+        {
+            instrList.remove(instr);
+            instrList.insert(instrList.get(i - 1), new MethodInsnNode(instr.getOpcode(), "me/ktcm/text/ModTextFormatting", 
+                ASMAPI.mapMethod(instr.name), instr.desc.replace("net/minecraft/util/text/TextFormatting", "me/ktcm/text/ModTextFormatting"), false));
+        }
+        else if(instr instanceof FieldInsnNode && instr.owner.equals("net/minecraft/util/text/TextFormatting"))
+        {
+            instrList.remove(instr);
+            instrList.insert(instrList.get(i - 1), new FieldInsnNode(instr.getOpcode(), "me/ktcm/text/ModTextFormatting", 
+                ASMAPI.mapField(instr.name), instr.desc.replace("net/minecraft/util/text/TextFormatting", "me/ktcm/text/ModTextFormatting")));
+        }
+    }
+}

+ 7 - 0
src/main/resources/mcmod.info

@@ -0,0 +1,7 @@
+{
+    "pack": {
+        "description": "kcm resources",
+        "pack_format": 4,
+        "_comment": "A pack_format of 4 requires json lang files. Note: we require v4 pack meta for all mods."
+    }
+}