From a98e77aade5b7646dea422bd221d1fcda1ea3ac7 Mon Sep 17 00:00:00 2001 From: Taiyou06 Date: Fri, 12 Jul 2024 05:00:11 +0300 Subject: [PATCH] W.I.P Enum Redirector, Improve Encoding --- .../network/microopt/StringEncodingMixin.java | 34 +++++ .../redirector/RedirectorTransformer.java | 124 ++++++++++++++++++ src/main/resources/mixins.core.json | 1 + 3 files changed, 159 insertions(+) create mode 100644 src/main/java/net/gensokyoreimagined/nitori/mixin/network/microopt/StringEncodingMixin.java create mode 100644 src/main/java/net/gensokyoreimagined/nitori/mixin/redirector/RedirectorTransformer.java diff --git a/src/main/java/net/gensokyoreimagined/nitori/mixin/network/microopt/StringEncodingMixin.java b/src/main/java/net/gensokyoreimagined/nitori/mixin/network/microopt/StringEncodingMixin.java new file mode 100644 index 0000000..130ba69 --- /dev/null +++ b/src/main/java/net/gensokyoreimagined/nitori/mixin/network/microopt/StringEncodingMixin.java @@ -0,0 +1,34 @@ +package net.gensokyoreimagined.nitori.mixin.network.microopt; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.handler.codec.EncoderException; +import net.minecraft.network.Utf8String; +import net.minecraft.network.VarInt; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +import java.nio.charset.StandardCharsets; + +@Mixin(Utf8String.class) +public class StringEncodingMixin { + /** + * @author Andrew Steinborn + * @reason optimized version + */ + @Overwrite + public static void write(ByteBuf buf, CharSequence string, int length) { + // Mojang almost gets it right, but stumbles at the finish line... + if (string.length() > length) { + throw new EncoderException("String too big (was " + string.length() + " characters, max " + length + ")"); + } + int utf8Bytes = ByteBufUtil.utf8Bytes(string); + int maxBytesPermitted = ByteBufUtil.utf8MaxBytes(length); + if (utf8Bytes > maxBytesPermitted) { + throw new EncoderException("String too big (was " + utf8Bytes + " bytes encoded, max " + maxBytesPermitted + ")"); + } else { + VarInt.write(buf, utf8Bytes); + buf.writeCharSequence(string, StandardCharsets.UTF_8); + } + } +} \ No newline at end of file diff --git a/src/main/java/net/gensokyoreimagined/nitori/mixin/redirector/RedirectorTransformer.java b/src/main/java/net/gensokyoreimagined/nitori/mixin/redirector/RedirectorTransformer.java new file mode 100644 index 0000000..3ae1e2c --- /dev/null +++ b/src/main/java/net/gensokyoreimagined/nitori/mixin/redirector/RedirectorTransformer.java @@ -0,0 +1,124 @@ +package net.gensokyoreimagined.nitori.mixin.redirector; + +// https://github.com/MCTeamPotato/Redirector/issues/9 + + + +//import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; +//import org.jetbrains.annotations.Contract; +//import org.jetbrains.annotations.NotNull; +//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.InsnList; +//import org.objectweb.asm.tree.MethodNode; +// +//import java.lang.instrument.ClassFileTransformer; +//import java.security.ProtectionDomain; +//import java.util.ListIterator; +//import java.util.Map; +// +//public class RedirectorTransformer implements ClassFileTransformer { +// public static @NotNull String getSuperClass(byte[] clazz) { +// Map utfMap = new Int2IntOpenHashMap(); +// Map classMap = new Int2IntOpenHashMap(); +// int constantsCount = readUnsignedShort(clazz, 8); +// int passcount = 10; +// for (int i = 1; i < constantsCount; i++) { +// int size; +// switch (clazz[passcount]) { +// case 9: +// case 10: +// case 11: +// case 3: +// case 4: +// case 12: +// case 18: +// size = 5; +// break; +// case 5: +// case 6: +// size = 9; +// break; +// case 1://UTF8 +// int UTFSize = readUnsignedShort(clazz, passcount + 1); +// size = 3 + UTFSize; +// utfMap.put(i, passcount); +// break; +// case 15: +// size = 4; +// break; +// case 7://class +// size = 3; +// int index = readUnsignedShort(clazz, passcount + 1); +// classMap.put(i, index); +// break; +// default: +// size = 3; +// break; +// } +// passcount += size; +// +// } +// passcount += 4; +// passcount = readUnsignedShort(clazz, passcount); +// passcount = classMap.get(passcount); +// passcount = utfMap.get(passcount); +// int UTFSize = readUnsignedShort(clazz, passcount + 1); +// return readUTF8(clazz, passcount + 3, UTFSize); +// } +// +// @Contract(pure = true) +// public static int readUnsignedShort(byte @NotNull [] b, int index) { +// return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF); +// } +// +// @Contract(value = "_, _, _ -> new", pure = true) +// public static @NotNull String readUTF8(byte[] b, int index, int length) { +// char[] str = new char[length]; +// for (int i = 0; i < length; i++) { +// str[i] = (char) b[i + index]; +// } +// return new String(str); +// } +// +// @Override +// public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] basicClass) { +// try { +// String superClass = getSuperClass(basicClass); +// if (!"java/lang/Enum".equals(superClass)) return basicClass; +// ClassReader classReader = new ClassReader(basicClass); +// if ("java/lang/Enum".equals(classReader.getSuperName())) { +// ClassNode cn = new ClassNode(); +// classReader.accept(cn, 0); +// for (MethodNode mn : cn.methods) { +// if ("values".equals(mn.name) && mn.desc.contains("()")) { +// InsnList il = mn.instructions; +// ListIterator iterator = il.iterator(); +// AbstractInsnNode n1 = null; +// AbstractInsnNode n2 = null; +// while (iterator.hasNext()) { +// AbstractInsnNode note = iterator.next(); +// if (Opcodes.GETSTATIC == note.getOpcode()) { +// n1 = note; +// } else if (Opcodes.ARETURN == note.getOpcode()) { +// n2 = note; +// } +// } +// il.clear(); +// il.add(n1); +// il.add(n2); +// } +// } +// ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); +// cn.accept(classWriter); +// return classWriter.toByteArray(); +// } +// } catch (Exception e) { +// return basicClass; +// } +// return basicClass; +// } +//} \ No newline at end of file diff --git a/src/main/resources/mixins.core.json b/src/main/resources/mixins.core.json index b0d60b8..23bb71e 100755 --- a/src/main/resources/mixins.core.json +++ b/src/main/resources/mixins.core.json @@ -57,6 +57,7 @@ "math.sine_lut.MixinMth", "math.vec.FastMathVec3DMixin", "network.microopt.VarIntsMixin", + "network.microopt.StringEncodingMixin", "playerwatching.MixinChunkFilter", "playerwatching.MixinServerPlayerEntity", "playerwatching.optimize_nearby_player_lookups.MixinMobEntity",