rename files, add javadocs, remove unused class

This commit is contained in:
moehreag 2024-06-15 21:13:18 +02:00
parent 0476adadd8
commit d58867a92e
14 changed files with 176 additions and 148 deletions

View file

@ -6,16 +6,15 @@ import java.util.Optional;
import dev.frogmc.frogloader.api.env.Env;
import dev.frogmc.frogloader.api.mod.ModProperties;
import dev.frogmc.frogloader.api.plugin.FrogGamePlugin;
import dev.frogmc.frogloader.api.plugin.FrogModProvider;
import dev.frogmc.frogloader.api.plugin.FrogPlugin;
import dev.frogmc.frogloader.api.plugin.GamePlugin;
import dev.frogmc.frogloader.api.plugin.ModProvider;
import dev.frogmc.frogloader.impl.FrogLoaderImpl;
/**
* General API to interact with this loader.
*
* @see ModProperties
* @see FrogPlugin
* @see ModProvider
* @see Env
*/
public interface FrogLoader {
@ -34,14 +33,14 @@ public interface FrogLoader {
*
* @return The game plugin applicable to the current game
*/
FrogGamePlugin getGamePlugin();
GamePlugin getGamePlugin();
/**
* Get all loaded mod providers.
*
* @return A collection of all loaded mod providers
*/
Collection<FrogModProvider> getModProviders();
Collection<ModProvider> getModProviders();
/**
* Get the current (physical) environment.
@ -103,12 +102,13 @@ public interface FrogLoader {
*
* @return A collection of all loaded mods
* @see ModProperties
* @see FrogPlugin
* @see ModProvider
*/
Collection<ModProperties> getMods();
/**
* Get the version of the currently loaded game
*
* @return The current game version
*/
String getGameVersion();

View file

@ -1,22 +0,0 @@
package dev.frogmc.frogloader.api.plugin;
import dev.frogmc.frogloader.api.FrogLoader;
import dev.frogmc.frogloader.api.mod.ModProperties;
public interface FrogGamePlugin {
default void run() {
}
default boolean isApplicable() {
return false;
}
default void init(FrogLoader loader) throws Exception {
}
String queryVersion();
default ModProperties getGameMod() {
return null;
}
}

View file

@ -1,34 +0,0 @@
package dev.frogmc.frogloader.api.plugin;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import dev.frogmc.frogloader.api.mod.ModProperties;
public interface FrogModProvider {
String id();
default String loadDirectory() {
return "mods";
}
default boolean isApplicable() {
return false;
}
default boolean isFileApplicable(Path path) {
return false;
}
default boolean isDirectoryApplicable(Path path) {
return false;
}
default void preLaunch(Collection<ModProperties> mods) {
}
default Collection<ModProperties> loadMods(Collection<Path> modFiles) throws Exception {
return Collections.emptySet();
}
}

View file

@ -1,57 +0,0 @@
package dev.frogmc.frogloader.api.plugin;
import java.util.Collection;
import java.util.Collections;
import dev.frogmc.frogloader.api.FrogLoader;
import dev.frogmc.frogloader.api.mod.ModProperties;
/**
* A Plugin that may load mods for a specific game and environment
*
* @see FrogLoader
*/
public interface FrogPlugin {
/**
* General run method of this plugin. This method is run after all plugins have been initialized.
*
* @see FrogPlugin#init(FrogLoader)
* @see FrogPlugin#getMods()
*/
default void run() {
}
/**
* Check whether this plugin is applicable for the current environment
*
* @return Whether this plugin is applicable to be loaded in the current environment
*/
default boolean isApplicable() {
return false;
}
/**
* Initialization method for this plugin. This method will be called after <code>isApplicable()</code>
* if it returns true to initialize is plugin.
*
* @param loader the loader loading this plugin
* @throws Exception This method may throw any exception, it will be handled by the loader.
* @see FrogPlugin#isApplicable()
* @see FrogPlugin#getMods()
*/
default void init(FrogLoader loader) throws Exception {
}
/**
* This method should return all mods loaded by this plugin. It will be queried after <code>init(FrogLoader)</code>
* and before <code>run()</code>.
*
* @return A collection of mods loaded by this plugin.
* @see FrogPlugin#init(FrogLoader)
* @see FrogPlugin#run()
*/
default Collection<ModProperties> getMods() {
return Collections.emptySet();
}
}

View file

@ -0,0 +1,52 @@
package dev.frogmc.frogloader.api.plugin;
import dev.frogmc.frogloader.api.FrogLoader;
import dev.frogmc.frogloader.api.mod.ModProperties;
import org.jetbrains.annotations.NotNull;
/**
* A plugin responsible for loading a game.
* Only one of these may be loaded at a time.
* @see FrogLoader
* @see ModProvider
*/
public interface GamePlugin {
/**
* Method to launch the game.
* This method will be called after mods are located and loaded.
*/
default void run() {
}
/**
* Whether this plugin is applicable to be loaded in the current environment.
* Only one plugin may be applicable at a time.
* @return Whether this plugin is applicable to be loaded
*/
default boolean isApplicable() {
return false;
}
/**
* Initialize this plugin.
* @param loader The loader currently loading this plugin
* @throws Exception If an exception occurs during initialization. It will be handled by the loader.
*/
default void init(FrogLoader loader) throws Exception {
}
/**
* Queries the version of the game of this plugin.
* @return The version of the game loaded by this plugin
*/
@NotNull
String queryVersion();
/**
* Get the mod embodying the game loaded by this plugin.
* @return A mod for the currently loaded game. May be null if no such mod shall be added.
*/
default ModProperties getGameMod() {
return null;
}
}

View file

@ -0,0 +1,85 @@
package dev.frogmc.frogloader.api.plugin;
import java.net.URL;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.function.Consumer;
import dev.frogmc.frogloader.api.mod.ModProperties;
import dev.frogmc.frogloader.api.FrogLoader;
/**
* A provider for mods to be loaded.
* @see FrogLoader
* @see GamePlugin
* @see ModProperties
*/
public interface ModProvider {
/**
* Get the ID of this provider. Mods will be stored separated by their provider ID.
* @return The ID of this provider
*/
String id();
/**
* The directory to search in for mods. This will be resolved relative to the game directory.
* @return The name of the mods directory, relative to the game directory
*/
default String loadDirectory() {
return "mods";
}
/**
* Whether this provider is applicable to load in the current environment.
* @return Whether this provider is applicable to load
*/
default boolean isApplicable() {
return false;
}
/**
* Whether a mod file is valid to be loaded by this provider.
* @param path The path to validate
* @return Whether this path is valid to be loaded by this provider
* @see #isDirectoryApplicable(Path)
* @see #loadDirectory()
*/
default boolean isFileApplicable(Path path) {
return false;
}
/**
* Whether a directory (inside the path declared by this provider's mod directory) is valid to be queried for mods
* to be loaded by this provider.
* @param path The directory to be validated
* @return Whether this directory should be traversed further
* @see #loadDirectory()
* @see #isFileApplicable(Path)
*/
default boolean isDirectoryApplicable(Path path) {
return false;
}
/**
* This method will be invoked just before the game is launched. It may be used for a pre-launch entrypoint for mods.
* @param mods The mods loaded by this provider
*/
default void preLaunch(Collection<ModProperties> mods) {
}
/**
* This method should load the mods found previously into their runtime representation.
* This method should also load any nested mods
* <p>Note: This method also needs to add mods to the classpath for them to be loaded correctly. For this, a parameter is provided.</p>
*
* @param modFiles The paths to be loaded by this provider
* @param classpathAdder A consumer to easily add URLs to the classpath used to run the game on
* @return Mods loaded by this provider
* @throws Exception If an exception occurs during loading. It will be handled by the loader.
*/
default Collection<ModProperties> loadMods(Collection<Path> modFiles, Consumer<URL> classpathAdder) throws Exception {
return Collections.emptySet();
}
}

View file

@ -14,8 +14,8 @@ import com.google.gson.Gson;
import dev.frogmc.frogloader.api.FrogLoader;
import dev.frogmc.frogloader.api.env.Env;
import dev.frogmc.frogloader.api.mod.ModProperties;
import dev.frogmc.frogloader.api.plugin.FrogGamePlugin;
import dev.frogmc.frogloader.api.plugin.FrogModProvider;
import dev.frogmc.frogloader.api.plugin.GamePlugin;
import dev.frogmc.frogloader.api.plugin.ModProvider;
import dev.frogmc.frogloader.impl.gui.LoaderGui;
import dev.frogmc.frogloader.impl.launch.MixinClassLoader;
import dev.frogmc.frogloader.impl.mod.ModUtil;
@ -37,7 +37,7 @@ public class FrogLoaderImpl implements FrogLoader {
@Getter
private final Env env;
@Getter
private final Collection<FrogModProvider> modProviders = new ArrayList<>();
private final Collection<ModProvider> modProviders = new ArrayList<>();
@Getter
private final Path gameDir, configDir;
@Getter
@ -48,7 +48,7 @@ public class FrogLoaderImpl implements FrogLoader {
private final Gson gson = new Gson();
private final Map<String, Map<String, ModProperties>> mods = new HashMap<>();
@Getter
private FrogGamePlugin gamePlugin;
private GamePlugin gamePlugin;
@Getter
private String gameVersion;
private Collection<String> modIds = new ArrayList<>();
@ -73,7 +73,7 @@ public class FrogLoaderImpl implements FrogLoader {
try {
loadGamePlugin();
loadModProviders();
modProviders.stream().map(FrogModProvider::loadDirectory).map(gameDir::resolve).forEach(modsDirs::add);
modProviders.stream().map(ModProvider::loadDirectory).map(gameDir::resolve).forEach(modsDirs::add);
advanceMixinState();
modIds = collectModIds();
LOGGER.info(ModUtil.getModList(getMods()));
@ -105,7 +105,7 @@ public class FrogLoaderImpl implements FrogLoader {
}
private void loadGamePlugin() {
FrogGamePlugin plugin = PluginLoader.discoverGamePlugins();
GamePlugin plugin = PluginLoader.discoverGamePlugins();
gameVersion = plugin.queryVersion();
ModProperties gameMod = plugin.getGameMod();
if (gameMod != null) {

View file

@ -9,8 +9,8 @@ import java.util.stream.Collectors;
import dev.frogmc.frogloader.api.FrogLoader;
import dev.frogmc.frogloader.api.mod.ModProperties;
import dev.frogmc.frogloader.api.plugin.FrogGamePlugin;
import dev.frogmc.frogloader.api.plugin.FrogModProvider;
import dev.frogmc.frogloader.api.plugin.GamePlugin;
import dev.frogmc.frogloader.api.plugin.ModProvider;
import dev.frogmc.frogloader.impl.gui.LoaderGui;
import dev.frogmc.frogloader.impl.mixin.AWProcessor;
import dev.frogmc.frogloader.impl.mod.BuiltinExtensions;
@ -23,10 +23,10 @@ import org.spongepowered.asm.mixin.Mixins;
public class PluginLoader {
private static final Logger LOGGER = LoggerFactory.getLogger("FrogLoader/Plugins");
public static void discoverModProviders(Path gameDir, Map<String, Map<String, ModProperties>> mods, Collection<String> modIds, Collection<FrogModProvider> modProviders) throws ModDependencyResolver.ResolverException {
public static void discoverModProviders(Path gameDir, Map<String, Map<String, ModProperties>> mods, Collection<String> modIds, Collection<ModProvider> modProviders) throws ModDependencyResolver.ResolverException {
LOGGER.info("Discovering mod providers...");
for (FrogModProvider plugin : ServiceLoader.load(FrogModProvider.class)) {
for (ModProvider plugin : ServiceLoader.load(ModProvider.class)) {
LOGGER.debug("Found mod provider: {}", plugin.getClass().getName());
if (!plugin.isApplicable()) {
continue;
@ -34,7 +34,7 @@ public class PluginLoader {
try {
LOGGER.debug("Initialising mod provider: {}", plugin.id());
Map<String, ModProperties> modsFromProvider = new HashMap<>();
Collection<ModProperties> loadedMods = plugin.loadMods(Discovery.find(gameDir.resolve(plugin.loadDirectory()), plugin::isDirectoryApplicable, plugin::isFileApplicable));
Collection<ModProperties> loadedMods = plugin.loadMods(Discovery.find(gameDir.resolve(plugin.loadDirectory()), plugin::isDirectoryApplicable, plugin::isFileApplicable), FrogLoaderImpl.getInstance().getClassloader()::addURL);
initializeModMixins(loadedMods);
AWProcessor.load(loadedMods);
@ -72,18 +72,18 @@ public class PluginLoader {
});
}
public static FrogGamePlugin discoverGamePlugins() {
public static GamePlugin discoverGamePlugins() {
LOGGER.info("Discovering game plugins...");
ServiceLoader<FrogGamePlugin> loader = ServiceLoader.load(FrogGamePlugin.class);
ServiceLoader<GamePlugin> loader = ServiceLoader.load(GamePlugin.class);
loader.stream().map(ServiceLoader.Provider::get).forEach(p -> LOGGER.info("Found game plugin: {}", p.getClass().getName()));
FrogGamePlugin[] applicablePlugins = ServiceLoader.load(FrogGamePlugin.class).stream().map(ServiceLoader.Provider::get).filter(FrogGamePlugin::isApplicable).toArray(FrogGamePlugin[]::new);
GamePlugin[] applicablePlugins = ServiceLoader.load(GamePlugin.class).stream().map(ServiceLoader.Provider::get).filter(GamePlugin::isApplicable).toArray(GamePlugin[]::new);
if (applicablePlugins.length > 1) {
throw new IllegalStateException("Multiple applicable game plugins found!");
} else if (applicablePlugins.length == 0) {
throw new IllegalStateException("No applicable game plugin found!");
}
FrogGamePlugin plugin = applicablePlugins[0]; // we can skip the loop as we always will only have one element
GamePlugin plugin = applicablePlugins[0]; // we can skip the loop as we always will only have one element
try {
plugin.init(FrogLoader.getInstance());
return plugin;

View file

@ -14,15 +14,16 @@ import dev.frogmc.frogloader.api.FrogLoader;
import dev.frogmc.frogloader.api.mod.ModDependencies;
import dev.frogmc.frogloader.api.mod.ModExtensions;
import dev.frogmc.frogloader.api.mod.ModProperties;
import dev.frogmc.frogloader.api.plugin.FrogGamePlugin;
import dev.frogmc.frogloader.api.plugin.GamePlugin;
import dev.frogmc.frogloader.impl.FrogLoaderImpl;
import dev.frogmc.frogloader.impl.mod.ModPropertiesImpl;
import dev.frogmc.frogloader.impl.util.SystemProperties;
import dev.frogmc.thyroxine.Thyroxine;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MinecraftGamePlugin implements FrogGamePlugin {
public class MinecraftGamePlugin implements GamePlugin {
protected final String[] MINECRAFT_CLASSES = new String[]{
"net/minecraft/client/main/Main.class",
@ -126,7 +127,7 @@ public class MinecraftGamePlugin implements FrogGamePlugin {
}
@Override
public String queryVersion() {
public @NotNull String queryVersion() {
return version;
}

View file

@ -2,23 +2,24 @@ package dev.frogmc.frogloader.impl.plugin.mod;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import java.util.function.Consumer;
import com.electronwill.nightconfig.core.UnmodifiableConfig;
import dev.frogmc.frogloader.api.FrogLoader;
import dev.frogmc.frogloader.api.extensions.PreLaunchExtension;
import dev.frogmc.frogloader.api.mod.ModProperties;
import dev.frogmc.frogloader.api.plugin.FrogModProvider;
import dev.frogmc.frogloader.impl.FrogLoaderImpl;
import dev.frogmc.frogloader.api.plugin.ModProvider;
import dev.frogmc.frogloader.impl.mod.BuiltinExtensions;
import dev.frogmc.frogloader.impl.mod.ModPropertiesReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings("unused")
public class FrogmodModProvider implements FrogModProvider {
public class FrogModProvider implements ModProvider {
public static final String MOD_FILE_EXTENSION = ".frogmod";
@ -53,7 +54,7 @@ public class FrogmodModProvider implements FrogModProvider {
}
@Override
public Collection<ModProperties> loadMods(Collection<Path> paths) throws Exception {
public Collection<ModProperties> loadMods(Collection<Path> paths, Consumer<URL> classpathAdder) throws Exception {
Path jijCache = getJijCacheDir();
Map<Path, ModProperties> mods = new HashMap<>();
@ -74,7 +75,7 @@ public class FrogmodModProvider implements FrogModProvider {
LOGGER.warn("Failed to resolve url for {}", path, e);
return null;
}
}).filter(Objects::nonNull).forEach(FrogLoaderImpl.getInstance().getClassloader()::addURL);
}).filter(Objects::nonNull).forEach(classpathAdder);
loadedMods.addAll(mods.values());

View file

@ -1,14 +1,16 @@
package dev.frogmc.frogloader.impl.plugin.mod;
import java.net.URL;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.function.Consumer;
import dev.frogmc.frogloader.api.mod.ModProperties;
import dev.frogmc.frogloader.api.plugin.FrogModProvider;
import dev.frogmc.frogloader.api.plugin.ModProvider;
import dev.frogmc.frogloader.impl.mod.JavaModProperties;
public class JavaModProvider implements FrogModProvider {
public class JavaModProvider implements ModProvider {
@Override
public String id() {
return "frogloader:integrated/java";
@ -20,7 +22,7 @@ public class JavaModProvider implements FrogModProvider {
}
@Override
public Collection<ModProperties> loadMods(Collection<Path> modFiles) throws Exception {
public Collection<ModProperties> loadMods(Collection<Path> modFiles, Consumer<URL> classpathAdder) throws Exception {
return Collections.singleton(JavaModProperties.get());
}
}

View file

@ -1,2 +0,0 @@
dev.frogmc.frogloader.impl.plugin.mod.JavaModProvider
dev.frogmc.frogloader.impl.plugin.mod.FrogmodModProvider

View file

@ -0,0 +1,2 @@
dev.frogmc.frogloader.impl.plugin.mod.JavaModProvider
dev.frogmc.frogloader.impl.plugin.mod.FrogModProvider