Skip to content
Draft

Mixin #299

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ dependencies {
exclude group: 'com.google.code.gson', module: 'gson'
}

implementation("com.cleanroommc:modularui:2.5.1") { transitive false }
api "codechicken:codechickenlib:3.2.3.358"
// api "gregtech:gregtech:2.8.10-beta", { transitive false }

Expand Down
54 changes: 54 additions & 0 deletions examples/lib/ui.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@

import com.cleanroommc.modularui.ModularUI;
import com.cleanroommc.modularui.animation.Animator;
import com.cleanroommc.modularui.animation.IAnimator;
import com.cleanroommc.modularui.animation.Wait;
import com.cleanroommc.modularui.api.IThemeApi;
import com.cleanroommc.modularui.api.drawable.IDrawable;
import com.cleanroommc.modularui.api.drawable.IKey;
import com.cleanroommc.modularui.api.widget.IWidget;
import com.cleanroommc.modularui.drawable.GuiDraw;
import com.cleanroommc.modularui.drawable.GuiTextures;
import com.cleanroommc.modularui.drawable.ItemDrawable;
import com.cleanroommc.modularui.drawable.SpriteDrawable;
import com.cleanroommc.modularui.screen.CustomModularScreen;
import com.cleanroommc.modularui.screen.ModularPanel;
import com.cleanroommc.modularui.screen.RichTooltip;
import com.cleanroommc.modularui.screen.viewport.GuiContext;
import com.cleanroommc.modularui.screen.viewport.ModularGuiContext;
import com.cleanroommc.modularui.theme.WidgetTheme;
import com.cleanroommc.modularui.utils.Alignment;
import com.cleanroommc.modularui.utils.Color;
import com.cleanroommc.modularui.utils.GameObjectHelper;
import com.cleanroommc.modularui.utils.Interpolation;
import com.cleanroommc.modularui.utils.Interpolations;
import com.cleanroommc.modularui.utils.SpriteHelper;
import com.cleanroommc.modularui.utils.fakeworld.ArraySchema;
import com.cleanroommc.modularui.utils.fakeworld.FakeEntity;
import com.cleanroommc.modularui.utils.fakeworld.ISchema;
import com.cleanroommc.modularui.value.BoolValue;
import com.cleanroommc.modularui.value.StringValue;
import com.cleanroommc.modularui.widget.DraggableWidget;
import com.cleanroommc.modularui.widget.Widget;
import com.cleanroommc.modularui.widgets.ListWidget;
import com.cleanroommc.modularui.widgets.RichTextWidget;
import com.cleanroommc.modularui.widgets.SchemaWidget;
import com.cleanroommc.modularui.widgets.SortableListWidget;
import com.cleanroommc.modularui.widgets.TextWidget;
import com.cleanroommc.modularui.widgets.ToggleButton;
import com.cleanroommc.modularui.widgets.TransformWidget;
import com.cleanroommc.modularui.widgets.layout.Column;
import com.cleanroommc.modularui.widgets.layout.Flow;
import com.cleanroommc.modularui.widgets.layout.Grid;
import com.cleanroommc.modularui.widgets.layout.Row;
import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget;

class ui {

static ModularPanel buildUI(ModularGuiContext context) {
return new ModularPanel("grs")
.size(100, 25)
.child(IKey.str("This UI was made with GroovyScript").asWidget().center())
}

}
17 changes: 17 additions & 0 deletions examples/mixins/PlayerListMixin.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.NetHandlerPlayServer;
import net.minecraft.network.NetworkManager;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.server.management.PlayerList

@Mixin(value=PlayerList.class, remap=false)
class PlayerListMixin {

@Inject(method = "initializeConnectionToPlayer", at = @At(value = "INVOKE",
target = "Lnet/minecraftforge/fml/common/FMLCommonHandler;firePlayerLoggedIn(Lnet/minecraft/entity/player/EntityPlayer;)V"))
void init(NetworkManager netManager, EntityPlayerMP playerIn, NetHandlerPlayServer nethandlerplayserver, CallbackInfo ci) {
playerIn.sendMessage(new TextComponentString("Player " + playerIn.getName() + " logged in"));
}

}
14 changes: 14 additions & 0 deletions examples/mixins/TestClassMixin.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

import com.cleanroommc.groovyscript.TestClass
import com.cleanroommc.groovyscript.api.GroovyLog

@Mixin(value = TestClass.class, remap=false)
class TestClassMixin {

@Inject(method = "sayHello", at = @At("HEAD"), cancellable = true)
private static void sayBye(CallbackInfo ci) {
GroovyLog.get().info("Bye from TestClassMixin");
ci.cancel();
}

}
20 changes: 20 additions & 0 deletions examples/mixins/TestGuisMixin.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// mods_loaded: modularui
// side: client

import com.cleanroommc.modularui.screen.ModularPanel;
import com.cleanroommc.modularui.screen.viewport.ModularGuiContext;
import com.cleanroommc.modularui.test.TestGuis;
import lib.ui

@Mixin(value = TestGuis.class, remap = false)
public abstract class TestGuisMixin {

@Shadow
public abstract ModularPanel buildToggleGridListUI(ModularGuiContext context);

@Inject(method = "buildUI", at = @At("HEAD"), cancellable = true)
public void buildUI(ModularGuiContext context, CallbackInfoReturnable<ModularPanel> cir) {
//cir.setReturnValue(buildToggleGridListUI(context));
cir.setReturnValue(ui.buildUI(context));
}
}
10 changes: 1 addition & 9 deletions examples/runConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,8 @@
"version": "1.0.0",
"debug": true,
"loaders": {
"preInit": [
"classes/",
"preInit/"
],
"init": [
"init/"
],
"postInit": [
"postInit/",
"recipes/"
"test/"
]
},
"packmode": {
Expand Down
4 changes: 4 additions & 0 deletions examples/test/main.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

import com.cleanroommc.groovyscript.TestClass

TestClass.sayHello()
35 changes: 3 additions & 32 deletions src/main/java/com/cleanroommc/groovyscript/GroovyScript.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public void onConstruction(FMLConstructionEvent event) {
LOGGER.throwing(new IllegalStateException("Sandbox data should have been initialised by now, but isn't! Trying to initialize again."));
SandboxData.initialize((File) FMLInjectionData.data()[6], LOGGER);
}
SandboxData.onLateInit();
MinecraftForge.EVENT_BUS.register(this);
MinecraftForge.EVENT_BUS.register(EventHandler.class);
NetworkHandler.init();
Expand All @@ -105,6 +106,7 @@ public void onConstruction(FMLConstructionEvent event) {
GroovyDeobfMapper.init();
LinkGeneratorHooks.init();
ReloadableRegistryManager.init();
((GroovyLogImpl) GroovyLog.get()).setPassedEarly();
GroovyScript.sandbox = new GroovyScriptSandbox();
ModSupport.INSTANCE.setup(event.getASMHarvestedData());

Expand Down Expand Up @@ -142,7 +144,6 @@ public void onRegisterItem(RegistryEvent.Register<Item> event) {
@ApiStatus.Internal
public static void initializeRunConfig(File minecraftHome) {
SandboxData.initialize(minecraftHome, LOGGER);
reloadRunConfig(true);
}

@ApiStatus.Internal
Expand Down Expand Up @@ -225,37 +226,7 @@ public static boolean isSandboxLoaded() {
}

public static RunConfig getRunConfig() {
return runConfig;
}

@ApiStatus.Internal
public static void reloadRunConfig(boolean init) {
JsonElement element = JsonHelper.loadJson(getRunConfigFile());
if (element == null || !element.isJsonObject()) element = new JsonObject();
JsonObject json = element.getAsJsonObject();
if (runConfig == null) {
if (!Files.exists(getRunConfigFile().toPath())) {
json = RunConfig.createDefaultJson();
runConfig = createRunConfig(json);
} else {
runConfig = new RunConfig(json);
}
}
runConfig.reload(json, init);
}

private static RunConfig createRunConfig(JsonObject json) {
JsonHelper.saveJson(getRunConfigFile(), json);
File main = new File(getScriptFile().getPath() + File.separator + "postInit" + File.separator + "main.groovy");
if (!Files.exists(main.toPath())) {
try {
main.getParentFile().mkdirs();
Files.write(main.toPath(), "\nlog.info('Hello World!')\n".getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.WRITE);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return new RunConfig(json);
return SandboxData.getRunConfig();
}

public static void postScriptRunResult(ICommandSender sender, boolean onlyLogFails, boolean running, boolean packmode, long time) {
Expand Down
37 changes: 6 additions & 31 deletions src/main/java/com/cleanroommc/groovyscript/TestClass.java
Original file line number Diff line number Diff line change
@@ -1,39 +1,14 @@
package com.cleanroommc.groovyscript;

public class TestClass {

private static int next = 20;

private final Inner inner;
private final int id;
import com.cleanroommc.groovyscript.api.GroovyLog;

public TestClass(String name) {
this.inner = new Inner(name);
this.id = next++;
}

public Inner getInner() {
return inner;
}
public class TestClass {

public int getId() {
return id;
static {
GroovyLog.get().info("Hello we are now initialising TestClass");
}

public class Inner {

private final String name;

public Inner(String name) {
this.name = name;
}

public String getName() {
return name;
}

public int getId() {
return id;
}
public static void sayHello() {
GroovyLog.get().info("Hello from TestClass");
}
}
15 changes: 14 additions & 1 deletion src/main/java/com/cleanroommc/groovyscript/api/GroovyLog.java
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,20 @@ default void errorMC(Object o) {
*
* @param throwable exception to log
*/
void exception(String msg, Throwable throwable);
default void exception(String msg, Throwable throwable) {
exception(msg, throwable, false);
}

/**
* Formats and logs an exception to this log AND Minecraft's log with a message.<br>
* The log will be printed without formatting to Minecraft's log.
* Unnecessary lines that clutter the log will get removed before logging to this log.<br>
* <b>The exception will NOT be thrown!</b>
*
* @param throwable exception to log
* @param doThrow true if the throwable should be thrown after logged to groovy log
*/
void exception(String msg, Throwable throwable, boolean doThrow);

/**
* Formats a {@link String} and arguments according to the defined rules.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ public GSCommand() {
sender.sendMessage(new TextComponentString("Applied the default GameRules to the current world."));
}));


addSubcommand(new SimpleCommand("wiki", (server, sender, args) -> sender.sendMessage(getTextForUrl("GroovyScript wiki", "Click to open wiki in browser", new TextComponentString("https://cleanroommc.com/groovy-script/"))), "doc", "docs", "documentation"));

addSubcommand(new SimpleCommand("generateWiki", (server, sender, args) -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.cleanroommc.groovyscript.core;

import com.cleanroommc.groovyscript.api.GroovyLog;
import com.cleanroommc.groovyscript.sandbox.security.GroovySecurityManager;
import com.cleanroommc.groovyscript.sandbox.security.SandboxSecurityException;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;

import java.util.List;
import java.util.Set;

public abstract class AbstractMixinPlugin implements IMixinConfigPlugin {

@Override
public void onLoad(String mixinPackage) {}

@Override
public String getRefMapperConfig() {
return null;
}

@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
return false;
}

@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {}


@Override
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
if (!GroovySecurityManager.INSTANCE.isValid(targetClass, targetClassName)) {
GroovyLog.get()
.exception(
"An exception while applying a mixin occurred.",
new SandboxSecurityException("Can't mixin into class '" + targetClassName + "', since it is blacklisted for groovy!"),
true);
}
}

@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.cleanroommc.groovyscript.core;

import com.cleanroommc.groovyscript.sandbox.MixinSandbox;
import org.jetbrains.annotations.ApiStatus;

import java.util.List;

@ApiStatus.Internal
public class EarlyMixinPlugin extends AbstractMixinPlugin {

@Override
public List<String> getMixins() {
return MixinSandbox.getEarlyMixinClasses();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.cleanroommc.groovyscript.core;

import com.cleanroommc.groovyscript.sandbox.MixinSandbox;
import com.cleanroommc.groovyscript.sandbox.SandboxData;
import com.google.common.collect.ImmutableList;
import net.minecraftforge.common.ForgeVersion;
Expand Down Expand Up @@ -42,6 +43,11 @@ public void injectData(Map<String, Object> data) {
source = (File) data.getOrDefault("coremodLocation", null);
SandboxData.initialize((File) FMLInjectionData.data()[6], LOG);
SideOnlyConfig.init();
try {
MixinSandbox.loadEarlyMixins();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

@Override
Expand All @@ -51,6 +57,6 @@ public String getAccessTransformerClass() {

@Override
public List<String> getMixinConfigs() {
return ImmutableList.of("mixin.groovyscript.json");
return ImmutableList.of("mixin.groovyscript.groovy.json", "mixin.groovyscript.json");
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.cleanroommc.groovyscript.core;

import com.cleanroommc.groovyscript.compat.mods.ic2.IC2;
import com.cleanroommc.groovyscript.sandbox.MixinSandbox;
import com.google.common.collect.ImmutableList;
import net.minecraftforge.fml.common.Loader;
import zone.rong.mixinbooter.ILateMixinLoader;
Expand All @@ -11,6 +12,7 @@
public class LateMixin implements ILateMixinLoader {

public static final List<String> modMixins = ImmutableList.of(
"custom.late",
"advancedmortars",
"appliedenergistics2",
"armorplus",
Expand Down Expand Up @@ -49,6 +51,7 @@ public class LateMixin implements ILateMixinLoader {

@Override
public List<String> getMixinConfigs() {
MixinSandbox.loadLateMixins();
return modMixins.stream().map(mod -> "mixin.groovyscript." + mod + ".json").collect(Collectors.toList());
}

Expand Down
Loading