diff --git a/src/main/java/com/cleanroommc/loader/javafix/UUIDFix.java b/src/main/java/com/cleanroommc/loader/javafix/UUIDFix.java new file mode 100644 index 000000000..67adac91d --- /dev/null +++ b/src/main/java/com/cleanroommc/loader/javafix/UUIDFix.java @@ -0,0 +1,52 @@ +package com.cleanroommc.loader.javafix; + +import net.minecraftforge.fml.common.FMLLog; + +import java.util.UUID; + +public class UUIDFix { + + public static UUID fromString(String uuid) + { + try + { + return UUID.fromString(uuid); + } + catch (IllegalArgumentException e) + { + if ("UUID string too large".equals(e.getMessage())) + { + return oldFromString(uuid); + } + throw e; + } + } + + private static UUID oldFromString(String uuid) + { + String[] components = uuid.split("-"); + if (components.length != 5) + { + throw new IllegalArgumentException("Invalid UUID string: " + uuid); + } + FMLLog.log.error("UUID [{}] is being processed with the approach from Java 8 for compatibility's sake. This UUID is malformed!", uuid); + for (int i = 0; i < 5; i++) + { + components[i] = "0x" + components[i]; + } + long mostSigBits = Long.decode(components[0]); + mostSigBits <<= 16; + mostSigBits |= Long.decode(components[1]); + mostSigBits <<= 16; + mostSigBits |= Long.decode(components[2]); + + long leastSigBits = Long.decode(components[3]); + leastSigBits <<= 48; + leastSigBits |= Long.decode(components[4]); + + return new UUID(mostSigBits, leastSigBits); + } + + private UUIDFix() { } + +} diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/MalformedUUIDTransformer.java b/src/main/java/net/minecraftforge/fml/common/asm/transformers/MalformedUUIDTransformer.java new file mode 100644 index 000000000..b26447144 --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/common/asm/transformers/MalformedUUIDTransformer.java @@ -0,0 +1,54 @@ +package net.minecraftforge.fml.common.asm.transformers; + +import net.minecraft.launchwrapper.IClassTransformer; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.*; + +public class MalformedUUIDTransformer implements IClassTransformer +{ + + @Override + public byte[] transform(String s, String s1, byte[] bytes) + { + if (bytes == null) + { + return null; + } + ClassNode classNode = new ClassNode(); + ClassReader classReader = new ClassReader(bytes); + classReader.accept(classNode, 0); + boolean modified = false; + if (classNode.methods != null) + { + for (MethodNode methodNode : classNode.methods) + { + InsnList instructions = methodNode.instructions; + if (instructions != null) + { + for (AbstractInsnNode insnNode : instructions) + { + if (insnNode.getOpcode() == Opcodes.INVOKESTATIC && insnNode instanceof MethodInsnNode methodInsnNode) + { + if ("java/util/UUID".equals(methodInsnNode.owner) && "fromString".equalsIgnoreCase(methodInsnNode.name)) + { + methodInsnNode.owner = "com/cleanroommc/loader/javafix/UUIDFix"; + modified = true; + } + } + } + } + } + } + if (modified) + { + ClassWriter classWriter = new ClassWriter(0); + + classNode.accept(classWriter); + return classWriter.toByteArray(); + } + return bytes; + } + +} diff --git a/src/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java b/src/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java index ea98e9ae6..b5db77739 100644 --- a/src/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java +++ b/src/main/java/net/minecraftforge/fml/relauncher/FMLCorePlugin.java @@ -32,6 +32,7 @@ public String[] getASMTransformerClass() "net.minecraftforge.fml.common.asm.transformers.EventSubscriberTransformer", "net.minecraftforge.fml.common.asm.transformers.SoundEngineFixTransformer", "net.minecraftforge.fml.common.asm.transformers.JavaxTransformer", + "net.minecraftforge.fml.common.asm.transformers.MalformedUUIDTransformer", "net.minecraftforge.fml.common.asm.transformers.ReflectionFieldTransformer", "net.minecraftforge.fml.common.asm.transformers.ScriptEngineTransformer" };