Skip to content

Commit

Permalink
CoreMods 5.2.0
Browse files Browse the repository at this point in the history
Full Changelog:
https://gist.github.com/Jonathing/c3ad28b2a048ac839a7baba5417ee870

The key features are:
- ES6 language support
- Thoroughly updated ASMAPI, with full documentation
- Bug fixes (some optional for backwards-compatibility)
- Partial internal code cleanup
  • Loading branch information
Jonathing committed Nov 5, 2024
1 parent ba314a1 commit 347bbde
Show file tree
Hide file tree
Showing 22 changed files with 998 additions and 467 deletions.
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
# CoreMods

New JavaScript based system for implementing CoreMods.
CoreMods is a JavaScript-based system that acts as a wrapper around ObjectWeb ASM.

Why?
## Purpose

Because it means that it's a lot easier to manage the lifecycle correctly. We can isolate
CoreMod logic to the proper ClassLoading contexts without effort on the part of the Modder.
CoreMods need to be sandboxed, or otherwise isolated, in their own environments so that they are not able to cause early
class-loading. They transform classes as only as they are loaded and do not have access to objects outside of the
sandbox given to them. This helps prevent issues that would otherwise arise from CoreMods written traditionally in Java.

It hopefully also communicates that CoreMods are strictly arms-length : they operate on
classes as they load _only_ - changing structures and behaviours through that means.
Since CoreMods integrates with ModLauncher's transformation system, it is easier to manage the lifecycle as CoreMods is
only responsible for managing the transformation as ModLauncher is instead the one responsible for providing the class
loading system.

This is connected to Forge and FML through the CoreMod SPI being implemented in new Forge.
## Usage

CoreMods are JavaScript files that are sandboxed by the limitations provided within the CoreMod engine. It is only able
to access a limited set of classes and packages. ASMAPI, included within CoreMods, exists to provide several helpful
tools for writing CoreMods. You can view this class yourself to see its usages, or you can find examples of it in other
CoreMods.

The best way to find examples for CoreMods is to look at Forge itself, since it includes complex examples that utilize
much of the functionality within the sandbox.
6 changes: 5 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,15 @@ dependencies {
testImplementation('org.powermock:powermock-core:2.0.+')
testImplementation('org.hamcrest:hamcrest-core:2.2')
testImplementation('org.apache.logging.log4j:log4j-core:2.19.0')
testImplementation(libs.modlauncher)
testImplementation(libs.forgespi)
testImplementation(libs.unsafe)
testCompileOnly('org.jetbrains:annotations:21.0.1')
testRuntimeOnly('org.junit.jupiter:junit-jupiter-engine:5.7.+')
testRuntimeOnly(project(':coremods-test-jar'))

compileOnly(libs.modlauncher)
compileOnly(libs.securemodules)
implementation(libs.log4j.api)
api(libs.bundles.asm)
compileOnly(libs.forgespi)
Expand Down
3 changes: 3 additions & 0 deletions coremods-test/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ dependencies {
testImplementation(project(':coremods-test-jar'))
testImplementation(libs.junit.api)
testImplementation(libs.log4j.api)
testImplementation(libs.modlauncher)
testImplementation(libs.forgespi)
testImplementation(libs.unsafe)
testRuntimeOnly(libs.bundles.junit.runtime)
testCompileOnly(libs.nulls)
}
Expand Down
17 changes: 11 additions & 6 deletions coremods-test/src/test/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@
* SPDX-License-Identifier: LGPL-2.1-only
*/
module net.minecraftforge.coremods.test {
requires cpw.mods.modlauncher;
requires net.minecraftforge.forgespi;
requires org.junit.jupiter.api;
requires org.apache.logging.log4j;
requires cpw.mods.modlauncher;
requires org.objectweb.asm.tree;
requires org.jetbrains.annotations;
}
requires net.minecraftforge.coremod;
requires org.junit.jupiter.api;
requires org.apache.logging.log4j;
requires org.objectweb.asm.tree;
requires org.jetbrains.annotations;
requires net.minecraftforge.unsafe;

provides cpw.mods.modlauncher.api.ITransformationService
with net.minecraftforge.coremod.test.TestTransformerService;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@

import net.minecraftforge.coremod.CoreModEngine;

import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.stream.Collectors;

import net.minecraftforge.forgespi.coremod.ICoreModFile;
import net.minecraftforge.unsafe.UnsafeHacks;
import org.junit.jupiter.api.Test;
import org.objectweb.asm.tree.ClassNode;

Expand All @@ -18,11 +21,13 @@ public class CoreModTest {

@SuppressWarnings("unchecked")
@Test
void testJSLoading() {
void testJSLoading() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
final CoreModEngine coreModEngine = new CoreModEngine();
coreModEngine.loadCoreMod(new JSFileLoader("src/test/javascript/testcoremod.js"));
coreModEngine.loadCoreMod(new JSFileLoader("src/test/javascript/testcore2mod.js"));
coreModEngine.loadCoreMod(new JSFileLoader("src/test/javascript/testdata.js"));
var loadCoreMod = coreModEngine.getClass().getMethod("loadCoreMod", ICoreModFile.class);
UnsafeHacks.setAccessible(loadCoreMod);
loadCoreMod.invoke(coreModEngine, new JSFileLoader("src/test/javascript/testcoremod.js"));
loadCoreMod.invoke(coreModEngine, new JSFileLoader("src/test/javascript/testcore2mod.js"));
loadCoreMod.invoke(coreModEngine, new JSFileLoader("src/test/javascript/testdata.js"));
final List<ITransformer<?>> iTransformers = coreModEngine.initializeCoreMods();
iTransformers.forEach(t -> {
System.out.printf("targ: %s\n", t.targets().stream().map(ITransformer.Target::getClassName).collect(Collectors.joining(",")));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
import cpw.mods.modlauncher.api.ITransformer;
import net.minecraftforge.coremod.CoreModEngine;

import net.minecraftforge.forgespi.coremod.ICoreModFile;
import net.minecraftforge.unsafe.UnsafeHacks;
import org.junit.jupiter.api.Test;

import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.concurrent.Callable;

Expand All @@ -21,14 +24,16 @@ public static List<ITransformer<?>> getTransformers() {
}

@Test
public void testCoreModLoading() {
public void testCoreModLoading() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
System.setProperty("test.harness", "out/production/classes,out/test/classes,out/testJars/classes,build/classes/java/main,build/classes/java/test,build/classes/java/testJars");
System.setProperty("test.harness.callable", "net.minecraftforge.coremod.test.TestLaunchTransformer$Callback");

cme.loadCoreMod(new JSFileLoader("src/test/javascript/testcoremod.js"));
cme.loadCoreMod(new JSFileLoader("src/test/javascript/testcore2mod.js"));
cme.loadCoreMod(new JSFileLoader("src/test/javascript/testmethodcoremod.js"));
cme.loadCoreMod(new JSFileLoader("src/test/javascript/testmethodcoreinsert.js"));
var loadCoreMod = cme.getClass().getMethod("loadCoreMod", ICoreModFile.class);
UnsafeHacks.setAccessible(loadCoreMod);
loadCoreMod.invoke(cme, new JSFileLoader("src/test/javascript/testcoremod.js"));
loadCoreMod.invoke(cme, new JSFileLoader("src/test/javascript/testcore2mod.js"));
loadCoreMod.invoke(cme, new JSFileLoader("src/test/javascript/testmethodcoremod.js"));
loadCoreMod.invoke(cme, new JSFileLoader("src/test/javascript/testmethodcoreinsert.js"));

Launcher.main("--version", "1.0", "--launchTarget", "testharness");
}
Expand Down
4 changes: 4 additions & 0 deletions coremods-test/src/test/javascript/testcore2mod.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) Forge Development LLC
* SPDX-License-Identifier: LGPL-2.1-only
*/
var core2fn = function() {
print("Core2 function!");
}
Expand Down
4 changes: 4 additions & 0 deletions coremods-test/src/test/javascript/testcoremod.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) Forge Development LLC
* SPDX-License-Identifier: LGPL-2.1-only
*/
function initializeCoreMod() {
print("Hello");
Java.type('net.minecraftforge.coremod.api.ASMAPI').loadFile('testcoremod2.js')
Expand Down
4 changes: 4 additions & 0 deletions coremods-test/src/test/javascript/testcoremod2.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) Forge Development LLC
* SPDX-License-Identifier: LGPL-2.1-only
*/
function moreFunctions() {
print("Poopy from more functions!");
}
4 changes: 4 additions & 0 deletions coremods-test/src/test/javascript/testdata.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) Forge Development LLC
* SPDX-License-Identifier: LGPL-2.1-only
*/
function initializeCoreMod() {
var data = Java.type('net.minecraftforge.coremod.api.ASMAPI').loadData('testdata.json')
print('Loaded JSON: ' + JSON.stringify(data))
Expand Down
6 changes: 5 additions & 1 deletion coremods-test/src/test/javascript/testmethodcoreinsert.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
/*
* Copyright (c) Forge Development LLC
* SPDX-License-Identifier: LGPL-2.1-only
*/
function initializeCoreMod() {
return {
'coremodmethod': {
'target': {
'type': 'METHOD',
'class': 'cpw.mods.TestClass',
'class': 'net.minecraftforge.coremods.testjar.TestClass',
'methodName': 'testInsert',
'methodDesc': '()Z'
},
Expand Down
6 changes: 5 additions & 1 deletion coremods-test/src/test/javascript/testmethodcoremod.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
/*
* Copyright (c) Forge Development LLC
* SPDX-License-Identifier: LGPL-2.1-only
*/
function initializeCoreMod() {
return {
'coremodmethod': {
'target': {
'type': 'METHOD',
'class': 'cpw.mods.TestClass',
'class': 'net.minecraftforge.coremods.testjar.TestClass',
'methodName': 'testMethod',
'methodDesc': '()Z'
},
Expand Down

This file was deleted.

6 changes: 3 additions & 3 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ dependencyResolutionManagement {
library('junit-platform-launcher', 'org.junit.platform:junit-platform-launcher:1.10.0')
bundle('junit-runtime', ['junit-engine', 'junit-platform-launcher'])

library('unsafe', 'net.minecraftforge:unsafe:0.9.2')
library('securemodules', 'net.minecraftforge:securemodules:2.2.20') // Needs unsafe
/*
library('unsafe', 'net.minecraftforge:unsafe:0.9.1')
library('securemodules', 'net.minecraftforge:securemodules:2.2.0') // Needs unsafe
library('gson', 'com.google.code.gson:gson:2.10.1')
library('jopt-simple', 'net.sf.jopt-simple:jopt-simple:5.0.4')
*/

library('forgespi', 'net.minecraftforge:forgespi:7.1.0')
library('modlauncher', 'net.minecraftforge:modlauncher:10.1.1') // Needs securemodules
library('nulls', 'org.jetbrains:annotations:23.0.0')
library('nashorn', 'org.openjdk.nashorn:nashorn-core:15.3') // Needed by coremods, because the JRE no longer ships JS
library('nashorn', 'org.openjdk.nashorn:nashorn-core:15.4') // Needed by coremods, because the JRE no longer ships JS

version('log4j', '2.19.0')
library('log4j-api', 'org.apache.logging.log4j', 'log4j-api' ).versionRef('log4j')
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (c) Forge Development LLC
* SPDX-License-Identifier: LGPL-2.1-only
*/
module net.minecraftforge.coremod {
// CoreMods framework
exports net.minecraftforge.coremod;
// ASMAPI
exports net.minecraftforge.coremod.api;

requires cpw.mods.modlauncher;
requires net.minecraftforge.forgespi;
requires org.apache.logging.log4j;
requires org.jetbrains.annotations;
requires org.openjdk.nashorn;
requires org.objectweb.asm.util;

provides net.minecraftforge.forgespi.coremod.ICoreModProvider
with net.minecraftforge.coremod.CoreModProvider;
}
Loading

0 comments on commit 347bbde

Please sign in to comment.