瀏覽代碼

New Plugin Loader

Unknown 6 年之前
父節點
當前提交
0cde1f4a83

+ 1 - 1
build.gradle

@@ -6,7 +6,7 @@ sourceCompatibility = 1.8
 targetCompatibility = 1.8
 
 archivesBaseName = "RoughlyEnoughItems"
-version = "2.0.0.40"
+version = "2.1.0.41"
 
 def minecraftVersion = "19w03c"
 def yarnVersion = "19w03c.4"

+ 64 - 7
src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java

@@ -2,15 +2,19 @@ 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.fabric.networking.CustomPayloadPacketRegistry;
+import net.fabricmc.loader.FabricLoader;
+import net.fabricmc.loader.ModContainer;
 import net.minecraft.item.ItemStack;
 import net.minecraft.server.network.ServerPlayerEntity;
 import net.minecraft.sortme.ChatMessageType;
@@ -19,17 +23,23 @@ import net.minecraft.util.Identifier;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
+import java.io.File;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.file.Files;
+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 {
     
     public static final Logger LOGGER = LogManager.getFormatterLogger("REI");
     public static final Identifier DELETE_ITEMS_PACKET = new Identifier("roughlyenoughitems", "delete_item");
     public static final Identifier CREATE_ITEMS_PACKET = new Identifier("roughlyenoughitems", "create_item");
-    public static final Identifier DEFAULT_PLUGIN = new Identifier("roughlyenoughitems", "default_plugin");
     private static final List<IListener> listeners = Lists.newArrayList();
     private static final Map<Identifier, IRecipePlugin> plugins = Maps.newHashMap();
     private static ConfigHelper configHelper;
@@ -70,14 +80,10 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer, ModInitiali
     @Override
     public void onInitializeClient() {
         registerREIListeners();
-        registerDefaultPlugin();
+        discoverPlugins();
         configHelper = new ConfigHelper();
     }
     
-    private void registerDefaultPlugin() {
-        registerPlugin(RoughlyEnoughItemsCore.DEFAULT_PLUGIN, new DefaultPlugin());
-    }
-    
     private void registerREIListeners() {
         registerListener(new ClientHelper());
         registerListener(new RecipeHelper());
@@ -95,6 +101,57 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer, ModInitiali
         registerFabricPackets();
     }
     
+    private void discoverPlugins() {
+        Collection<ModContainer> modContainers = FabricLoader.INSTANCE.getModContainers();
+        List<REIPluginInfo> pluginInfos = Lists.newArrayList();
+        JsonParser parser = new JsonParser();
+        modContainers.forEach(modContainer -> {
+            if (modContainer.getOriginFile().isFile())
+                try (JarFile file = new JarFile(modContainer.getOriginFile())) {
+                    ZipEntry entry = file.getEntry("plugins" + File.separator + "rei.plugin.json");
+                    if (entry != null) {
+                        InputStream in = file.getInputStream(entry);
+                        JsonElement jsonElement = parser.parse(new InputStreamReader(in));
+                        if (jsonElement != null && jsonElement.isJsonObject()) {
+                            REIPluginInfo info = REIPluginInfo.GSON.fromJson(jsonElement, REIPluginInfo.class);
+                            if (info != null)
+                                pluginInfos.add(info);
+                        }
+                    }
+                } catch (Exception e) {
+                    RoughlyEnoughItemsCore.LOGGER.error("REI: Failed to load REI plugin info from " + modContainer.getInfo().getId() + " when it should can. (" + e.getLocalizedMessage() + ")");
+                }
+            else if (modContainer.getOriginFile().isDirectory()) {
+                File modInfo = new File(modContainer.getOriginFile(), "plugins" + File.separator + "rei.plugin.json");
+                if (modInfo.exists())
+                    try {
+                        InputStream in = Files.newInputStream(modInfo.toPath());
+                        JsonElement jsonElement = parser.parse(new InputStreamReader(in));
+                        if (jsonElement != null && jsonElement.isJsonObject()) {
+                            REIPluginInfo info = REIPluginInfo.GSON.fromJson(jsonElement, REIPluginInfo.class);
+                            if (info != null)
+                                pluginInfos.add(info);
+                        }
+                    } catch (Exception e) {
+                        RoughlyEnoughItemsCore.LOGGER.error("REI: Failed to load REI plugin info from " + modContainer.getInfo().getId() + " when it should can. (" + e.getLocalizedMessage() + ")");
+                    }
+            }
+        });
+        pluginInfos.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 load REI plugin: " + reiPlugin.getIdentifier() + " (" + e.getLocalizedMessage() + ")");
+                }
+            });
+        });
+    }
+    
     private void registerFabricPackets() {
         CustomPayloadPacketRegistry.SERVER.register(DELETE_ITEMS_PACKET, (packetContext, packetByteBuf) -> {
             ServerPlayerEntity player = (ServerPlayerEntity) packetContext.getPlayer();

+ 34 - 0
src/main/java/me/shedaniel/rei/api/REIPluginInfo.java

@@ -0,0 +1,34 @@
+package me.shedaniel.rei.api;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.annotations.SerializedName;
+
+import java.util.List;
+
+public class REIPluginInfo {
+    
+    public static Gson GSON = new GsonBuilder().create();
+    
+    private List<REIPlugin> plugins;
+    
+    public static class REIPlugin {
+        private String identifier;
+        @SerializedName("class") private String pluginClass;
+    
+        public String getIdentifier() {
+            if (identifier == null)
+                return "null:null";
+            return identifier;
+        }
+    
+        public String getPluginClass() {
+            return pluginClass;
+        }
+    }
+    
+    public List<REIPlugin> getPlugins() {
+        return plugins;
+    }
+    
+}

+ 4 - 0
src/main/java/me/shedaniel/rei/client/ClientHelper.java

@@ -91,6 +91,10 @@ public class ClientHelper implements ClientLoaded, ClientModInitializer {
     }
     
     public static void sendDeletePacket() {
+        if (MinecraftClient.getInstance().interactionManager.hasCreativeInventory()) {
+            MinecraftClient.getInstance().player.inventory.setCursorStack(ItemStack.EMPTY);
+            return;
+        }
         PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
         MinecraftClient.getInstance().getNetworkHandler().sendPacket(new CustomPayloadServerPacket(RoughlyEnoughItemsCore.DELETE_ITEMS_PACKET, buf));
     }

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

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