Skip to content

Commit

Permalink
Locator rewrite (#112)
Browse files Browse the repository at this point in the history
Co-authored-by: Technici4n <[email protected]>
Co-authored-by: Sebastian Hartte <[email protected]>
  • Loading branch information
3 people authored May 1, 2024
1 parent 0aa8991 commit 0844898
Show file tree
Hide file tree
Showing 139 changed files with 3,992 additions and 2,289 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/build-prs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ jobs:
uses: neoforged/actions/.github/workflows/build-prs.yml@main
with:
java: 21
gradle_tasks: test
# --info allows seeing STDOUT of tests
gradle_tasks: check --info
jar_compatibility: true
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>
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# 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. Filesystem locations, virtual jars or even full mod-files can be reported to the discovery pipeline for inclusion in the mod loading process.
The pipeline also offers a way for locators to add issues (warnings & errors) that will later be shown to the user when mod loading concludes.

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`.
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ allprojects {
name = 'Minecraft'
url = 'https://libraries.minecraft.net'
}

// TODO remove
mavenLocal()
}

dependencyUpdates.rejectVersionIf { isNonStable(it.candidate.version) }
Expand All @@ -69,6 +66,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
10 changes: 5 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ accesstransformers_version=10.0.1
coremods_version=7.0.3
eventbus_version=7.0.16
modlauncher_version=10.1.10
securejarhandler_version=2.1.31
securejarhandler_version=3.0.4
bootstraplauncher_version=1.1.8
asm_version=9.5
mixin_version=0.12.5+mixin.0.8.5
mixin_version=0.13.1+mixin.0.8.5
terminalconsoleappender_version=1.2.0
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
10 changes: 4 additions & 6 deletions loader/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ 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.junit.jupiter:junit-jupiter-params:$jupiter_version")
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 +70,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));
}
}
}
20 changes: 4 additions & 16 deletions loader/src/main/java/net/neoforged/fml/ModList.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
Expand All @@ -32,15 +30,12 @@
import net.neoforged.neoforgespi.language.IModInfo;
import net.neoforged.neoforgespi.language.ModFileScanData;
import net.neoforged.neoforgespi.locating.IModFile;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
* Master list of all mods - game-side version. This is classloaded in the game scope and
* can dispatch game level events as a result.
*/
public class ModList {
private static Logger LOGGER = LogManager.getLogger();
private static ModList INSTANCE;
private final List<IModFileInfo> modFiles;
private final List<IModInfo> sortedList;
Expand All @@ -58,10 +53,11 @@ private ModList(final List<ModFile> modFiles, final List<ModInfo> sortedList) {
}

private String fileToLine(IModFile mf) {
var mainMod = mf.getModInfos().getFirst();
return String.format(Locale.ENGLISH, "%-50.50s|%-30.30s|%-30.30s|%-20.20s|Manifest: %s", mf.getFileName(),
mf.getModInfos().get(0).getDisplayName(),
mf.getModInfos().get(0).getModId(),
mf.getModInfos().get(0).getVersion(),
mainMod.getDisplayName(),
mainMod.getModId(),
mainMod.getVersion(),
((ModFileInfo) mf.getModFileInfo()).getCodeSigningFingerprint().orElse("NOSIGNATURE"));
}

Expand All @@ -78,14 +74,6 @@ public static ModList get() {
return INSTANCE;
}

private static ForkJoinWorkerThread newForkJoinWorkerThread(ForkJoinPool pool) {
ForkJoinWorkerThread thread = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
thread.setName("modloading-worker-" + thread.getPoolIndex());
// The default sets it to the SystemClassloader, so copy the current one.
thread.setContextClassLoader(Thread.currentThread().getContextClassLoader());
return thread;
}

public List<IModFileInfo> getModFiles() {
return modFiles;
}
Expand Down
Loading

0 comments on commit 0844898

Please sign in to comment.