| /* Copyright 2015-2024 Rivoreo |
| |
| Permission is hereby granted, free of charge, to any person obtaining |
| a copy of this software and associated documentation files (the |
| "Software"), to deal in the Software without restriction, including |
| without limitation the rights to use, copy, modify, merge, publish, |
| distribute, sublicense, and/or sell copies of the Software, and to |
| permit persons to whom the Software is furnished to do so, subject to |
| the following conditions: |
| |
| The above copyright notice and this permission notice shall be |
| included in all copies or substantial portions of the Software. |
| |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE |
| FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
| CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| |
| package rivoreo.minecraft.cauldronrmguava10; |
| |
| import net.minecraft.launchwrapper.IClassTransformer; |
| import org.objectweb.asm.ClassReader; |
| import org.objectweb.asm.ClassWriter; |
| import org.objectweb.asm.tree.ClassNode; |
| import org.objectweb.asm.tree.MethodNode; |
| import org.objectweb.asm.tree.AbstractInsnNode; |
| import org.objectweb.asm.tree.FieldInsnNode; |
| import org.objectweb.asm.tree.LdcInsnNode; |
| import org.objectweb.asm.Opcodes; |
| import java.util.List; |
| |
| public class CauldronRemoveGuava10Transformer implements IClassTransformer { |
| private static byte[] transform_bukkitpluginclassloader(byte[] class_code) { |
| ClassReader reader = new ClassReader(class_code); |
| ClassNode class_node = new ClassNode(); |
| reader.accept(class_node, ClassReader.SKIP_DEBUG); |
| for(MethodNode method : (List<MethodNode>)class_node.methods) { |
| if(method.desc.equals("(I)Lnet/md_5/specialsource/JarMapping;") && method.name.equals("getJarMapping")) { |
| AbstractInsnNode[] insn_nodes = method.instructions.toArray(); |
| for(int i = 0; i < insn_nodes.length - 5; i++) { |
| if(insn_nodes[i].getOpcode() != Opcodes.ALOAD) continue; |
| if(insn_nodes[i + 1].getOpcode() != Opcodes.GETFIELD) continue; |
| FieldInsnNode field_insn = (FieldInsnNode)insn_nodes[i + 1]; |
| if(!field_insn.desc.equals("Ljava/util/LinkedHashMap;")) continue; |
| if(insn_nodes[i + 2].getOpcode() != Opcodes.LDC) continue; |
| LdcInsnNode ldc_insn = (LdcInsnNode)insn_nodes[i + 2]; |
| if(!ldc_insn.cst.equals("com/google/common")) continue; |
| if(insn_nodes[i + 3].getOpcode() != Opcodes.LDC) continue; |
| ldc_insn = (LdcInsnNode)insn_nodes[i + 3]; |
| if(!ldc_insn.cst.equals("guava10/com/google/common")) continue; |
| if(insn_nodes[i + 4].getOpcode() != Opcodes.INVOKEVIRTUAL) continue; |
| if(insn_nodes[i + 5].getOpcode() != Opcodes.POP) continue; |
| for(int j = i; j < i + 6; j++) { |
| method.instructions.remove(insn_nodes[j]); |
| } |
| break; |
| } |
| break; |
| } |
| } |
| ClassWriter writer = new ClassWriter(0); |
| class_node.accept(writer); |
| return writer.toByteArray(); |
| } |
| |
| public byte[] transform(String original_name, String runtime_name, byte[] class_code) { |
| if(runtime_name.equals("org.bukkit.plugin.java.PluginClassLoader")) return transform_bukkitpluginclassloader(class_code); |
| return class_code; |
| } |
| } |