Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge SPI into FML #58

Merged
merged 1 commit into from
Dec 22, 2023
Merged
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
6 changes: 0 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,6 @@ allprojects {

subprojects { subProject ->
subProject.version = gradleutils.getTagOffsetVersion()
ext {
MANIFESTS = [
'' : [
] as LinkedHashMap
]
}

jar.doFirst {
manifest.attributes(
Expand Down
1 change: 0 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
spi_version=9.0.2
mergetool_version=2.0.0
accesstransformers_version=10.0.1
coremods_version=6.0.0
Expand Down
2 changes: 1 addition & 1 deletion loader/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ dependencies {
api("org.ow2.asm:asm:${asm_version}")
api("org.ow2.asm:asm-tree:${asm_version}")
api("org.ow2.asm:asm-commons:${asm_version}")
api("net.neoforged:neoforgespi:${spi_version}")
api(project(':spi'))
api("net.neoforged:mergetool:${mergetool_version}:api")
api("org.apache.logging.log4j:log4j-api:${log4j_version}")
api("org.slf4j:slf4j-api:${slf4j_api_version}")
Expand Down
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ include 'loader'
include 'core'
include 'events'
include 'earlydisplay'
include 'spi'

includeLanguage 'minecraft'
includeLanguage 'java'
Expand Down
29 changes: 29 additions & 0 deletions spi/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
plugins {
id 'org.javamodularity.moduleplugin'
id 'maven-publish'
id 'java-library'
}

dependencies {
implementation("cpw.mods:modlauncher:$modlauncher_version")
implementation("org.ow2.asm:asm:$asm_version")
implementation("org.ow2.asm:asm-commons:$asm_version")
implementation("org.ow2.asm:asm-tree:$asm_version")
implementation("org.apache.logging.log4j:log4j-api:$log4j_version")
implementation("org.apache.maven:maven-artifact:$apache_maven_artifact_version")
implementation("cpw.mods:securejarhandler:$securejarhandler_version")
api("net.neoforged:mergetool:$mergetool_version:api") {
transitive false
}


testRuntimeOnly("org.apache.logging.log4j:log4j-core:$log4j_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-engine:$jupiter_version")
}

test {
useJUnitPlatform()
}
83 changes: 83 additions & 0 deletions spi/src/main/java/net/neoforged/neoforgespi/Environment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforgespi;

import cpw.mods.modlauncher.api.IEnvironment;
import cpw.mods.modlauncher.api.ITransformationService;
import cpw.mods.modlauncher.api.TypesafeMap;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.neoforgespi.locating.IModDirectoryLocatorFactory;
import net.neoforged.neoforgespi.locating.IModLocator;
import net.neoforged.neoforgespi.locating.IModFile;
import net.neoforged.neoforgespi.locating.ModFileFactory;

import java.nio.file.Path;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
* Global environment variables - allows discoverability with other systems without full forge
* dependency
*/
public class Environment {
public static final class Keys {

/**
* The @{@link Dist} which is running.
* Populated by forge during {@link ITransformationService#initialize(IEnvironment)}
*/
public static final Supplier<TypesafeMap.Key<Dist>> DIST = IEnvironment.buildKey("FORGEDIST", Dist.class);

/**
* Use {@link #MODDIRECTORYFACTORY} instead.
*/
@Deprecated
public static final Supplier<TypesafeMap.Key<Function<Path,IModLocator>>> MODFOLDERFACTORY = IEnvironment.buildKey("MODFOLDERFACTORY", Function.class);
/**
* Build a custom modlocator based on a supplied directory, with custom name
*/
public static final Supplier<TypesafeMap.Key<IModDirectoryLocatorFactory>> MODDIRECTORYFACTORY = IEnvironment.buildKey("MODDIRFACTORY", IModDirectoryLocatorFactory.class);

/**
* Factory for building {@link IModFile} instances
*/
public static final Supplier<TypesafeMap.Key<ModFileFactory>> MODFILEFACTORY = IEnvironment.buildKey("MODFILEFACTORY", ModFileFactory.class);
/**
* Provides a string consumer which can be used to push notification messages to the early startup GUI.
*/
public static final Supplier<TypesafeMap.Key<Consumer<String>>> PROGRESSMESSAGE = IEnvironment.buildKey("PROGRESSMESSAGE", Consumer.class);
}
private static Environment INSTANCE;

public static void build(IEnvironment environment) {
if (INSTANCE != null) throw new RuntimeException("Environment is a singleton");
INSTANCE = new Environment(environment);
}

public static Environment get() {
return INSTANCE;
}


private final IEnvironment environment;

private final Dist dist;
private final ModFileFactory modFileFactory;

private Environment(IEnvironment setup) {
this.environment = setup;
this.dist = setup.getProperty(Keys.DIST.get()).orElseThrow(()->new RuntimeException("Missing DIST in environment!"));
this.modFileFactory = setup.getProperty(Keys.MODFILEFACTORY.get()).orElseThrow(()->new RuntimeException("Missing MODFILEFACTORY in environment!"));
}

public Dist getDist() {
return this.dist;
}
public ModFileFactory getModFileFactory() {
return this.modFileFactory;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforgespi.coremod;

import java.io.*;
import java.nio.file.*;

/**
* Interface for core mods to discover content and properties
* of their location and context to the coremod implementation.
*/
public interface ICoreModFile {
String getOwnerId();
Reader readCoreMod() throws IOException;
Path getPath();
Reader getAdditionalFile(final String fileName) throws IOException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforgespi.coremod;

import cpw.mods.modlauncher.api.*;

import java.util.*;

/**
* Core Mod Provider - core mod logic is implemented
* in a separate library. Connection is provided here
*
*/
public interface ICoreModProvider {
/**
* Add a coremod file to the list of coremods
* @param file the file to add
*/
void addCoreMod(ICoreModFile file);

/**
* Return the completed list of transformers for all coremods
* @return all coremod transformers
*/
List<ITransformer<?>> getCoreModTransformers();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforgespi.language;

import java.util.List;
import java.util.Optional;


/**
* This is an interface for querying configuration elements
*/
public interface IConfigurable {
<T> Optional<T> getConfigElement(final String... key);
public List<? extends IConfigurable> getConfigList(final String... key);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforgespi.language;

public interface ILifecycleEvent<R extends ILifecycleEvent<?>> {
@SuppressWarnings("unchecked")
default R concrete() {
return (R) this;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforgespi.language;

import net.neoforged.neoforgespi.locating.IModFile;
import org.apache.maven.artifact.versioning.VersionRange;

import java.util.List;
import java.util.Map;

public interface IModFileInfo
{
List<IModInfo> getMods();

record LanguageSpec(String languageName, VersionRange acceptedVersions) {}

List<LanguageSpec> requiredLanguageLoaders();

boolean showAsResourcePack();

boolean showAsDataPack();

Map<String,Object> getFileProperties();

String getLicense();

String moduleName();

String versionString();

List<String> usesServices();

IModFile getFile();

IConfigurable getConfig();
}
110 changes: 110 additions & 0 deletions spi/src/main/java/net/neoforged/neoforgespi/language/IModInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforgespi.language;

import net.neoforged.api.distmarker.Dist;
import net.neoforged.neoforgespi.Environment;
import net.neoforged.neoforgespi.locating.ForgeFeature;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.VersionRange;

import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Optional;

public interface IModInfo
{
// " " will just be the preferred version for Maven, but it will accept anything.
// The space is very important, else we get a range that doesn't accept anything.
VersionRange UNBOUNDED = MavenVersionAdapter.createFromVersionSpec(" ");

IModFileInfo getOwningFile();

String getModId();

String getDisplayName();

String getDescription();

ArtifactVersion getVersion();

List<? extends ModVersion> getDependencies();

List<? extends ForgeFeature.Bound> getForgeFeatures();

String getNamespace();

Map<String,Object> getModProperties();

Optional<URL> getUpdateURL();

Optional<URL> getModURL();

Optional<String> getLogoFile();

boolean getLogoBlur();

IConfigurable getConfig();

enum Ordering {
BEFORE, AFTER, NONE
}

enum DependencySide {
CLIENT(Dist.CLIENT), SERVER(Dist.DEDICATED_SERVER), BOTH(Dist.values());

private final Dist[] dist;

DependencySide(final Dist... dist) {
this.dist = dist;
}

public boolean isContained(Dist side) {
return this == BOTH || dist[0] == side;
}
public boolean isCorrectSide()
{
return this == BOTH || Environment.get().getDist().equals(this.dist[0]);
}
}

enum DependencyType {
REQUIRED, OPTIONAL,
/**
* Prevents the game from loading if the dependency is loaded.
*/
INCOMPATIBLE,
/**
* Shows a warning if the dependency is loaded.
*/
DISCOURAGED
}

interface ModVersion {
String getModId();

VersionRange getVersionRange();

DependencyType getType();

/**
* {@return the reason of this dependency}
* Only displayed if the type is either {@link DependencyType#DISCOURAGED} or {@link DependencyType#INCOMPATIBLE}
*/
Optional<String> getReason();

Ordering getOrdering();

DependencySide getSide();

void setOwner(IModInfo owner);

IModInfo getOwner();

Optional<URL> getReferralURL();
}
}
Loading