Skip to content

Commit

Permalink
Implement Metadata changes (#8)
Browse files Browse the repository at this point in the history
* Implement metadata changes

* Prepare for the deprecation of Launchwrapper by moving more methods into the Loader and cleanup code

* Update actions config

* Cleanup code and generate source & javadoc jars
  • Loading branch information
ChachyDev authored Jul 29, 2021
1 parent b054804 commit 03a0d60
Show file tree
Hide file tree
Showing 26 changed files with 446 additions and 167 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ name: Build and test

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build_and_test_jdk8:
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# loader

The version independent loader for Book
7 changes: 6 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ ext {
}

group "org.bookmc"
version "0.3.0${local ? "+local" : ""}"
version "0.4.0${local ? "+local" : ""}"

repositories {
mavenCentral()
Expand Down Expand Up @@ -57,6 +57,11 @@ test {
useJUnitPlatform()
}

java {
withSourcesJar()
withJavadocJar()
}

blossom {
replaceToken("%LOADER_VERSION%", project.version)
}
Expand Down
63 changes: 22 additions & 41 deletions src/main/java/org/bookmc/loader/api/BookMCLoaderCommon.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
import net.minecraft.launchwrapper.LaunchClassLoader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bookmc.loader.api.compat.CompatiblityLayer;
import org.bookmc.loader.api.exception.IllegalDependencyException;
import org.bookmc.loader.api.vessel.ModVessel;
import org.bookmc.loader.impl.BookModLoader;
import org.bookmc.loader.api.vessel.environment.Environment;
import org.bookmc.loader.impl.Loader;
import org.bookmc.loader.impl.vessel.dummy.BookLoaderVessel;
import org.bookmc.loader.impl.vessel.dummy.JavaModVessel;
Expand All @@ -17,15 +16,15 @@
import org.bookmc.loader.shared.utils.ClassUtils;
import org.spongepowered.asm.launch.MixinBootstrap;
import org.spongepowered.asm.mixin.MixinEnvironment;
import org.spongepowered.asm.mixin.Mixins;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public abstract class BookMCLoaderCommon implements ITweaker {
private static File modsDirectory;
private static MixinEnvironment.Side side = MixinEnvironment.Side.UNKNOWN;
private static Environment environment = Environment.UNKNOWN;
private final Logger logger = LogManager.getLogger(this);
private final List<String> args = new ArrayList<>();
private String version;
Expand All @@ -34,37 +33,43 @@ public static File getModsDirectory() {
return modsDirectory;
}

public static MixinEnvironment.Side getSide() {
return side;
public static Environment getEnvironment() {
return environment;
}

public abstract void injectIntoClassLoader(LaunchClassLoader classLoader, MixinEnvironment environment);

public abstract Environment setEnvironment();

@Override
public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
this.args.addAll(args);

if (gameDir != null) {
addArg("gameDir", gameDir.getAbsolutePath());
this.args.addAll(Arrays.asList("--gameDir", gameDir.getAbsolutePath()));
}

if (assetsDir != null) {
addArg("assetsDir", assetsDir.getAbsolutePath());
this.args.addAll(Arrays.asList("--assetsDir", assetsDir.getAbsolutePath()));
}

if (profile != null) {
addArg("version", profile);
this.version = profile;
version = profile;
this.args.addAll(Arrays.asList("--version", profile));
}
}

@Override
public void injectIntoClassLoader(LaunchClassLoader classLoader) {
BookMCLoaderCommon.environment = setEnvironment();

classLoader.addClassLoaderExclusion("org.bookmc.loader.");

MixinBootstrap.init();

MixinEnvironment environment = MixinEnvironment.getDefaultEnvironment();
MixinEnvironment mixinEnvironment = MixinEnvironment.getDefaultEnvironment();

injectIntoClassLoader(classLoader, environment);
injectIntoClassLoader(classLoader, mixinEnvironment);

String passedDirectory = System.getProperty("book.discovery.folder", "mods");

Expand All @@ -79,62 +84,38 @@ public void injectIntoClassLoader(LaunchClassLoader classLoader) {
Loader.registerCandidate(new DummyCandidate(new ModVessel[]{new MinecraftModVessel(version), new JavaModVessel(), new BookLoaderVessel()}));

try {
loadModMixins(modsDirectory, classLoader);
Loader.discoverAndLoad(modsDirectory, classLoader, environment);
} catch (IllegalDependencyException e) {
e.printStackTrace();
}

if (version != null) {
try {
loadModMixins(new File(modsDirectory, version), classLoader);
Loader.discoverAndLoad(new File(modsDirectory, version), classLoader, environment);
} catch (IllegalDependencyException e) {
e.printStackTrace();
}
} else {
logger.error("Failed to detect the game version! Mods inside the game version's mod folder will not be loaded!");
}

if (environment.getObfuscationContext() == null) {
environment.setObfuscationContext("notch"); // Switch's to notch mappings
if (mixinEnvironment.getObfuscationContext() == null) {
mixinEnvironment.setObfuscationContext("notch"); // Switch's to notch mappings
}

// Load our transformation service only if it's available.
if (ClassUtils.isClassAvailable("org.bookmc.services.TransformationService")) {
classLoader.registerTransformer("org.bookmc.services.TransformationService");
}

side = setSide(environment);
mixinEnvironment.setSide(Environment.toMixin(environment));
}

public abstract void injectIntoClassLoader(LaunchClassLoader classLoader, MixinEnvironment environment);

public abstract MixinEnvironment.Side setSide(MixinEnvironment environment);

@Override
public String[] getLaunchArguments() {
return args.toArray(new String[0]);
}

private void addArg(String key, String value) {
args.add("--" + key);
args.add(value);
}

private void loadModMixins(File modsDirectory, LaunchClassLoader classLoader) throws IllegalDependencyException {
Loader.discover(modsDirectory);
BookModLoader.loadCandidates(classLoader);

for (ModVessel vessel : Loader.getModVessels()) {
Loader.loadCompatibilityLayer(vessel, classLoader);

String mixinEntrypoint = vessel.getMixinEntrypoint();
// Load mixins from everywhere (All jars should now be on the LaunchClassLoader)
if (mixinEntrypoint != null) {
Mixins.addConfiguration(mixinEntrypoint);
}
}
}

public String getVersion() {
return version;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* The ModCandidates system allows us to internally allow alternate candidates but also the default candidates
* such as {@link ZipModCandidate} which checks for the required template needed to load a Book mod such as a valid
* book.mod.json.
*
* <p>
* If you were to create your own compatibility layer you would most likely create your own implementation of
* this interface to allow for your custom candidate to be loaded. Enjoy developers!
*
Expand All @@ -21,6 +21,7 @@ public interface ModCandidate {
/**
* If the candidate has succeeded the {@link ModCandidate#isAcceptable()} phase
* you can now continue onto retrieving the vessel and loading it.
*
* @return ModVessel
*/
ModVessel[] getVessels();
Expand All @@ -30,6 +31,7 @@ public interface ModCandidate {
* If you were to create a compatability layer you would create your own ModCandidate implementation
* instead of using the current existing ones as they're heavily focused on the Book loader itself
* rather than customisation for external loaders.
*
* @return Whether the given candidate should be accepted. You should receive the required parameters
* to perform this check via the constructor of your ModCandidate implementation.
*/
Expand All @@ -39,6 +41,7 @@ public interface ModCandidate {
* Invoked directly before the vessel is registered to add the candidate to the classpath. In some cases
* such as {@link org.bookmc.loader.impl.discoverer.DevelopmentModDiscoverer} or {@link org.bookmc.loader.impl.discoverer.ClasspathModDiscoverer}
* this method may not be needed at all as the mod candidates should already be present on the classpath or something is going wrong!
*
* @param appender A custom class to abstract appending to the current URLClassLoader. (Currently {@link LaunchClassLoader})
*/
void addToClasspath(ClassLoaderURLAppender appender);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public ClassLoaderURLAppender(URLClassLoader classLoader) {
* Simply calls the {@link URLClassLoader#addURL(URL)} via reflection.
* This is due to it's default visibility being protected so we change
* the visibility and then invoke it.
*
* @param url The URL to be added to the classloader
* @author ChachyDev
* @since 0.3.0
Expand All @@ -44,4 +45,7 @@ public void add(URL url) {
}
}

public URLClassLoader getClassLoader() {
return classLoader;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package org.bookmc.loader.api.compat;

import net.minecraft.launchwrapper.LaunchClassLoader;
import org.bookmc.loader.api.BookMCLoaderCommon;
import org.bookmc.loader.api.classloader.ClassLoaderURLAppender;

public interface CompatiblityLayer {
void init(LaunchClassLoader classLoader);
void init(ClassLoaderURLAppender classLoader);
}
14 changes: 11 additions & 3 deletions src/main/java/org/bookmc/loader/api/vessel/ModVessel.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package org.bookmc.loader.api.vessel;

import org.bookmc.loader.api.vessel.author.Author;
import org.bookmc.loader.api.vessel.dependency.ModDependency;
import org.bookmc.loader.api.vessel.entrypoint.Entrypoint;
import org.bookmc.loader.api.vessel.entrypoint.MixinEntrypoint;
import org.bookmc.loader.api.vessel.environment.Environment;

import java.io.File;
import java.net.URL;
Expand All @@ -19,22 +23,26 @@ public interface ModVessel {
String getConfig();

// Returns the authors of the mod
String[] getAuthors();
Author[] getAuthors();

// Get version of the mod
String getVersion();

// Get an (optional) icon
String getIcon();

String getLicense();

// Get the entrypoint of the mod
String getEntrypoint();
Entrypoint[] getEntrypoints();

Environment getEnvironment();

// Return the location of the mod (If it is a jar/zip mod)
File getFile();

// Returns the mixin entrypoint file (if available)
String getMixinEntrypoint();
MixinEntrypoint[] getMixinEntrypoints();

// Returns the dependencies of the mod
ModDependency[] getDependsOn();
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/org/bookmc/loader/api/vessel/author/Author.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.bookmc.loader.api.vessel.author;

public class Author {
private final String name;
private final String github;
private final String email;

public Author(String name, String github, String email) {
this.name = name;
this.github = github;
this.email = email;
}

public String getName() {
return name;
}

public String getGithub() {
return github;
}

public String getEmail() {
return email;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.bookmc.loader.api.vessel.entrypoint;

public class Entrypoint {
private final String owner;
private final String method;

public Entrypoint(String owner, String method) {
this.owner = owner;
this.method = method;
}

public String getOwner() {
return owner;
}

public String getMethod() {
return method;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.bookmc.loader.api.vessel.entrypoint;

import org.bookmc.loader.api.vessel.environment.Environment;

public class MixinEntrypoint {
private final String mixinFile;
private final Environment environment;

public MixinEntrypoint(String mixinFile, Environment environment) {
this.mixinFile = mixinFile;
this.environment = environment;
}

public String getMixinFile() {
return mixinFile;
}

public Environment getEnvironment() {
return environment;
}
}
Loading

0 comments on commit 03a0d60

Please sign in to comment.