From b23a3f3ffff4ab42a0ad985a63e7f487d59238f7 Mon Sep 17 00:00:00 2001 From: Hileb <107909747+Ecdcaeb@users.noreply.github.com> Date: Sun, 20 Apr 2025 10:45:19 +0800 Subject: [PATCH 1/8] test using groovy --- build.gradle | 1 + .../java/mods/Hileb/shotaasm/ShotaASM.java | 3 +- .../Hileb/shotaasm/impl/EventHandler.java | 16 ++++++ .../Hileb/shotaasm/impl/ShotaCompiler.java | 8 +-- .../impl/groovy/GroovyShotaCompiler.java | 40 +++++++++++++ .../impl/groovy/ShotaGroovySandbox.java | 57 +++++++++++++++++++ .../mods.Hileb.shotaasm.api.IScriptCompiler | 3 +- 7 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 src/main/java/mods/Hileb/shotaasm/impl/EventHandler.java create mode 100644 src/main/java/mods/Hileb/shotaasm/impl/groovy/GroovyShotaCompiler.java create mode 100644 src/main/java/mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java diff --git a/build.gradle b/build.gradle index 40efad1..b5cc058 100644 --- a/build.gradle +++ b/build.gradle @@ -96,6 +96,7 @@ repositories { dependencies { implementation 'curse.maven:resource-mod-loader-945917:5768125+5768126' + implementation 'com.cleanroommc:groovyscript:1.2.3' if (propertyBool('use_asset_mover')) { implementation "com.cleanroommc:assetmover:${propertyString('asset_mover_version')}" } diff --git a/src/main/java/mods/Hileb/shotaasm/ShotaASM.java b/src/main/java/mods/Hileb/shotaasm/ShotaASM.java index 4bd648b..beecd54 100644 --- a/src/main/java/mods/Hileb/shotaasm/ShotaASM.java +++ b/src/main/java/mods/Hileb/shotaasm/ShotaASM.java @@ -4,6 +4,7 @@ import com.google.common.eventbus.Subscribe; import mods.Hileb.shotaasm.api.ShotaContext; import mods.Hileb.shotaasm.impl.ShotaCompiler; +import mods.Hileb.shotaasm.impl.ErrorHandler; import net.minecraftforge.fml.common.LoadController; import net.minecraftforge.fml.common.ModMetadata; import net.minecraftforge.fml.common.event.FMLStateEvent; @@ -71,7 +72,7 @@ public File getSource() { @Subscribe public void onFMLState(FMLStateEvent event) { - ShotaCompiler.executeEvent(event.getEventType()); + EventHandler.executeEvent(event.getEventType()); } } diff --git a/src/main/java/mods/Hileb/shotaasm/impl/EventHandler.java b/src/main/java/mods/Hileb/shotaasm/impl/EventHandler.java new file mode 100644 index 0000000..2fc7fc2 --- /dev/null +++ b/src/main/java/mods/Hileb/shotaasm/impl/EventHandler.java @@ -0,0 +1,16 @@ +package mods.Hileb.shotaasm.impl; + +import com.google.common.collect.HashMultimap; + +public class EventHandler { + private static final HashMultimap eventTasks = HashMultimap.create(); + + public static void executeEvent(String evt) { + eventTasks.get(evt).forEach(Runnable::run); + eventTasks.removeAll(evt); + } + + public static void addEvent(String evt, Runnable r) { + eventTasks.put(evt, r); + } +} \ No newline at end of file diff --git a/src/main/java/mods/Hileb/shotaasm/impl/ShotaCompiler.java b/src/main/java/mods/Hileb/shotaasm/impl/ShotaCompiler.java index 10c8a5d..cc0f348 100644 --- a/src/main/java/mods/Hileb/shotaasm/impl/ShotaCompiler.java +++ b/src/main/java/mods/Hileb/shotaasm/impl/ShotaCompiler.java @@ -16,12 +16,6 @@ import java.lang.reflect.InvocationTargetException; public class ShotaCompiler implements IScriptCompiler { - private static final HashMultimap eventTasks = HashMultimap.create(); - - public static void executeEvent(String evt) { - eventTasks.get(evt).forEach(Runnable::run); - eventTasks.removeAll(evt); - } @Override public String name() { @@ -35,7 +29,7 @@ public Runnable compile(final ScriptFile file) { if (file.property().containsKey("event")) { String event = Iterables.getFirst(file.property().get("event"), null); if (event != null) { - eventTasks.put(event, () -> ShotaCompiler.this.compile(file)); + EventHandler.addEvent(event, () -> ShotaCompiler.this.compile(file)); return () -> {}; } else return null; } else { diff --git a/src/main/java/mods/Hileb/shotaasm/impl/groovy/GroovyShotaCompiler.java b/src/main/java/mods/Hileb/shotaasm/impl/groovy/GroovyShotaCompiler.java new file mode 100644 index 0000000..0f83022 --- /dev/null +++ b/src/main/java/mods/Hileb/shotaasm/impl/groovy/GroovyShotaCompiler.java @@ -0,0 +1,40 @@ +package mods.Hileb.shotaasm.impl.groovy; + +import mods.Hileb.shotaasm.api.IScriptCompiler; +import mods.Hileb.shotaasm.api.ScriptFile; + +public class GroovyShotaCompiler implements IScriptCompiler { + + @Override + public String name() { + return "groovyShota"; + } + + @Override + public Runnable compile(final ScriptFile file) { + if (ShotaContext.isClassExist("groovy.lang.GroovyClassLoader")) { + if (file.property().containsKey("event")) { + String event = Iterables.getFirst(file.property().get("event"), null); + if (event != null) { + eventTasks.put(event, () -> GroovyShotaCompiler.this.compile(file)); + return () -> {}; + } else throw new RuntimeException("Could not understand the first event property is null. At " + file.name()); + } else { + String singleName = file.name().substring(0, file.name().lastIndexOf('.')).replace('.', '_') + file.hashCode(); + String name = "mods.Hileb.shotaasm.dynamic.groovy" + singleName; + StringBuilder builder = new StringBuilder(); + for (String s : file.property().get("import")) { + builder.append("import ").append(s).append(";\n"); + } + builder.append("\n").append(file.text()); + try { + return ShotaGroovySandbox.compile(name, builder.toString()); + } catch (Throwable e) { + throw new RuntimeException("Unable to compile for " + file.name(), e); + } + } + } else { + throw new RuntimeException("Groovy Support not found. But " + file.name() + " required the compiler of groovyShota.", e); + } + } +} diff --git a/src/main/java/mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java b/src/main/java/mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java new file mode 100644 index 0000000..0ace54d --- /dev/null +++ b/src/main/java/mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java @@ -0,0 +1,57 @@ +package mods.Hileb.shotaasm.impl.groovy; + +import org.codehaus.groovy.control.customizers.ImportCustomizer; +import org.codehaus.groovy.control.CompilerConfiguration; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import groovy.lang.Binding; +import groovy.lang.GroovyClassLoader; +import groovy.lang.Script; +import org.codehaus.groovy.runtime.InvokerHelper; +import mods.Hileb.shotaasm.api.ScriptFile; +import net.minecraft.launchwrapper.Launch; + +import java.util.*; + +public class ShotaGroovySandbox { + + ImportCustomizer importCustomizer = new ImportCustomizer(); + CompilerConfiguration config = new CompilerConfiguration(); + Map bindings = new Object2ObjectOpenHashMap<>(); + Binding binding = new Binding(this.bindings); + GroovyClassLoader classLoader; + + public AbstractGroovySandbox() { + importCustomizer = new ImportCustomizer(); + config = new CompilerConfiguration(); + + importCustomizer.addImports( + "mods.Hileb.shotaasm.api.TransformerRegistry", + "mods.Hileb.shotaasm.api.ShotaContext" + ); + importCustomizer.addStarImports( + "org.objectweb.asm.*", + "org.objectweb.asm.tree.*", + "org.objectweb.asm.util.*", + "org.objectweb.asm.commons.*", + "org.objectweb.asm.signature.*" + ); + importCustomizer.addStaticStars("org.objectweb.asm.Opcodes"); + config.addCompilationCustomizers(importCustomizer); + classLoader = new GroovyClassLoader(Launch.classLoader, config, false); + } + + public Class compile(String name, String text) { + return classLoader.parseClass(new String(this.getFile()), name); + } + + public Runnable makeScript(Class cls){ + final Script script = InvokerHelper.createScript(cls, binding); + return script::run ; + } + + static ShotaGroovySandbox box = null; + public static Runnable compile(String name, String file){ + if (box == null) box = new ShotaGroovySandbox(); + return box.makeScript(box.compile(name, file)); + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/services/mods.Hileb.shotaasm.api.IScriptCompiler b/src/main/resources/META-INF/services/mods.Hileb.shotaasm.api.IScriptCompiler index a194455..04a42a7 100644 --- a/src/main/resources/META-INF/services/mods.Hileb.shotaasm.api.IScriptCompiler +++ b/src/main/resources/META-INF/services/mods.Hileb.shotaasm.api.IScriptCompiler @@ -1 +1,2 @@ -mods.Hileb.shotaasm.impl.ShotaCompiler \ No newline at end of file +mods.Hileb.shotaasm.impl.ShotaCompiler +mods.Hileb.shotaasm.impl.groovy.GroovyShotaCompiler \ No newline at end of file From 4fe5392724bf42972179ac933a40029c22b69c04 Mon Sep 17 00:00:00 2001 From: Hileb <107909747+Ecdcaeb@users.noreply.github.com> Date: Sun, 20 Apr 2025 10:45:40 +0800 Subject: [PATCH 2/8] fix star imports --- .../Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java b/src/main/java/mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java index 0ace54d..24b6352 100644 --- a/src/main/java/mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java +++ b/src/main/java/mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java @@ -29,11 +29,11 @@ public AbstractGroovySandbox() { "mods.Hileb.shotaasm.api.ShotaContext" ); importCustomizer.addStarImports( - "org.objectweb.asm.*", - "org.objectweb.asm.tree.*", - "org.objectweb.asm.util.*", - "org.objectweb.asm.commons.*", - "org.objectweb.asm.signature.*" + "org.objectweb.asm", + "org.objectweb.asm.tree", + "org.objectweb.asm.util", + "org.objectweb.asm.commons", + "org.objectweb.asm.signature" ); importCustomizer.addStaticStars("org.objectweb.asm.Opcodes"); config.addCompilationCustomizers(importCustomizer); From 5a226e71f4b3081a0a81d2c4fb6a848918a273bc Mon Sep 17 00:00:00 2001 From: Hileb <107909747+Ecdcaeb@users.noreply.github.com> Date: Sun, 20 Apr 2025 10:49:01 +0800 Subject: [PATCH 3/8] add new context --- src/main/java/mods/Hileb/shotaasm/ScriptLoader.java | 4 ++-- src/main/java/mods/Hileb/shotaasm/api/ShotaContext.java | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/mods/Hileb/shotaasm/ScriptLoader.java b/src/main/java/mods/Hileb/shotaasm/ScriptLoader.java index 8fda95c..19286da 100644 --- a/src/main/java/mods/Hileb/shotaasm/ScriptLoader.java +++ b/src/main/java/mods/Hileb/shotaasm/ScriptLoader.java @@ -15,8 +15,8 @@ import java.util.stream.Collectors; public class ScriptLoader { - private static Collection locators; - private static HashMap compilers = new HashMap<>(); + public static Collection locators; + public static HashMap compilers = new HashMap<>(); public static void initialize() { locators = loadServices(IScriptLocator.class).stream().map( aClass -> { diff --git a/src/main/java/mods/Hileb/shotaasm/api/ShotaContext.java b/src/main/java/mods/Hileb/shotaasm/api/ShotaContext.java index b1845e6..e5bf12a 100644 --- a/src/main/java/mods/Hileb/shotaasm/api/ShotaContext.java +++ b/src/main/java/mods/Hileb/shotaasm/api/ShotaContext.java @@ -6,4 +6,8 @@ public static void initialize() {} public static boolean isClassExist(String name) { return net.minecraft.launchwrapper.Launch.classLoader.isClassExist(name); } + + public static java.util.Set supportedCompilers() { + return mods.Hileb.shotaasm.ScriptLoader.compilers.keySet(); + } } From febbead3572f9fac1b042f25916715b2849eb72f Mon Sep 17 00:00:00 2001 From: Hileb <107909747+Ecdcaeb@users.noreply.github.com> Date: Sun, 20 Apr 2025 10:51:31 +0800 Subject: [PATCH 4/8] maven? --- build.gradle | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build.gradle b/build.gradle index b5cc058..9a39311 100644 --- a/build.gradle +++ b/build.gradle @@ -91,6 +91,14 @@ repositories { name 'CurseMaven' url 'https://curse.cleanroommc.com' } + maven { + name 'GTNH Maven' + url 'https://nexus.gtnewhorizons.com/repository/public/' + } + maven { + name 'GTCEu Maven' + url 'https://maven.gtceu.com' + } } From 6e0fc4503412afba7222446e09f11eda510dac72 Mon Sep 17 00:00:00 2001 From: Hileb <107909747+Ecdcaeb@users.noreply.github.com> Date: Sun, 20 Apr 2025 10:53:35 +0800 Subject: [PATCH 5/8] maven? --- build.gradle | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 9a39311..04869c1 100644 --- a/build.gradle +++ b/build.gradle @@ -92,12 +92,8 @@ repositories { url 'https://curse.cleanroommc.com' } maven { - name 'GTNH Maven' - url 'https://nexus.gtnewhorizons.com/repository/public/' - } - maven { - name 'GTCEu Maven' - url 'https://maven.gtceu.com' + name 'BlameJared Maven' + url 'https://maven.blamejared.com' } } From 4d5a56f78dd9a591bbac17f11e70dea2e6eb1831 Mon Sep 17 00:00:00 2001 From: Hileb <107909747+Ecdcaeb@users.noreply.github.com> Date: Sun, 20 Apr 2025 10:53:46 +0800 Subject: [PATCH 6/8] maven --- build.gradle | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build.gradle b/build.gradle index 04869c1..f11d5e2 100644 --- a/build.gradle +++ b/build.gradle @@ -95,6 +95,14 @@ repositories { name 'BlameJared Maven' url 'https://maven.blamejared.com' } + maven { + name 'GTNH Maven' + url 'https://nexus.gtnewhorizons.com/repository/public/' + } + maven { + name 'GTCEu Maven' + url 'https://maven.gtceu.com' + } } From 241f34b00510907f556e1414f3a4a8efb994309b Mon Sep 17 00:00:00 2001 From: Hileb <107909747+Ecdcaeb@users.noreply.github.com> Date: Sun, 20 Apr 2025 10:55:12 +0800 Subject: [PATCH 7/8] fix --- .../mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java b/src/main/java/mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java index 24b6352..115304d 100644 --- a/src/main/java/mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java +++ b/src/main/java/mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java @@ -20,7 +20,7 @@ public class ShotaGroovySandbox { Binding binding = new Binding(this.bindings); GroovyClassLoader classLoader; - public AbstractGroovySandbox() { + public ShotaGroovySandbox() { importCustomizer = new ImportCustomizer(); config = new CompilerConfiguration(); From 6b58993857046658a4a4e8b31b66020d1716534c Mon Sep 17 00:00:00 2001 From: Hileb <107909747+Ecdcaeb@users.noreply.github.com> Date: Sun, 20 Apr 2025 11:01:37 +0800 Subject: [PATCH 8/8] fix --- src/main/java/mods/Hileb/shotaasm/ShotaASM.java | 2 +- .../shotaasm/impl/groovy/GroovyShotaCompiler.java | 11 ++++++++--- .../shotaasm/impl/groovy/ShotaGroovySandbox.java | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/mods/Hileb/shotaasm/ShotaASM.java b/src/main/java/mods/Hileb/shotaasm/ShotaASM.java index beecd54..ce8c9f1 100644 --- a/src/main/java/mods/Hileb/shotaasm/ShotaASM.java +++ b/src/main/java/mods/Hileb/shotaasm/ShotaASM.java @@ -4,7 +4,7 @@ import com.google.common.eventbus.Subscribe; import mods.Hileb.shotaasm.api.ShotaContext; import mods.Hileb.shotaasm.impl.ShotaCompiler; -import mods.Hileb.shotaasm.impl.ErrorHandler; +import mods.Hileb.shotaasm.impl.EventHandler; import net.minecraftforge.fml.common.LoadController; import net.minecraftforge.fml.common.ModMetadata; import net.minecraftforge.fml.common.event.FMLStateEvent; diff --git a/src/main/java/mods/Hileb/shotaasm/impl/groovy/GroovyShotaCompiler.java b/src/main/java/mods/Hileb/shotaasm/impl/groovy/GroovyShotaCompiler.java index 0f83022..b579622 100644 --- a/src/main/java/mods/Hileb/shotaasm/impl/groovy/GroovyShotaCompiler.java +++ b/src/main/java/mods/Hileb/shotaasm/impl/groovy/GroovyShotaCompiler.java @@ -1,7 +1,12 @@ package mods.Hileb.shotaasm.impl.groovy; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Iterables; + +import mods.Hileb.shotaasm.api.ShotaContext; import mods.Hileb.shotaasm.api.IScriptCompiler; import mods.Hileb.shotaasm.api.ScriptFile; +import mods.Hileb.shotaasm.impl.EventHandler; public class GroovyShotaCompiler implements IScriptCompiler { @@ -16,7 +21,7 @@ public Runnable compile(final ScriptFile file) { if (file.property().containsKey("event")) { String event = Iterables.getFirst(file.property().get("event"), null); if (event != null) { - eventTasks.put(event, () -> GroovyShotaCompiler.this.compile(file)); + EventHandler.addEvent(event, () -> GroovyShotaCompiler.this.compile(file)); return () -> {}; } else throw new RuntimeException("Could not understand the first event property is null. At " + file.name()); } else { @@ -28,13 +33,13 @@ public Runnable compile(final ScriptFile file) { } builder.append("\n").append(file.text()); try { - return ShotaGroovySandbox.compile(name, builder.toString()); + return ShotaGroovySandbox.compileScript(name, builder.toString()); } catch (Throwable e) { throw new RuntimeException("Unable to compile for " + file.name(), e); } } } else { - throw new RuntimeException("Groovy Support not found. But " + file.name() + " required the compiler of groovyShota.", e); + throw new RuntimeException("Groovy Support not found. But " + file.name() + " required the compiler of groovyShota."); } } } diff --git a/src/main/java/mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java b/src/main/java/mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java index 115304d..93aa329 100644 --- a/src/main/java/mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java +++ b/src/main/java/mods/Hileb/shotaasm/impl/groovy/ShotaGroovySandbox.java @@ -41,7 +41,7 @@ public ShotaGroovySandbox() { } public Class compile(String name, String text) { - return classLoader.parseClass(new String(this.getFile()), name); + return classLoader.parseClass(text, name); } public Runnable makeScript(Class cls){ @@ -50,7 +50,7 @@ public Runnable makeScript(Class cls){ } static ShotaGroovySandbox box = null; - public static Runnable compile(String name, String file){ + public static Runnable compileScript(String name, String file){ if (box == null) box = new ShotaGroovySandbox(); return box.makeScript(box.compile(name, file)); }