Skip to content

Commit

Permalink
Auto-prefix mod handlers & unique annotated methods (FabricMC#97)
Browse files Browse the repository at this point in the history
Aims to avoid double prefixing where a mod has correctly prefixed already
  • Loading branch information
Chocohead authored Feb 13, 2023
1 parent 3bb4cbf commit f466542
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
6 changes: 5 additions & 1 deletion src/main/java/org/spongepowered/asm/mixin/FabricUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ public final class FabricUtil {
public static final int COMPATIBILITY_LATEST = COMPATIBILITY_0_10_0;

public static String getModId(IMixinConfig config) {
return getDecoration(config, KEY_MOD_ID, "(unknown)");
return getModId(config, "(unknown)");
}

public static String getModId(IMixinConfig config, String defaultValue) {
return getDecoration(config, KEY_MOD_ID, defaultValue);
}

public static String getModId(ISelectorContext context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,17 @@
import org.spongepowered.asm.logging.ILogger;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
import org.spongepowered.asm.mixin.FabricUtil;
import org.spongepowered.asm.mixin.MixinEnvironment;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo;
import org.spongepowered.asm.mixin.transformer.ClassInfo.Method;
import org.spongepowered.asm.mixin.transformer.MixinInfo.MixinMethodNode;
import org.spongepowered.asm.service.MixinService;
import org.spongepowered.asm.util.Counter;
import org.spongepowered.asm.util.asm.MethodNodeEx;

import com.google.common.base.Strings;
import com.google.common.primitives.Chars;

/**
* Maintains method remaps for a target class
Expand Down Expand Up @@ -108,8 +111,17 @@ public void remapHandlerMethod(MixinInfo mixin, MethodNode handler, Method metho
public String getHandlerName(MixinMethodNode method) {
String prefix = InjectionInfo.getInjectorPrefix(method.getInjectorAnnotation());
String classUID = MethodMapper.getClassUID(method.getOwner().getClassRef());
String methodUID = MethodMapper.getMethodUID(method.name, method.desc, !method.isSurrogate());
return String.format("%s$%s%s$%s", prefix, classUID, methodUID, method.name);
String mod = FabricUtil.getModId(method.getOwner().getConfig(), "");
String methodName = method.name;
if (!mod.isEmpty()) {
//It's common for mods to prefix their own handlers, let's account for that happening
if (methodName.startsWith(mod) && methodName.length() > mod.length() + 1 && Chars.contains(new char[] {'_', '$'}, methodName.charAt(mod.length()))) {
methodName = methodName.substring(mod.length() + 1);
}
mod += '$';
}
String methodUID = MethodMapper.getMethodUID(methodName, method.desc, !method.isSurrogate());
return String.format("%s$%s%s$%s%s", prefix, classUID, methodUID, mod, methodName);
}

/**
Expand All @@ -123,8 +135,23 @@ public String getHandlerName(MixinMethodNode method) {
*/
public String getUniqueName(MethodNode method, String sessionId, boolean preservePrefix) {
String uniqueIndex = Integer.toHexString(this.nextUniqueMethodIndex++);
String methodName = method.name;
if (method instanceof MethodNodeEx) {
String mod = FabricUtil.getModId(((MethodNodeEx) method).getOwner().getConfig(), "");
if (!mod.isEmpty()) {
//It's rarer for mods to prefix their @Unique methods, but let's account for it anyway
if (methodName.startsWith(mod) && methodName.length() > mod.length() + 1 && Chars.contains(new char[] {'_', '$'}, methodName.charAt(mod.length()))) {
methodName = methodName.substring(mod.length() + 1);
}
if (preservePrefix) {
methodName += '$' + mod;
} else {
methodName = mod + '$' + methodName;
}
}
}
String pattern = preservePrefix ? "%2$s_$md$%1$s$%3$s" : "md%s$%s$%s";
return String.format(pattern, sessionId.substring(30), method.name, uniqueIndex);
return String.format(pattern, sessionId.substring(30), methodName, uniqueIndex);
}

/**
Expand Down

0 comments on commit f466542

Please sign in to comment.