Skip to content

Commit

Permalink
Finish the loading for now (there's still stuff to do but this is goo…
Browse files Browse the repository at this point in the history
…d enough for now) and do a bit a cleanup
  • Loading branch information
nelind3 committed Oct 14, 2024
1 parent b9bcb4c commit 310ab04
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,7 @@
*/
package dk.nelind.loofah.applaunch.plugin;

import org.spongepowered.plugin.Environment;
import org.spongepowered.plugin.builtin.StandardPluginLanguageService;
import org.spongepowered.plugin.metadata.Container;
import org.spongepowered.plugin.metadata.builtin.MetadataParser;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

/**
* Adapted from {@link org.spongepowered.vanilla.applaunch.plugin.JavaPluginLanguageService}
Expand All @@ -51,11 +43,4 @@ public String pluginLoader() {
// hard coded string to avoid circular gradle task dependency hell
return "dk.nelind.loofah.launch.plugin.JavaPluginLoader";
}

@Override
public Container loadMetadataContainer(final Environment environment, final InputStream stream) throws Exception {
final BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
return MetadataParser.read(reader, MetadataParser.gsonBuilder().create());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,72 @@
*/
package dk.nelind.loofah.applaunch.plugin.resource;

import net.fabricmc.loader.impl.launch.FabricLauncherBase;
import net.fabricmc.loader.impl.util.FileSystemUtil;
import org.spongepowered.plugin.builtin.jvm.JVMPluginResource;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

// TODO(loofah): figure out what do to here. works fine for current needs but probably doesn't actually act up to spec
// (regarding unioned paths). Consider if there's something in fabric-loader itself we can hook into and use?
public class FabricPluginResource implements JVMPluginResource {
private final String locator;
private final Path[] paths;
private final List<Path> paths;
private final Manifest manifest;

public FabricPluginResource(final String locator, final Path[] paths) {
this.locator = locator;
this.paths = paths;
this.manifest = new Manifest();
if (Files.exists(this.resourcesRoot().resolve(JarFile.MANIFEST_NAME))) {
try {
this.manifest.read(Files.newInputStream(this.resourcesRoot().resolve(JarFile.MANIFEST_NAME)));
} catch (IOException e) {
throw new RuntimeException(e);
try {
this.paths = FabricPluginResource.processPaths(paths);
this.manifest = FabricPluginResource.getManifest(this.paths);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private static List<Path> processPaths(Path[] paths) throws IOException {
var processedPaths = new ArrayList<Path>();

for (Path path : paths) {
if (Files.isDirectory(path)) {
FabricLauncherBase.getLauncher().addToClassPath(path);
processedPaths.add(path);
continue;
}

if (path.toString().endsWith(".jar")) {
var fs = FileSystemUtil.getJarFileSystem(path, false);
var jarPath = fs.get().getRootDirectories().iterator().next();
FabricLauncherBase.getLauncher().addToClassPath(jarPath);
processedPaths.add(jarPath);
continue;
}

throw new IllegalStateException(String.format("Resource path \"%s\" of unknown type given!" +
"Plugins can only be provided in jar or directory form!", path));
}

return processedPaths;
}

public static Manifest getManifest(List<Path> paths) throws IOException {
var manifest = new Manifest();

for (Path path : paths) {
var manifestPath = path.resolve(JarFile.MANIFEST_NAME);
if (Files.exists(manifestPath)) {
manifest.read(Files.newInputStream(manifestPath));
break;
}
}

return manifest;
}

@Override
Expand All @@ -59,7 +99,7 @@ public String locator() {

@Override
public Path path() {
return this.paths[paths.length - 1];
return this.paths.getLast();
}

@Override
Expand Down
14 changes: 12 additions & 2 deletions loofah/src/launch/java/dk/nelind/loofah/launch/FabricLaunch.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@
public class FabricLaunch extends Launch {
private final FabricMappingManager mappingManager;
private final FabricPluginManager pluginManager;
public static final List<String> PLATFORM_PLUGINS = List.of(
"minecraft",
"fabricloader",
"fabric-api",
"spongeapi",
"sponge",
"loofah"
);

public FabricLaunch(PluginPlatform pluginPlatform) {
super(pluginPlatform);
Expand All @@ -65,6 +73,7 @@ public static void launch(FabricPluginPlatform pluginPlatform) {
FabricLaunch launch = new FabricLaunch(pluginPlatform);
Launch.setInstance(launch);
launch.bootstrap();
launch.loadPlugins();
}

private void bootstrap() {
Expand All @@ -80,8 +89,9 @@ private void bootstrap() {
this.setLifecycle(lifecycle);
lifecycle.establishFactories();
lifecycle.establishBuilders();
}

this.logger().info("Loading Plugins");
private void loadPlugins() {
this.pluginManager.loadPlugins(this.pluginPlatform());
}

Expand All @@ -106,7 +116,7 @@ private void createPlatformPlugins() {
// Get SpongeCommon and SpongeAPI plugins from the mod jar
// since they can't be loom included for a variety of reasons
this.pluginPlatform().getCandidates().values().stream().flatMap(Collection::stream)
.filter(plugin -> List.of("spongeapi", "sponge").contains(plugin.metadata().id()))
.filter(plugin -> PLATFORM_PLUGINS.contains(plugin.metadata().id()))
.map(FabricDummyPluginContainer::of)
.forEach(this.pluginManager()::addPlugin);
this.pluginManager.addPlugin(FabricModBackedPluginContainer.of(loofahMod));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
*/
package dk.nelind.loofah.launch.plugin.modbacked;

import dk.nelind.loofah.applaunch.plugin.resource.FabricPluginResource;
import net.fabricmc.loader.api.ModContainer;
import net.fabricmc.loader.api.metadata.ModMetadata;
import org.spongepowered.plugin.PluginCandidate;
Expand All @@ -33,18 +32,13 @@
import org.spongepowered.plugin.metadata.builtin.StandardPluginMetadata;
import org.spongepowered.plugin.metadata.builtin.model.StandardPluginContributor;

import java.nio.file.Path;

// TODO(loofah): consider making a mod backed plugin locator/language service/loader triplet
public class FabricModBackedPluginCandidate implements PluginCandidate {
private final PluginMetadata pluginMetadata;
private final FabricPluginResource pluginResource;
private final PluginResource pluginResource;

public FabricModBackedPluginCandidate(final ModContainer modContainer) {
this.pluginResource = new FabricPluginResource(
"fabric_loader",
modContainer.getOrigin().getPaths().toArray(new Path[0])
);
this.pluginResource = new FabricModBackedPluginResource(modContainer);
this.pluginMetadata = FabricModBackedPluginCandidate.pluginMetadataFromMod(modContainer.getMetadata());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* This file is part of Loofah, licensed under the MIT License (MIT).
*
* Copyright (c) Nelind <https://www.nelind.dk>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package dk.nelind.loofah.launch.plugin.modbacked;

import dk.nelind.loofah.applaunch.plugin.resource.FabricPluginResource;
import net.fabricmc.loader.api.ModContainer;
import org.spongepowered.plugin.builtin.jvm.JVMPluginResource;

import java.io.IOException;
import java.nio.file.Path;
import java.util.jar.Manifest;

public class FabricModBackedPluginResource implements JVMPluginResource {
private final ModContainer mod;
private final Manifest manifest;

public FabricModBackedPluginResource(ModContainer mod) {
this.mod = mod;
try {
// TODO(loofah): idk this feels weird but i don't see an immediate need to pull this out into a
// util class so in FabricPluginResource it shall stay
this.manifest = FabricPluginResource.getManifest(mod.getRootPaths());
} catch (IOException e) {
throw new RuntimeException(e);
}
}

@Override
public Manifest manifest() {
return this.manifest;
}

@Override
public Path resourcesRoot() {
return this.mod.getRootPaths().getLast();
}

@Override
public String locator() {
return "fabric_loader";
}

@Override
public Path path() {
return this.mod.getOrigin().getPaths().getLast();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public static ResolutionResult resolveAndSortCandidates(final Collection<PluginC
final Logger logger) {
final Map<String, Node> nodes = new HashMap<>();
final ResolutionResult resolutionResult = new ResolutionResult();
// TODO(loofah): since sponge and spongeapi are loaded as candidates but the rest of the platform plugins
// aren't the sponge plugin throws a missing dep error for minecraft
for (final PluginCandidate candidate : candidates) {
final String id = candidate.metadata().id();
// If we already have an entry, this is now a duplicate ID situation.
Expand Down

0 comments on commit 310ab04

Please sign in to comment.