Skip to content

Commit

Permalink
Rewrite the mod discovery process with a focus on better end-to-end r…
Browse files Browse the repository at this point in the history
…eporting of errors and warnings

Co-authored-by: Matyrobbrt <[email protected]>
Co-authored-by: Technici4n <[email protected]>
  • Loading branch information
2 people authored and shartte committed Apr 20, 2024
1 parent fa57788 commit 724f88f
Show file tree
Hide file tree
Showing 133 changed files with 3,065 additions and 2,148 deletions.
11 changes: 11 additions & 0 deletions .run/Template JUnit.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<component name="ProjectRunConfigurationManager">
<configuration default="true" type="JUnit" factoryName="JUnit">
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="class" />
<option name="VM_PARAMETERS" value="-ea --add-opens=java.base/java.lang.invoke=ALL-UNNAMED" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Fancy Mod Loader

The mod loader used by [NeoForge](https://github.com/neoforged/NeoForge).

## Extension Points

### Mod File Candidate Locators

Responsible for locating potential mod files. Represents candiates as `JarContents`
from [SJH](https://github.com/McModLauncher/securejarhandler).

Interface: `net.neoforged.neoforgespi.locating.IModFileCandidateLocator`

Resolved via Java ServiceLoader.

You can construct a basic locator to scan a folder for mods by using `IModFileCandidateLocator.forFolder`. This can be
useful if your locator generates a folder on-disk and wants to delegate to default behavior for it (For example used
by [ServerPackLocator](https://github.com/marchermans/serverpacklocator/)).

### Mod File Readers

Responsible for creating a `IModFile` for mod file candidates.

The default implementation will resolve the type of the mod file by inspecting the Jar manifest or the mod metadata
file (`neoforge.mods.toml`) and return an `IModFile` instance if this succeeds.

Interface: `net.neoforged.neoforgespi.locating.IModFileReader`

Resolved via Java ServiceLoader.

Mod file instances can be created using the static methods on `IModFile`.

### Mod File Provider

Responsible for supplying `IModFile` that are not based on candidates resolved through locators.

Interface: `net.neoforged.neoforgespi.locating.IModFileReader`

Resolved via Java ServiceLoader.

Mod file instances can be created using the static methods on `IModFile`.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ allprojects {

test {
useJUnitPlatform()

// Needed by UnionFS
jvmArgs("--add-opens=java.base/java.lang.invoke=ALL-UNNAMED")
}
}

Expand Down
3 changes: 1 addition & 2 deletions earlydisplay/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ dependencies {
implementation("net.sf.jopt-simple:jopt-simple:${jopt_simple_version}")

testImplementation("org.junit.jupiter:junit-jupiter-api:${jupiter_version}")
testImplementation("org.powermock:powermock-core:${powermock_version}")


testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${jupiter_version}")
testRuntimeOnly("org.slf4j:slf4j-jdk14:${slf4j_api_version}")
testRuntimeOnly("org.lwjgl:lwjgl::${lwjglNatives}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
import java.util.stream.Collectors;
import joptsimple.OptionParser;
import net.neoforged.fml.loading.FMLConfig;
import net.neoforged.fml.loading.FMLLoader;
import net.neoforged.fml.loading.FMLPaths;
import net.neoforged.fml.loading.ImmediateWindowHandler;
import net.neoforged.fml.loading.progress.StartupNotificationManager;
Expand Down Expand Up @@ -600,7 +599,7 @@ public <T> Supplier<T> loadingOverlay(final Supplier<?> mc, final Supplier<?> ri
public void updateModuleReads(final ModuleLayer layer) {
var fm = layer.findModule("neoforge").orElseThrow();
getClass().getModule().addReads(fm);
var clz = FMLLoader.getGameLayer().findModule("neoforge").map(l -> Class.forName(l, "net.neoforged.neoforge.client.loading.NeoForgeLoadingOverlay")).orElseThrow();
var clz = Class.forName(fm, "net.neoforged.neoforge.client.loading.NeoForgeLoadingOverlay");
var methods = Arrays.stream(clz.getMethods()).filter(m -> Modifier.isStatic(m.getModifiers())).collect(Collectors.toMap(Method::getName, Function.identity()));
loadingOverlay = methods.get("newInstance");
}
Expand Down
6 changes: 3 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ nightconfig_version=3.6.4
jetbrains_annotations_version=24.0.1
slf4j_api_version=1.8.0-beta4
apache_maven_artifact_version=3.8.5
jarjar_version=0.4.0
jarjar_version=0.4.1
lwjgl_version=3.3.1
jupiter_version=5.8.2
powermock_version=2.0.9
jupiter_version=5.10.2
mockito_version=5.11.0

mojang_logging_version=1.1.1
log4j_version=2.19.0
Expand Down
9 changes: 3 additions & 6 deletions loader/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ dependencies {
testCompileOnly("org.jetbrains:annotations:${jetbrains_annotations_version}")
testRuntimeOnly("cpw.mods:bootstraplauncher:${bootstraplauncher_version}")
testRuntimeOnly("org.apache.logging.log4j:log4j-core:$log4j_version")
testRuntimeOnly("net.neoforged:JarJarFileSystems:$jarjar_version")
testImplementation("org.junit.jupiter:junit-jupiter-api:$jupiter_version")
testImplementation("org.powermock:powermock-core:$powermock_version")
testImplementation("org.hamcrest:hamcrest-core:2.2+")
testImplementation("org.mockito:mockito-junit-jupiter:$mockito_version")
testImplementation("org.assertj:assertj-core:3.25.3")
testImplementation("org.junit.jupiter:junit-jupiter-engine:$jupiter_version")
}

Expand All @@ -68,7 +69,3 @@ spotless {
bumpThisNumberIfACustomStepChanges(1)
}
}

test {
useJUnitPlatform()
}
26 changes: 0 additions & 26 deletions loader/src/main/java/net/neoforged/fml/LoadingFailedException.java

This file was deleted.

4 changes: 2 additions & 2 deletions loader/src/main/java/net/neoforged/fml/ModContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ public final <T extends Event & IModBusEvent> void acceptEvent(T e) {
LOGGER.trace(LOADING, "Fired event for modid {} : {}", this.getModId(), e);
} catch (Throwable t) {
LOGGER.error(LOADING, "Caught exception during event {} dispatch for modid {}", e, this.getModId(), t);
throw new ModLoadingException(modInfo, "fml.modloading.errorduringevent", t, e.getClass().getName());
throw new ModLoadingException(ModLoadingIssue.error("fml.modloading.errorduringevent", e.getClass().getName()).withAffectedMod(modInfo).withCause(t));
}
}

Expand All @@ -204,7 +204,7 @@ public final <T extends Event & IModBusEvent> void acceptEvent(EventPriority pha
LOGGER.trace(LOADING, "Fired event for phase {} for modid {} : {}", phase, this.getModId(), e);
} catch (Throwable t) {
LOGGER.error(LOADING, "Caught exception during event {} dispatch for modid {}", e, this.getModId(), t);
throw new ModLoadingException(modInfo, "fml.modloading.errorduringevent", t, e.getClass().getName());
throw new ModLoadingException(ModLoadingIssue.error("fml.modloading.errorduringevent", e.getClass().getName()).withAffectedMod(modInfo).withCause(t));
}
}
}
Loading

0 comments on commit 724f88f

Please sign in to comment.