Переглянути джерело

Migrate to pluginloader

With this implementation, the loader will only be created on the client
to mimic the current implementation. If plugin loader is not installed,
the default plugin will still be registered so core functionality is
preserved.
Nicholas Ignoffo 6 роки тому
батько
коміт
9d8b4cee3a

+ 7 - 0
build.gradle

@@ -11,6 +11,7 @@ version = "2.1.0.42"
 def minecraftVersion = "19w03c"
 def yarnVersion = "19w03c.4"
 def fabricVersion = "0.1.4.76"
+def pluginLoaderVersion = "1.14-1.0.6-8"
 
 minecraft {
 }
@@ -22,6 +23,10 @@ processResources {
 	inputs.property "version", project.version
 }
 
+repositories {
+	maven { url "https://tehnut.info/maven/" }
+}
+
 dependencies {
 	minecraft "com.mojang:minecraft:${minecraftVersion}"
 	mappings "net.fabricmc:yarn:${yarnVersion}"
@@ -29,6 +34,8 @@ dependencies {
 
 	// Fabric API. This is technically optional, but you probably want it anyway.
 	modCompile "net.fabricmc:fabric:${fabricVersion}"
+	
+	modCompile "info.tehnut.pluginloader:plugin-loader:${pluginLoaderVersion}"
 }
 
 // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task

+ 5 - 71
src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java

@@ -2,19 +2,16 @@ package me.shedaniel.rei;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParser;
 import me.shedaniel.rei.api.IRecipePlugin;
-import me.shedaniel.rei.api.REIPluginInfo;
 import me.shedaniel.rei.client.ClientHelper;
 import me.shedaniel.rei.client.ConfigHelper;
 import me.shedaniel.rei.client.RecipeHelper;
 import me.shedaniel.rei.listeners.IListener;
+import me.shedaniel.rei.plugin.DefaultPlugin;
 import net.fabricmc.api.ClientModInitializer;
 import net.fabricmc.api.ModInitializer;
+import net.fabricmc.api.loader.Loader;
 import net.fabricmc.fabric.networking.CustomPayloadPacketRegistry;
-import net.fabricmc.loader.FabricLoader;
-import net.fabricmc.loader.ModContainer;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.item.ItemStack;
 import net.minecraft.server.network.ServerPlayerEntity;
@@ -25,19 +22,10 @@ import net.minecraft.util.Identifier;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.file.Files;
-import java.nio.file.StandardOpenOption;
-import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.jar.JarFile;
 import java.util.stream.Collectors;
-import java.util.zip.ZipEntry;
 
 public class RoughlyEnoughItemsCore implements ClientModInitializer, ModInitializer {
     
@@ -84,7 +72,9 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer, ModInitiali
     @Override
     public void onInitializeClient() {
         registerREIListeners();
-        discoverPlugins();
+        // If pluginloader is not installed, base functionality should still remain
+        if (!Loader.getInstance().isModLoaded("pluginloader"))
+            registerPlugin(new Identifier("roughlyenoughitems", "default_plugin"), new DefaultPlugin());
         configHelper = new ConfigHelper();
     }
     
@@ -105,62 +95,6 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer, ModInitiali
         registerFabricPackets();
     }
     
-    private void discoverPlugins() {
-        Collection<ModContainer> modContainers = FabricLoader.INSTANCE.getModContainers();
-        List<REIPluginInfo> pluginInfoList = Lists.newArrayList();
-        JsonParser parser = new JsonParser();
-        modContainers.forEach(modContainer -> {
-            InputStream inputStream = null;
-            if (modContainer.getOriginFile().isFile())
-                try (JarFile file = new JarFile(modContainer.getOriginFile())) {
-                    ZipEntry entry = file.getEntry("plugins" + File.separatorChar + "rei.plugin.json");
-                    if (entry != null)
-                        inputStream = file.getInputStream(entry);
-                } catch (Exception e) {
-                    RoughlyEnoughItemsCore.LOGGER.error("REI: Failed to load plugin file from " + modContainer.getInfo().getId() + ". (" + e.getLocalizedMessage() + ")");
-                }
-            else if (modContainer.getOriginFile().isDirectory()) {
-                File modInfo = new File(modContainer.getOriginFile(), "plugins" + File.separatorChar + "rei.plugin.json");
-                if (modInfo.exists())
-                    try {
-                        inputStream = Files.newInputStream(modInfo.toPath(), StandardOpenOption.READ);
-                    } catch (Exception e) {
-                        RoughlyEnoughItemsCore.LOGGER.error("REI: Failed to load plugin file from " + modContainer.getInfo().getId() + ". (" + e.getLocalizedMessage() + ")");
-                    }
-            }
-            if (inputStream != null)
-                try {
-                    JsonElement jsonElement = parser.parse(new InputStreamReader(inputStream));
-                    if (jsonElement != null && jsonElement.isJsonObject()) {
-                        REIPluginInfo info = REIPluginInfo.GSON.fromJson(jsonElement, REIPluginInfo.class);
-                        if (info != null)
-                            pluginInfoList.add(info);
-                    }
-                } catch (Exception e) {
-                    RoughlyEnoughItemsCore.LOGGER.error("REI: Failed to load REI plugin info from " + modContainer.getInfo().getId() + ". (" + e.getLocalizedMessage() + ")");
-                } finally {
-                    try {
-                        inputStream.close();
-                    } catch (IOException e) {
-                        RoughlyEnoughItemsCore.LOGGER.error("REI: Failed to close input stream from " + modContainer.getInfo().getId() + ". (" + e.getLocalizedMessage() + ")");
-                    }
-                }
-        });
-        pluginInfoList.stream().forEachOrdered(reiPluginInfo -> {
-            reiPluginInfo.getPlugins().forEach(reiPlugin -> {
-                try {
-                    Identifier identifier = new Identifier(reiPlugin.getIdentifier());
-                    Class<?> aClass = Class.forName(reiPlugin.getPluginClass());
-                    IRecipePlugin plugin = IRecipePlugin.class.cast(aClass.newInstance());
-                    RoughlyEnoughItemsCore.registerPlugin(identifier, plugin);
-                    RoughlyEnoughItemsCore.LOGGER.info("REI: Registered REI plugin: " + reiPlugin.getIdentifier());
-                } catch (Exception e) {
-                    RoughlyEnoughItemsCore.LOGGER.error("REI: Failed to register REI plugin: " + reiPlugin.getIdentifier() + ". (" + e.getLocalizedMessage() + ")");
-                }
-            });
-        });
-    }
-    
     private void registerFabricPackets() {
         CustomPayloadPacketRegistry.SERVER.register(DELETE_ITEMS_PACKET, (packetContext, packetByteBuf) -> {
             ServerPlayerEntity player = (ServerPlayerEntity) packetContext.getPlayer();

+ 31 - 0
src/main/java/me/shedaniel/rei/RoughlyEnoughItemsPlugins.java

@@ -0,0 +1,31 @@
+package me.shedaniel.rei;
+
+import info.tehnut.pluginloader.LoaderCreator;
+import info.tehnut.pluginloader.PluginLoaderBuilder;
+import info.tehnut.pluginloader.ValidationStrategy;
+import me.shedaniel.rei.api.IRecipePlugin;
+import net.fabricmc.loader.language.LanguageAdapter;
+import net.fabricmc.loader.language.LanguageAdapterException;
+import net.minecraft.util.Identifier;
+
+public class RoughlyEnoughItemsPlugins implements LoaderCreator {
+
+    @Override
+    public void createLoaders() {
+        LanguageAdapter.Options instantiationOptions = new LanguageAdapter.Options();
+
+        new PluginLoaderBuilder("roughlyenoughitems")
+                .withValidator(ValidationStrategy.hasInterface(IRecipePlugin.class))
+                .withInitializer((aClass, container) -> {
+                    Identifier id = new Identifier(container.getOwner().getInfo().getId(), container.getInfo().getId());
+                    try {
+                        IRecipePlugin plugin = (IRecipePlugin) container.getOwner().getAdapter().createInstance(aClass, instantiationOptions);
+                        RoughlyEnoughItemsCore.registerPlugin(id, plugin);
+                        RoughlyEnoughItemsCore.LOGGER.info("Registered plugin %s from %s", id, aClass);
+                    } catch (LanguageAdapterException e) {
+                        RoughlyEnoughItemsCore.LOGGER.error("Error loading plugin %s", id, e);
+                    }
+                })
+                .build();
+    }
+}

+ 3 - 0
src/main/resources/fabric.mod.json

@@ -14,6 +14,9 @@
   "requires": {
     "fabric": "0.1.4.76"
   },
+  "recommended": {
+    "pluginloader": "1.0.7"
+  },
   "mixins": {
     "client": "roughlyenoughitems.client.json"
   }

+ 7 - 0
src/main/resources/pluginloader.json

@@ -0,0 +1,7 @@
+{
+  "id": "roughlyenoughitems",
+  "initializer": "me.shedaniel.rei.RoughlyEnoughItemsPlugins",
+  "data": {
+    "side": "CLIENT"
+  }
+}

+ 0 - 8
src/main/resources/plugins/rei.plugin.json

@@ -1,8 +0,0 @@
-{
-  "plugins": [
-    {
-      "identifier": "roughlyenoughitems:default_plugin",
-      "class": "me.shedaniel.rei.plugin.DefaultPlugin"
-    }
-  ]
-}

+ 6 - 0
src/main/resources/plugins/roughlyenoughitems.plugin.json

@@ -0,0 +1,6 @@
+[
+  {
+    "id": "default_plugin",
+    "initializer": "me.shedaniel.rei.plugin.DefaultPlugin"
+  }
+]