Skip to content

Commit

Permalink
Bootstrap SpongeCommon and initial plugin loading impl
Browse files Browse the repository at this point in the history
  • Loading branch information
nelind3 committed Sep 11, 2024
1 parent b9cf0e6 commit 9ea235d
Show file tree
Hide file tree
Showing 11 changed files with 870 additions and 14 deletions.
4 changes: 3 additions & 1 deletion loofah/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,10 @@ val fabricAppLaunch by sourceSets.register("applaunch") {
// implementation (compile) dependencies
spongeImpl.applyNamedDependencyOnOutput(commonProject, launch, this, project, this.implementationConfigurationName)
spongeImpl.applyNamedDependencyOnOutput(commonProject, applaunch, this, project, this.implementationConfigurationName)
spongeImpl.applyNamedDependencyOnOutput(commonProject, fabricLaunch, this, project, this.implementationConfigurationName)

spongeImpl.applyNamedDependencyOnOutput(project, this, fabricMain, project, fabricMain.implementationConfigurationName)
spongeImpl.applyNamedDependencyOnOutput(project, this, fabricLaunch, project, fabricLaunch.implementationConfigurationName)


configurations.named(implementationConfigurationName) {
extendsFrom(gameManagedLibraries)
Expand Down Expand Up @@ -179,6 +180,7 @@ dependencies {
exclude("com.google.code.gson")
}
fabricBootstrapLibrariesConfig(apiLibs.configurate.yaml)
fabricBootstrapLibrariesConfig(apiLibs.guice)
fabricLibrariesConfig("org.spongepowered:spongeapi:$apiVersion") { isTransitive = false }
fabricLibrariesConfig(platform(apiLibs.adventure.bom))
fabricLibrariesConfig(apiLibs.adventure.api)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,30 @@
package dk.nelind.loofah.applaunch;

import dk.nelind.loofah.applaunch.plugin.FabricPluginPlatform;
import dk.nelind.loofah.launch.FabricLaunch;
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
import org.spongepowered.common.applaunch.AppLaunch;
import org.spongepowered.common.launch.Launch;

import java.lang.reflect.InvocationTargetException;

public class AppLaunchMain implements PreLaunchEntrypoint {
@Override
public void onPreLaunch() {
FabricPluginPlatform pluginPlatform = AppLaunch.pluginPlatform();
final FabricPluginPlatform pluginPlatform = AppLaunch.pluginPlatform();

pluginPlatform.discoverLocatorServices();
pluginPlatform.discoverLanguageServices();

pluginPlatform.locatePluginResources();
pluginPlatform.createPluginCandidates();

Launch.setInstance(new FabricLaunch(pluginPlatform));

// reflection call to avoid circular gradle task dependency hell
try {
Class.forName("dk.nelind.loofah.launch.FabricLaunch")
.getMethod("launch", FabricPluginPlatform.class)
.invoke(null, pluginPlatform);
} catch (IllegalAccessException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@
import org.spongepowered.common.applaunch.config.core.SpongeConfigs;
import org.spongepowered.common.applaunch.plugin.PluginPlatform;
import org.spongepowered.common.applaunch.plugin.PluginPlatformConstants;
import org.spongepowered.plugin.PluginCandidate;
import org.spongepowered.plugin.PluginLanguageService;
import org.spongepowered.plugin.PluginResource;
import org.spongepowered.plugin.PluginResourceLocatorService;
import org.spongepowered.plugin.*;
import org.spongepowered.plugin.blackboard.Keys;
import org.spongepowered.plugin.builtin.StandardEnvironment;
import org.spongepowered.plugin.builtin.jvm.JVMKeys;
Expand Down Expand Up @@ -87,6 +84,10 @@ public static synchronized void bootstrap() {
FabricPluginPlatform.bootstrapped = true;
}

public Environment getStandardEnvironment() {
return this.standardEnvironment;
}

@Override
public String version() {
return this.standardEnvironment.blackboard().get(Keys.VERSION);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
*/
package dk.nelind.loofah.applaunch.plugin;

import dk.nelind.loofah.launch.plugin.JavaPluginLoader;
import org.spongepowered.plugin.Environment;
import org.spongepowered.plugin.builtin.jvm.JVMPluginLanguageService;
import org.spongepowered.plugin.metadata.Container;
Expand All @@ -49,7 +48,8 @@ public String name() {

@Override
public String pluginLoader() {
return JavaPluginLoader.class.getName();
// hard coded string to avoid circular gradle task dependency hell
return "dk.nelind.loofah.launch.plugin.JavaPluginLoader";
}

@Override
Expand Down
53 changes: 51 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 @@ -24,23 +24,67 @@
*/
package dk.nelind.loofah.launch;

import com.google.common.collect.Lists;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Stage;
import dk.nelind.loofah.applaunch.plugin.FabricPluginPlatform;
import dk.nelind.loofah.launch.inject.FabricModule;
import dk.nelind.loofah.launch.mapping.FabricMappingManager;
import dk.nelind.loofah.launch.plugin.FabricPluginManager;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.SharedConstants;
import org.spongepowered.common.SpongeCommon;
import org.spongepowered.common.SpongeLifecycle;
import org.spongepowered.common.applaunch.plugin.PluginPlatform;
import org.spongepowered.common.inject.SpongeCommonModule;
import org.spongepowered.common.inject.SpongeGuice;
import org.spongepowered.common.inject.SpongeModule;
import org.spongepowered.common.launch.Launch;
import org.spongepowered.common.launch.mapping.SpongeMappingManager;
import org.spongepowered.common.launch.plugin.SpongePluginManager;
import org.spongepowered.plugin.PluginContainer;

import java.util.List;

public class FabricLaunch extends Launch {
private final SpongeMappingManager mappingManager;
private final FabricMappingManager mappingManager;
private final FabricPluginManager pluginManager;

public FabricLaunch(PluginPlatform pluginPlatform) {
super(pluginPlatform);
this.mappingManager = new FabricMappingManager();
this.pluginManager = new FabricPluginManager();
}

public static void launch(FabricPluginPlatform pluginPlatform) {
FabricLaunch launch = new FabricLaunch(pluginPlatform);
Launch.setInstance(launch);
launch.bootstrap();
}

private void bootstrap() {
this.createPlatformPlugins();

// SpongeCommon bootstrap based on org.spongepowered.forge.mixin.core.server.BootstrapMixin_Forge
// and org.spongepowered.vanilla.launch.VanillaBootstrap
SharedConstants.tryDetectVersion();
final Stage stage = SpongeGuice.getInjectorStage(this.injectionStage());
SpongeCommon.logger().debug("Creating injector in stage '{}'", stage);
final Injector bootstrapInjector = this.createInjector();
final SpongeLifecycle lifecycle = bootstrapInjector.getInstance(SpongeLifecycle.class);
this.setLifecycle(lifecycle);
lifecycle.establishFactories();
lifecycle.establishBuilders();

this.logger().info("Loading Plugins");
this.pluginManager.loadPlugins((FabricPluginPlatform) this.pluginPlatform);
}

private void createPlatformPlugins() {
// TODO(loofah): create the platform plugins
}

@Override
Expand Down Expand Up @@ -70,6 +114,11 @@ public PluginContainer platformPlugin() {

@Override
public Injector createInjector() {
return null;
final List<Module> modules = Lists.newArrayList(
new SpongeModule(),
new SpongeCommonModule(),
new FabricModule()
);
return Guice.createInjector(this.injectionStage(), modules);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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.inject;

import com.google.inject.AbstractModule;

// TODO(loofah): finish platform injector
public class FabricModule extends AbstractModule {
@Override
protected void configure() {
//this.bind(Platform.class).to();
//this.bind(EventManager.class).toProvider();
//this.bind(SpongeCommandManager.class).to();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* 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;

import org.apache.logging.log4j.Logger;
import org.spongepowered.common.applaunch.plugin.DummyPluginContainer;
import org.spongepowered.plugin.PluginContainer;
import org.spongepowered.plugin.metadata.PluginMetadata;

import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Objects;
import java.util.Optional;
import java.util.StringJoiner;

public final class FabricDummyPluginContainer implements PluginContainer, DummyPluginContainer {

private final PluginMetadata metadata;
private final Logger logger;
private final Object instance;

public FabricDummyPluginContainer(final PluginMetadata metadata, final Logger logger, final Object instance) {
this.metadata = metadata;
this.logger = logger;
this.instance = instance;
}

@Override
public PluginMetadata metadata() {
return this.metadata;
}

@Override
public Logger logger() {
return this.logger;
}

@Override
public Object instance() {
return this.instance;
}

@Override
public Optional<URI> locateResource(final URI relative) {
final ClassLoader classLoader = this.getClass().getClassLoader();
final URL resolved = classLoader.getResource(relative.getPath());
try {
if (resolved == null) {
return Optional.empty();
}
return Optional.of(resolved.toURI());
} catch (final URISyntaxException ignored) {
return Optional.empty();
}
}

@Override
public int hashCode() {
return Objects.hash(this.metadata().id());
}

@Override
public boolean equals(final Object that) {
if (that == this) {
return true;
}

if (!(that instanceof PluginContainer)) {
return false;
}

return this.metadata().id().equals(((PluginContainer) that).metadata().id());
}

@Override
public String toString() {
return new StringJoiner(", ", FabricDummyPluginContainer.class.getSimpleName() + "[", "]")
.add("metadata= " + this.metadata)
.toString();
}
}
Loading

0 comments on commit 9ea235d

Please sign in to comment.