2021-06-11 14:02:28 +02:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Zach Brown <zach@zachbr.io>
|
|
|
|
Date: Wed, 3 Oct 2018 20:09:18 -0400
|
|
|
|
Subject: [PATCH] Hook into CB plugin rewrites
|
|
|
|
|
|
|
|
Allows us to do fun stuff like rewrite the OBC util fastutil location to
|
|
|
|
our own relocation. Also lets us rewrite NMS calls for when we're
|
|
|
|
debugging in an IDE pre-relocate.
|
|
|
|
|
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
|
2024-07-18 10:13:20 +02:00
|
|
|
index 4afaab8978d4c4d9b0e9339f1bea9a9a9963d20d..421ddf6ca955215dff77655a7eda62eb9d90aa92 100644
|
2021-06-11 14:02:28 +02:00
|
|
|
--- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
|
|
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
|
2024-07-18 10:13:20 +02:00
|
|
|
@@ -11,6 +11,7 @@ import java.util.Arrays;
|
|
|
|
import java.util.Collection;
|
2024-06-13 16:45:27 +02:00
|
|
|
import java.util.Collections;
|
2021-06-11 14:02:28 +02:00
|
|
|
import java.util.Enumeration;
|
|
|
|
+import java.util.HashMap;
|
|
|
|
import java.util.HashSet;
|
2023-09-23 04:06:03 +02:00
|
|
|
import java.util.List;
|
2024-01-14 10:46:04 +01:00
|
|
|
import java.util.Map;
|
2024-07-18 10:13:20 +02:00
|
|
|
@@ -20,6 +21,7 @@ import java.util.jar.JarEntry;
|
2021-06-11 14:02:28 +02:00
|
|
|
import java.util.jar.JarFile;
|
2024-01-14 10:46:04 +01:00
|
|
|
import java.util.jar.JarOutputStream;
|
|
|
|
import java.util.zip.ZipEntry;
|
|
|
|
+import javax.annotation.Nonnull;
|
|
|
|
import joptsimple.OptionParser;
|
|
|
|
import joptsimple.OptionSet;
|
|
|
|
import joptsimple.OptionSpec;
|
2024-07-18 10:13:20 +02:00
|
|
|
@@ -99,6 +101,40 @@ public class Commodore {
|
2024-06-13 19:12:48 +02:00
|
|
|
private static final Map<String, RerouteMethodData> METHOD_REROUTE = Commodore.createReroutes(MethodRerouting.class);
|
2024-07-18 10:13:20 +02:00
|
|
|
private static final Map<String, RerouteMethodData> ENUM_METHOD_REROUTE = Commodore.createReroutes(EnumEvil.class);
|
2021-06-11 14:02:28 +02:00
|
|
|
|
|
|
|
+ // Paper start - Plugin rewrites
|
|
|
|
+ private static final Map<String, String> SEARCH_AND_REMOVE = initReplacementsMap();
|
2024-01-14 10:46:04 +01:00
|
|
|
+ private static Map<String, String> initReplacementsMap() {
|
2021-06-11 14:02:28 +02:00
|
|
|
+ Map<String, String> getAndRemove = new HashMap<>();
|
|
|
|
+ // Be wary of maven shade's relocations
|
|
|
|
+
|
2022-11-05 06:16:57 +01:00
|
|
|
+ final java.util.jar.Manifest manifest = io.papermc.paper.util.JarManifests.manifest(Commodore.class);
|
2024-01-14 10:46:04 +01:00
|
|
|
+ if (Boolean.getBoolean( "debug.rewriteForIde") && manifest != null)
|
2021-06-11 14:02:28 +02:00
|
|
|
+ {
|
|
|
|
+ // unversion incoming calls for pre-relocate debug work
|
2022-05-31 07:18:45 +02:00
|
|
|
+ final String NMS_REVISION_PACKAGE = "v" + manifest.getMainAttributes().getValue("CraftBukkit-Package-Version") + "/";
|
2021-06-11 14:02:28 +02:00
|
|
|
+
|
2024-01-14 10:46:04 +01:00
|
|
|
+ getAndRemove.put("org/bukkit/".concat("craftbukkit/" + NMS_REVISION_PACKAGE), NMS_REVISION_PACKAGE);
|
2021-06-11 14:02:28 +02:00
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return getAndRemove;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Nonnull
|
|
|
|
+ private static String getOriginalOrRewrite(@Nonnull String original)
|
|
|
|
+ {
|
|
|
|
+ String rewrite = null;
|
|
|
|
+ for ( Map.Entry<String, String> entry : SEARCH_AND_REMOVE.entrySet() )
|
|
|
|
+ {
|
|
|
|
+ if ( original.contains( entry.getKey() ) )
|
|
|
|
+ {
|
|
|
|
+ rewrite = original.replace( entry.getValue(), "" );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return rewrite != null ? rewrite : original;
|
|
|
|
+ }
|
2024-01-14 10:46:04 +01:00
|
|
|
+ // Paper end - Plugin rewrites
|
2021-06-11 14:02:28 +02:00
|
|
|
+
|
2024-04-23 22:36:31 +02:00
|
|
|
public static void main(String[] args) {
|
2024-04-25 23:21:18 +02:00
|
|
|
OptionParser parser = new OptionParser();
|
|
|
|
OptionSpec<File> inputFlag = parser.acceptsAll(Arrays.asList("i", "input")).withRequiredArg().ofType(File.class).required();
|
2024-07-18 10:13:20 +02:00
|
|
|
@@ -252,9 +288,49 @@ public class Commodore {
|
|
|
|
}
|
|
|
|
|
2024-01-14 10:46:04 +01:00
|
|
|
return new MethodVisitor(this.api, super.visitMethod(access, name, desc, signature, exceptions)) {
|
2021-06-11 14:02:28 +02:00
|
|
|
+ // Paper start - Plugin rewrites
|
|
|
|
+ @Override
|
2024-01-14 10:46:04 +01:00
|
|
|
+ public void visitTypeInsn(int opcode, String type) {
|
|
|
|
+ type = getOriginalOrRewrite(type);
|
2021-06-11 14:02:28 +02:00
|
|
|
+
|
2024-01-14 10:46:04 +01:00
|
|
|
+ super.visitTypeInsn(opcode, type);
|
2021-06-11 14:02:28 +02:00
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
|
2024-01-14 10:46:04 +01:00
|
|
|
+ for (int i = 0; i < local.length; i++)
|
2021-06-11 14:02:28 +02:00
|
|
|
+ {
|
2024-01-14 10:46:04 +01:00
|
|
|
+ if (!(local[i] instanceof String)) { continue; }
|
2021-06-11 14:02:28 +02:00
|
|
|
+
|
2024-01-14 10:46:04 +01:00
|
|
|
+ local[i] = getOriginalOrRewrite((String) local[i]);
|
2021-06-11 14:02:28 +02:00
|
|
|
+ }
|
|
|
|
+
|
2024-01-14 10:46:04 +01:00
|
|
|
+ for (int i = 0; i < stack.length; i++)
|
2021-06-11 14:02:28 +02:00
|
|
|
+ {
|
2024-01-14 10:46:04 +01:00
|
|
|
+ if (!(stack[i] instanceof String)) { continue; }
|
2021-06-11 14:02:28 +02:00
|
|
|
+
|
2024-01-14 10:46:04 +01:00
|
|
|
+ stack[i] = getOriginalOrRewrite((String) stack[i]);
|
2021-06-11 14:02:28 +02:00
|
|
|
+ }
|
|
|
|
+
|
2024-01-14 10:46:04 +01:00
|
|
|
+ super.visitFrame(type, nLocal, local, nStack, stack);
|
2021-06-11 14:02:28 +02:00
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
2024-01-14 10:46:04 +01:00
|
|
|
+ public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) {
|
|
|
|
+ descriptor = getOriginalOrRewrite(descriptor);
|
2021-06-11 14:02:28 +02:00
|
|
|
+
|
2024-01-14 10:46:04 +01:00
|
|
|
+ super.visitLocalVariable(name, descriptor, signature, start, end, index);
|
2021-06-11 14:02:28 +02:00
|
|
|
+ }
|
2024-04-23 22:36:31 +02:00
|
|
|
+ // Paper end - Plugin rewrites
|
|
|
|
|
2021-06-11 14:02:28 +02:00
|
|
|
@Override
|
2024-01-14 10:46:04 +01:00
|
|
|
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
|
2021-06-11 14:02:28 +02:00
|
|
|
+ // Paper start - Rewrite plugins
|
2024-01-14 10:46:04 +01:00
|
|
|
+ owner = getOriginalOrRewrite(owner);
|
|
|
|
+ if (desc != null) {
|
|
|
|
+ desc = getOriginalOrRewrite(desc);
|
2021-06-11 14:02:28 +02:00
|
|
|
+ }
|
|
|
|
+ // Paper end
|
2024-04-23 22:36:31 +02:00
|
|
|
name = FieldRename.rename(pluginVersion, owner, name);
|
|
|
|
|
|
|
|
if (modern) {
|
2024-07-18 10:13:20 +02:00
|
|
|
@@ -374,6 +450,13 @@ public class Commodore {
|
2024-04-23 22:36:31 +02:00
|
|
|
return;
|
2021-06-11 14:02:28 +02:00
|
|
|
}
|
|
|
|
|
2024-04-23 22:36:31 +02:00
|
|
|
+ // Paper start - Rewrite plugins
|
2024-01-14 10:46:04 +01:00
|
|
|
+ owner = getOriginalOrRewrite(owner) ;
|
|
|
|
+ if (desc != null) {
|
2021-06-11 14:02:28 +02:00
|
|
|
+ desc = getOriginalOrRewrite(desc);
|
|
|
|
+ }
|
2024-04-23 22:36:31 +02:00
|
|
|
+ // Paper end - Rewrite plugins
|
|
|
|
+
|
|
|
|
if (modern) {
|
|
|
|
if (owner.equals("org/bukkit/Material") || (instantiatedMethodType != null && instantiatedMethodType.getDescriptor().startsWith("(Lorg/bukkit/Material;)"))) {
|
|
|
|
switch (name) {
|
2024-07-18 10:13:20 +02:00
|
|
|
@@ -470,6 +553,13 @@ public class Commodore {
|
2024-01-14 10:46:04 +01:00
|
|
|
|
2022-11-05 06:16:57 +01:00
|
|
|
@Override
|
2024-01-14 10:46:04 +01:00
|
|
|
public void visitLdcInsn(Object value) {
|
2022-11-05 06:16:57 +01:00
|
|
|
+ // Paper start
|
|
|
|
+ if (value instanceof Type type) {
|
|
|
|
+ if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
|
|
|
|
+ value = Type.getType(getOriginalOrRewrite(type.getDescriptor()));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // Paper end
|
2024-01-14 10:46:04 +01:00
|
|
|
if (value instanceof String && ((String) value).equals("com.mysql.jdbc.Driver")) {
|
|
|
|
super.visitLdcInsn("com.mysql.cj.jdbc.Driver");
|
|
|
|
return;
|
2024-07-18 10:13:20 +02:00
|
|
|
@@ -480,6 +570,14 @@ public class Commodore {
|
2024-01-14 10:46:04 +01:00
|
|
|
|
2023-09-23 04:06:03 +02:00
|
|
|
@Override
|
2024-01-14 10:46:04 +01:00
|
|
|
public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) {
|
2023-09-23 04:06:03 +02:00
|
|
|
+ // Paper start - Rewrite plugins
|
2024-01-14 10:46:04 +01:00
|
|
|
+ name = getOriginalOrRewrite(name);
|
|
|
|
+ if (descriptor != null) {
|
|
|
|
+ descriptor = getOriginalOrRewrite(descriptor);
|
2023-09-23 04:06:03 +02:00
|
|
|
+ }
|
2024-01-14 10:46:04 +01:00
|
|
|
+ final String fName = name;
|
|
|
|
+ final String fDescriptor = descriptor;
|
2023-09-23 04:06:03 +02:00
|
|
|
+ // Paper end - Rewrite plugins
|
2024-01-14 10:46:04 +01:00
|
|
|
if (bootstrapMethodHandle.getOwner().equals("java/lang/invoke/LambdaMetafactory")
|
|
|
|
&& bootstrapMethodHandle.getName().equals("metafactory") && bootstrapMethodArguments.length == 3) {
|
|
|
|
Type samMethodType = (Type) bootstrapMethodArguments[0];
|
2024-07-18 10:13:20 +02:00
|
|
|
@@ -496,7 +594,7 @@ public class Commodore {
|
2024-01-14 10:46:04 +01:00
|
|
|
methodArgs.add(new Handle(newOpcode, newOwner, newName, newDescription, newItf));
|
|
|
|
methodArgs.add(newInstantiated);
|
|
|
|
|
|
|
|
- super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, methodArgs.toArray(Object[]::new));
|
|
|
|
+ super.visitInvokeDynamicInsn(fName, fDescriptor, bootstrapMethodHandle, methodArgs.toArray(Object[]::new)); // Paper - use final local vars
|
|
|
|
}, implMethod.getTag(), implMethod.getOwner(), implMethod.getName(), implMethod.getDesc(), implMethod.isInterface(), samMethodType, instantiatedMethodType);
|
|
|
|
return;
|
|
|
|
}
|
2024-07-18 10:13:20 +02:00
|
|
|
@@ -547,6 +645,12 @@ public class Commodore {
|
2024-04-23 22:36:31 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
|
|
|
|
+ // Paper start - Rewrite plugins
|
|
|
|
+ descriptor = getOriginalOrRewrite(descriptor);
|
|
|
|
+ if ( signature != null ) {
|
|
|
|
+ signature = getOriginalOrRewrite(signature);
|
|
|
|
+ }
|
|
|
|
+ // Paper end
|
|
|
|
return new FieldVisitor(this.api, super.visitField(access, name, descriptor, signature, value)) {
|
|
|
|
@Override
|
|
|
|
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
|