Skip to content

Commit e7503dd

Browse files
JonathingLexManos
authored andcommitted
CoreMods 5.2.0
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
1 parent ba314a1 commit e7503dd

22 files changed

+998
-467
lines changed

README.md

+17-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
# CoreMods
22

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

5-
Why?
5+
## Purpose
66

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

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

13-
This is connected to Forge and FML through the CoreMod SPI being implemented in new Forge.
15+
## Usage
16+
17+
CoreMods are JavaScript files that are sandboxed by the limitations provided within the CoreMod engine. It is only able
18+
to access a limited set of classes and packages. ASMAPI, included within CoreMods, exists to provide several helpful
19+
tools for writing CoreMods. You can view this class yourself to see its usages, or you can find examples of it in other
20+
CoreMods.
21+
22+
The best way to find examples for CoreMods is to look at Forge itself, since it includes complex examples that utilize
23+
much of the functionality within the sandbox.

build.gradle

+5-1
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,15 @@ dependencies {
3939
testImplementation('org.powermock:powermock-core:2.0.+')
4040
testImplementation('org.hamcrest:hamcrest-core:2.2')
4141
testImplementation('org.apache.logging.log4j:log4j-core:2.19.0')
42+
testImplementation(libs.modlauncher)
43+
testImplementation(libs.forgespi)
44+
testImplementation(libs.unsafe)
4245
testCompileOnly('org.jetbrains:annotations:21.0.1')
4346
testRuntimeOnly('org.junit.jupiter:junit-jupiter-engine:5.7.+')
4447
testRuntimeOnly(project(':coremods-test-jar'))
45-
48+
4649
compileOnly(libs.modlauncher)
50+
compileOnly(libs.securemodules)
4751
implementation(libs.log4j.api)
4852
api(libs.bundles.asm)
4953
compileOnly(libs.forgespi)

coremods-test/build.gradle

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ dependencies {
4141
testImplementation(project(':coremods-test-jar'))
4242
testImplementation(libs.junit.api)
4343
testImplementation(libs.log4j.api)
44+
testImplementation(libs.modlauncher)
45+
testImplementation(libs.forgespi)
46+
testImplementation(libs.unsafe)
4447
testRuntimeOnly(libs.bundles.junit.runtime)
4548
testCompileOnly(libs.nulls)
4649
}

coremods-test/src/test/java/module-info.java

+11-6
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@
33
* SPDX-License-Identifier: LGPL-2.1-only
44
*/
55
module net.minecraftforge.coremods.test {
6+
requires cpw.mods.modlauncher;
67
requires net.minecraftforge.forgespi;
7-
requires org.junit.jupiter.api;
8-
requires org.apache.logging.log4j;
9-
requires cpw.mods.modlauncher;
10-
requires org.objectweb.asm.tree;
11-
requires org.jetbrains.annotations;
12-
}
8+
requires net.minecraftforge.coremod;
9+
requires org.junit.jupiter.api;
10+
requires org.apache.logging.log4j;
11+
requires org.objectweb.asm.tree;
12+
requires org.jetbrains.annotations;
13+
requires net.minecraftforge.unsafe;
14+
15+
provides cpw.mods.modlauncher.api.ITransformationService
16+
with net.minecraftforge.coremod.test.TestTransformerService;
17+
}

coremods-test/src/test/java/net/minecraftforge/coremod/test/CoreModTest.java

+9-4
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66

77
import net.minecraftforge.coremod.CoreModEngine;
88

9+
import java.lang.reflect.InvocationTargetException;
910
import java.util.List;
1011
import java.util.stream.Collectors;
1112

13+
import net.minecraftforge.forgespi.coremod.ICoreModFile;
14+
import net.minecraftforge.unsafe.UnsafeHacks;
1215
import org.junit.jupiter.api.Test;
1316
import org.objectweb.asm.tree.ClassNode;
1417

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

1922
@SuppressWarnings("unchecked")
2023
@Test
21-
void testJSLoading() {
24+
void testJSLoading() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
2225
final CoreModEngine coreModEngine = new CoreModEngine();
23-
coreModEngine.loadCoreMod(new JSFileLoader("src/test/javascript/testcoremod.js"));
24-
coreModEngine.loadCoreMod(new JSFileLoader("src/test/javascript/testcore2mod.js"));
25-
coreModEngine.loadCoreMod(new JSFileLoader("src/test/javascript/testdata.js"));
26+
var loadCoreMod = coreModEngine.getClass().getMethod("loadCoreMod", ICoreModFile.class);
27+
UnsafeHacks.setAccessible(loadCoreMod);
28+
loadCoreMod.invoke(coreModEngine, new JSFileLoader("src/test/javascript/testcoremod.js"));
29+
loadCoreMod.invoke(coreModEngine, new JSFileLoader("src/test/javascript/testcore2mod.js"));
30+
loadCoreMod.invoke(coreModEngine, new JSFileLoader("src/test/javascript/testdata.js"));
2631
final List<ITransformer<?>> iTransformers = coreModEngine.initializeCoreMods();
2732
iTransformers.forEach(t -> {
2833
System.out.printf("targ: %s\n", t.targets().stream().map(ITransformer.Target::getClassName).collect(Collectors.joining(",")));

coremods-test/src/test/java/net/minecraftforge/coremod/test/TestLaunchTransformer.java

+10-5
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99
import cpw.mods.modlauncher.api.ITransformer;
1010
import net.minecraftforge.coremod.CoreModEngine;
1111

12+
import net.minecraftforge.forgespi.coremod.ICoreModFile;
13+
import net.minecraftforge.unsafe.UnsafeHacks;
1214
import org.junit.jupiter.api.Test;
1315

16+
import java.lang.reflect.InvocationTargetException;
1417
import java.util.List;
1518
import java.util.concurrent.Callable;
1619

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

2326
@Test
24-
public void testCoreModLoading() {
27+
public void testCoreModLoading() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
2528
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");
2629
System.setProperty("test.harness.callable", "net.minecraftforge.coremod.test.TestLaunchTransformer$Callback");
2730

28-
cme.loadCoreMod(new JSFileLoader("src/test/javascript/testcoremod.js"));
29-
cme.loadCoreMod(new JSFileLoader("src/test/javascript/testcore2mod.js"));
30-
cme.loadCoreMod(new JSFileLoader("src/test/javascript/testmethodcoremod.js"));
31-
cme.loadCoreMod(new JSFileLoader("src/test/javascript/testmethodcoreinsert.js"));
31+
var loadCoreMod = cme.getClass().getMethod("loadCoreMod", ICoreModFile.class);
32+
UnsafeHacks.setAccessible(loadCoreMod);
33+
loadCoreMod.invoke(cme, new JSFileLoader("src/test/javascript/testcoremod.js"));
34+
loadCoreMod.invoke(cme, new JSFileLoader("src/test/javascript/testcore2mod.js"));
35+
loadCoreMod.invoke(cme, new JSFileLoader("src/test/javascript/testmethodcoremod.js"));
36+
loadCoreMod.invoke(cme, new JSFileLoader("src/test/javascript/testmethodcoreinsert.js"));
3237

3338
Launcher.main("--version", "1.0", "--launchTarget", "testharness");
3439
}

coremods-test/src/test/javascript/testcore2mod.js

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/*
2+
* Copyright (c) Forge Development LLC
3+
* SPDX-License-Identifier: LGPL-2.1-only
4+
*/
15
var core2fn = function() {
26
print("Core2 function!");
37
}

coremods-test/src/test/javascript/testcoremod.js

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/*
2+
* Copyright (c) Forge Development LLC
3+
* SPDX-License-Identifier: LGPL-2.1-only
4+
*/
15
function initializeCoreMod() {
26
print("Hello");
37
Java.type('net.minecraftforge.coremod.api.ASMAPI').loadFile('testcoremod2.js')
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/*
2+
* Copyright (c) Forge Development LLC
3+
* SPDX-License-Identifier: LGPL-2.1-only
4+
*/
15
function moreFunctions() {
26
print("Poopy from more functions!");
37
}

coremods-test/src/test/javascript/testdata.js

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/*
2+
* Copyright (c) Forge Development LLC
3+
* SPDX-License-Identifier: LGPL-2.1-only
4+
*/
15
function initializeCoreMod() {
26
var data = Java.type('net.minecraftforge.coremod.api.ASMAPI').loadData('testdata.json')
37
print('Loaded JSON: ' + JSON.stringify(data))

coremods-test/src/test/javascript/testmethodcoreinsert.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
/*
2+
* Copyright (c) Forge Development LLC
3+
* SPDX-License-Identifier: LGPL-2.1-only
4+
*/
15
function initializeCoreMod() {
26
return {
37
'coremodmethod': {
48
'target': {
59
'type': 'METHOD',
6-
'class': 'cpw.mods.TestClass',
10+
'class': 'net.minecraftforge.coremods.testjar.TestClass',
711
'methodName': 'testInsert',
812
'methodDesc': '()Z'
913
},

coremods-test/src/test/javascript/testmethodcoremod.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
/*
2+
* Copyright (c) Forge Development LLC
3+
* SPDX-License-Identifier: LGPL-2.1-only
4+
*/
15
function initializeCoreMod() {
26
return {
37
'coremodmethod': {
48
'target': {
59
'type': 'METHOD',
6-
'class': 'cpw.mods.TestClass',
10+
'class': 'net.minecraftforge.coremods.testjar.TestClass',
711
'methodName': 'testMethod',
812
'methodDesc': '()Z'
913
},

coremods-test/src/test/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService

-1
This file was deleted.

settings.gradle

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,17 @@ dependencyResolutionManagement {
2424
library('junit-platform-launcher', 'org.junit.platform:junit-platform-launcher:1.10.0')
2525
bundle('junit-runtime', ['junit-engine', 'junit-platform-launcher'])
2626

27+
library('unsafe', 'net.minecraftforge:unsafe:0.9.2')
28+
library('securemodules', 'net.minecraftforge:securemodules:2.2.20') // Needs unsafe
2729
/*
28-
library('unsafe', 'net.minecraftforge:unsafe:0.9.1')
29-
library('securemodules', 'net.minecraftforge:securemodules:2.2.0') // Needs unsafe
3030
library('gson', 'com.google.code.gson:gson:2.10.1')
3131
library('jopt-simple', 'net.sf.jopt-simple:jopt-simple:5.0.4')
3232
*/
3333

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

3939
version('log4j', '2.19.0')
4040
library('log4j-api', 'org.apache.logging.log4j', 'log4j-api' ).versionRef('log4j')

src/main/java/module-info.java

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright (c) Forge Development LLC
3+
* SPDX-License-Identifier: LGPL-2.1-only
4+
*/
5+
module net.minecraftforge.coremod {
6+
// CoreMods framework
7+
exports net.minecraftforge.coremod;
8+
// ASMAPI
9+
exports net.minecraftforge.coremod.api;
10+
11+
requires cpw.mods.modlauncher;
12+
requires net.minecraftforge.forgespi;
13+
requires org.apache.logging.log4j;
14+
requires org.jetbrains.annotations;
15+
requires org.openjdk.nashorn;
16+
requires org.objectweb.asm.util;
17+
18+
provides net.minecraftforge.forgespi.coremod.ICoreModProvider
19+
with net.minecraftforge.coremod.CoreModProvider;
20+
}

0 commit comments

Comments
 (0)