diff --git a/.github/workflows/compile-test.yml b/.github/workflows/compile-test.yml index 652ac84c..328c48a2 100644 --- a/.github/workflows/compile-test.yml +++ b/.github/workflows/compile-test.yml @@ -21,6 +21,7 @@ jobs: git config --global user.name "Jannyboy11" git clone https://github.com/PaperMC/Paper cd Paper + git checkout ver/1.20.4 ./gradlew applyPatches ./gradlew createReobfBundlerJar ./gradlew build diff --git a/ScalaLoader-Common/pom.xml b/ScalaLoader-Common/pom.xml index 124d22ee..2fff7b27 100644 --- a/ScalaLoader-Common/pom.xml +++ b/ScalaLoader-Common/pom.xml @@ -13,7 +13,7 @@ 1.20.4-R0.1-SNAPSHOT - 9.6 + 9.7 3.0.0 5.7.1 1.6.2 diff --git a/ScalaLoader-Common/src/main/java/xyz/janboerman/scalaloader/compat/Platform.java b/ScalaLoader-Common/src/main/java/xyz/janboerman/scalaloader/compat/Platform.java index a8d2b01f..b7e3b5a0 100644 --- a/ScalaLoader-Common/src/main/java/xyz/janboerman/scalaloader/compat/Platform.java +++ b/ScalaLoader-Common/src/main/java/xyz/janboerman/scalaloader/compat/Platform.java @@ -10,12 +10,16 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.util.Collections; +import java.util.Set; /** * This class is NOT part of the public API! */ public class Platform { + private static final String FAKE_PLUGIN_NAME = "Fake"; + protected Platform() { } @@ -31,7 +35,7 @@ public by try { Server server = currentPluginClassLoader.getServer(); UnsafeValues unsafeValues = server.getUnsafe(); - String fakeDescription = "name: Fake" + System.lineSeparator() + + String fakeDescription = "name: " + FAKE_PLUGIN_NAME + System.lineSeparator() + "version: 1.0" + System.lineSeparator() + "main: xyz.janboerman.scalaloader.FakePlugin" + System.lineSeparator(); ApiVersion apiVersion = currentPluginClassLoader.getApiVersion(); @@ -68,19 +72,69 @@ public static Platform detect(Server server) { public static class CraftBukkitPlatform extends Platform { + private static final Class API_VERSION_CLASS; + static { + Class apiVersionClass; + try { + apiVersionClass = Class.forName("org.bukkit.craftbukkit.util.ApiVersion"); + } catch (ClassNotFoundException e) { + apiVersionClass = null; + } + API_VERSION_CLASS = apiVersionClass; + } + private CraftBukkitPlatform() {} private MethodHandle commodoreConvert = null; private boolean attempted = false; + public byte[] transformNative(Server craftServer, byte[] classBytes, ScalaPluginClassLoader pluginClassLoader) throws Throwable { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + if (commodoreConvert == null) { + attempted = true; + try { + // public static byte[] convert(byte[] b, final String pluginName, final ApiVersion pluginVersion, final Set activeCompatibilities) + Class commodoreClass = Class.forName(getPackageName(craftServer.getClass()) + ".util.Commodore"); + String methodName = "convert"; + MethodType methodType = MethodType.methodType(byte[].class, + new Class[] { byte[].class, String.class, API_VERSION_CLASS, Set.class }); + commodoreConvert = lookup.findStatic(commodoreClass, methodName, methodType); + } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException ignored) { + //impossible + } + } + + if (commodoreConvert != null) { + String pluginName = getPluginName(pluginClassLoader); + try { + MethodHandle getOrCreateVersion = lookup.findStatic(API_VERSION_CLASS, "getOrCreateVersion", MethodType.methodType(API_VERSION_CLASS, String.class)); + Object apiVersion = getOrCreateVersion.invoke(pluginClassLoader.getApiVersion().getVersionString()); + + Set activeCompatibilities = Collections.emptySet(); + try { + MethodHandle compatibilitiesGetter = lookup.findGetter(craftServer.getClass(), "activeCompatibilities", Set.class); + activeCompatibilities = (Set) compatibilitiesGetter.invoke(craftServer); + } catch (Exception couldNotDetermineActiveCompatibilities) { + } + + classBytes = (byte[]) commodoreConvert.invoke(classBytes, pluginName, apiVersion, activeCompatibilities); + } catch (NoSuchMethodException | IllegalAccessException ignored) { + } + } + + return classBytes; + } + public byte[] transformNative(Server craftServer, byte[] classBytes, boolean modern) throws Throwable { if (!attempted) { attempted = true; MethodHandles.Lookup lookup = MethodHandles.lookup(); try { + // public static byte[] convert(byte[] b, boolean isModern) Class commodoreClass = Class.forName(getPackageName(craftServer.getClass()) + ".util.Commodore"); String methodName = "convert"; - MethodType methodType = MethodType.methodType(byte[].class, new Class[]{byte[].class, boolean.class}); + MethodType methodType = MethodType.methodType(byte[].class, + new Class[] { byte[].class, boolean.class }); commodoreConvert = lookup.findStatic(commodoreClass, methodName, methodType); } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException ignored) { //running on craftbukkit 1.12.2 or earlier @@ -96,9 +150,21 @@ public byte[] transformNative(Server craftServer, byte[] classBytes, boolean mod @Override public byte[] transform(String jarEntryPath, byte[] classBytes, ScalaPluginClassLoader pluginClassLoader) throws Throwable { - return transformNative(pluginClassLoader.getServer(), classBytes, pluginClassLoader.getApiVersion() != ApiVersion.LEGACY); + if (API_VERSION_CLASS != null) { + return transformNative(pluginClassLoader.getServer(), classBytes, pluginClassLoader); + } else { + return transformNative(pluginClassLoader.getServer(), classBytes, pluginClassLoader.getApiVersion() != ApiVersion.LEGACY); + } } + private static String getPluginName(IScalaPluginClassLoader classLoader) { + IScalaPlugin plugin = classLoader.getPlugin(); + if (plugin == null) { + return FAKE_PLUGIN_NAME; + } else { + return plugin.getName(); + } + } } public static class GlowstonePlatform extends Platform { diff --git a/ScalaLoader-Common/src/main/java/xyz/janboerman/scalaloader/configurationserializable/runtime/types/ScalaCollection.java b/ScalaLoader-Common/src/main/java/xyz/janboerman/scalaloader/configurationserializable/runtime/types/ScalaCollection.java index b9b25a9d..37b75849 100644 --- a/ScalaLoader-Common/src/main/java/xyz/janboerman/scalaloader/configurationserializable/runtime/types/ScalaCollection.java +++ b/ScalaLoader-Common/src/main/java/xyz/janboerman/scalaloader/configurationserializable/runtime/types/ScalaCollection.java @@ -435,7 +435,7 @@ private static