Sort field added by mixin (1.18). (#743)

Signed-off-by: 秋雨落 <i@rain.cx>
This commit is contained in:
秋雨落 2022-09-20 15:32:04 +08:00 committed by GitHub
parent 90ed5201f3
commit 3ebd71a152
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 14 deletions

View File

@ -1,5 +1,6 @@
package io.izzel.arclight.common.mixin.core.network.protocol.game;
import io.izzel.arclight.common.mod.ArclightMixinPlugin;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import net.minecraft.network.FriendlyByteBuf;
@ -22,7 +23,7 @@ public class SChatPacketMixin {
@Shadow private UUID sender;
// @formatter:on
public BaseComponent[] components;
@ArclightMixinPlugin.SortField(after = "f_131821_" /* message */) public BaseComponent[] components;
/**
* @author IzzelAliz

View File

@ -5,25 +5,27 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.*;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.*;
public class ArclightMixinPlugin implements IMixinConfigPlugin {
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.CLASS)
public @interface SortField {
String after();
}
private static final String SORT_FIELD_TYPE = Type.getDescriptor(SortField.class);
private final Map<String, Map.Entry<List<FieldNode>, List<MethodNode>>> accessTransformer =
ImmutableMap.<String, Map.Entry<List<FieldNode>, List<MethodNode>>>builder()
.put("net.minecraft.world.level.Level",
@ -128,6 +130,10 @@ public class ArclightMixinPlugin implements IMixinConfigPlugin {
.add("net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess")
.build();
private final Set<String> sortFields = ImmutableSet.<String>builder()
.add("net.minecraft.network.protocol.game.ClientboundChatPacket")
.build();
@Override
public void onLoad(String mixinPackage) {
@ -172,6 +178,35 @@ public class ArclightMixinPlugin implements IMixinConfigPlugin {
}
}
modifyConstructor(targetClassName, targetClass);
sortFields(targetClassName, targetClass);
}
private void sortFields(String targetClassName, ClassNode classNode) {
if (sortFields.contains(targetClassName)) {
TreeMap<Integer, FieldNode> insertions = new TreeMap<>();
for (ListIterator<FieldNode> iterator = classNode.fields.listIterator(); iterator.hasNext(); ) {
FieldNode node = iterator.next();
if (node.invisibleAnnotations == null) continue;
for (AnnotationNode annotation : node.invisibleAnnotations) {
if (SORT_FIELD_TYPE.equals(annotation.desc)) {
String name = annotation.values.get(1).toString();
int index = 0;
for (FieldNode field : classNode.fields) {
if (field.name.equals(name)) break;
else index++;
}
if (index >= classNode.fields.size())
throw new IllegalArgumentException(String.format("SortField cannot find %s in %s", name, targetClassName));
insertions.put(index + 1, node);
iterator.remove();
}
}
}
for (Map.Entry<Integer, FieldNode> entry : insertions.descendingMap().entrySet()) {
classNode.fields.add(entry.getKey(), entry.getValue());
entry.getValue().invisibleAnnotations.removeIf(it -> SORT_FIELD_TYPE.equals(it.desc));
}
}
}
private void modifyConstructor(String targetClassName, ClassNode classNode) {