diff options
author | Raven Szewczyk <git@eigenraven.me> | 2024-07-27 07:12:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-27 13:12:04 +0700 |
commit | c7b38c23c5b34a324256966f0a9335694fe8d63b (patch) | |
tree | 92aab6471745549a79c9f84f38c3076d9275ac4f | |
parent | c55db9d91fa0a065d7565107a1eca679698eab04 (diff) | |
download | GT5-Unofficial-c7b38c23c5b34a324256966f0a9335694fe8d63b.tar.gz GT5-Unofficial-c7b38c23c5b34a324256966f0a9335694fe8d63b.tar.bz2 GT5-Unofficial-c7b38c23c5b34a324256966f0a9335694fe8d63b.zip |
Optimize load time (#2774)
* Load time optimization: replace recipe reflection with mixin accessor
* Save an inner loop allocation in StaticRecipeChangeLoaders
* Move Bauble event handler from individual items to GT++ proxy
* Update mobs info with more optimizations
15 files changed, 273 insertions, 364 deletions
diff --git a/dependencies.gradle b/dependencies.gradle index 1403edbe0d..b358aa4615 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -46,7 +46,7 @@ dependencies { api("com.github.GTNewHorizons:AE2FluidCraft-Rework:1.3.16-gtnh:dev") api('com.github.GTNewHorizons:Yamcl:0.6.0:dev') api('com.github.GTNewHorizons:ThaumicTinkerer:2.10.1:dev') - api("com.github.GTNewHorizons:Mobs-Info:0.3.1-GTNH:dev") + api("com.github.GTNewHorizons:Mobs-Info:0.3.2-GTNH:dev") devOnlyNonPublishable("com.github.GTNewHorizons:Infernal-Mobs:1.8.1-GTNH:dev") runtimeOnly("com.github.GTNewHorizons:Draconic-Evolution:1.3.6-GTNH:dev") // needed? diff --git a/src/main/java/com/elisis/gtnhlanth/loader/RecipeLoader.java b/src/main/java/com/elisis/gtnhlanth/loader/RecipeLoader.java index 14194af8f7..b3dea32ca7 100644 --- a/src/main/java/com/elisis/gtnhlanth/loader/RecipeLoader.java +++ b/src/main/java/com/elisis/gtnhlanth/loader/RecipeLoader.java @@ -118,26 +118,15 @@ import static gtPlusPlus.api.recipe.GTPPRecipeMaps.chemicalDehydratorRecipes; import static gtPlusPlus.api.recipe.GTPPRecipeMaps.simpleWasherRecipes; import static gtPlusPlus.api.recipe.GTPPRecipeMaps.vacuumFurnaceRecipes; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import java.util.HashSet; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.IRecipe; -import net.minecraft.item.crafting.ShapedRecipes; -import net.minecraft.item.crafting.ShapelessRecipes; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.oredict.OreDictionary; -import net.minecraftforge.oredict.ShapedOreRecipe; -import net.minecraftforge.oredict.ShapelessOreRecipe; - -import org.apache.commons.lang3.reflect.FieldUtils; import com.elisis.gtnhlanth.Tags; import com.elisis.gtnhlanth.common.item.MaskList; @@ -156,6 +145,7 @@ import gregtech.api.enums.ItemList; import gregtech.api.enums.Materials; import gregtech.api.enums.OrePrefixes; import gregtech.api.enums.TierEU; +import gregtech.api.interfaces.IRecipeMutableAccess; import gregtech.api.util.GT_Log; import gregtech.api.util.GT_ModHandler; import gregtech.api.util.GT_OreDictUnificator; @@ -4280,133 +4270,26 @@ public class RecipeLoader { GT_Log.out.print("Crafting Table done!\n"); } - // below are taken from GoodGenerator - - // I don't understand. . . - // I use and copy some private methods in Bartworks because his system runs well. - // Bartworks is under MIT License - /* - * Copyright (c) 2018-2020 bartimaeusnek 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. - */ public static void replaceInCraftTable(Object obj) { - - Constructor<?> cs = null; - PlatinumSludgeOverHaul BartObj = null; - try { - cs = PlatinumSludgeOverHaul.class.getDeclaredConstructor(); - cs.setAccessible(true); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } - - if (cs == null) return; - - try { - BartObj = (PlatinumSludgeOverHaul) cs.newInstance(); - } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { - e.printStackTrace(); - } - - Method recipeCheck = null; - - try { - recipeCheck = PlatinumSludgeOverHaul.class.getDeclaredMethod("checkRecipe", Object.class, Materials.class); - recipeCheck.setAccessible(true); - } catch (Exception e) { - e.printStackTrace(); - } - - String inputName = "output"; - String inputItemName = "input"; - if (!(obj instanceof ShapedOreRecipe || obj instanceof ShapelessOreRecipe)) { - if (obj instanceof ShapedRecipes || (obj instanceof ShapelessRecipes)) { - inputName = "recipeOutput"; - inputItemName = "recipeItems"; - } - } IRecipe recipe = (IRecipe) obj; ItemStack result = recipe.getRecipeOutput(); - - Field out = FieldUtils.getDeclaredField(recipe.getClass(), inputName, true); - if (out == null) out = FieldUtils.getField(recipe.getClass(), inputName, true); - - Field in = FieldUtils.getDeclaredField(recipe.getClass(), inputItemName, true); - if (in == null) in = FieldUtils.getField(recipe.getClass(), inputItemName, true); - if (in == null) return; - - // this part here is NOT MIT LICENSED BUT LICSENSED UNDER THE Apache License, Version 2.0! - try { - if (Modifier.isFinal(in.getModifiers())) { - // Do all JREs implement Field with a private ivar called "modifiers"? - Field modifiersField = Field.class.getDeclaredField("modifiers"); - boolean doForceAccess = !modifiersField.isAccessible(); - if (doForceAccess) { - modifiersField.setAccessible(true); - } - try { - modifiersField.setInt(in, in.getModifiers() & ~Modifier.FINAL); - } finally { - if (doForceAccess) { - modifiersField.setAccessible(false); - } - } - } - } catch (NoSuchFieldException ignored) { - // The field class contains always a modifiers field - } catch (IllegalAccessException ignored) { - // The modifiers field is made accessible - } - // END OF APACHE COMMONS COLLECTION COPY - - Object input; - try { - input = in.get(obj); - } catch (IllegalAccessException e) { - e.printStackTrace(); + if (!(recipe instanceof IRecipeMutableAccess mutableRecipe)) { return; } - if (out == null || recipeCheck == null) return; + Object input = mutableRecipe.gt5u$getRecipeInputs(); if (GT_Utility.areStacksEqual(result, Materials.Cerium.getDust(1), true)) { - - recipeCheck.setAccessible(true); - boolean isOk = true; - - try { - isOk = (boolean) recipeCheck.invoke(BartObj, input, Materials.Cerium); - } catch (InvocationTargetException | IllegalAccessException ignored) {} - - if (isOk) return; - try { - out.set(recipe, WerkstoffMaterialPool.CeriumRichMixture.get(OrePrefixes.dust, 2)); - } catch (IllegalAccessException e) { - e.printStackTrace(); + if (PlatinumSludgeOverHaul.checkRecipe(input, Materials.Cerium)) { + return; } + mutableRecipe.gt5u$setRecipeOutputItem(WerkstoffMaterialPool.CeriumRichMixture.get(OrePrefixes.dust, 2)); } else if (GT_Utility.areStacksEqual(result, Materials.Samarium.getDust(1), true)) { - - recipeCheck.setAccessible(true); - boolean isOk = true; - - try { - isOk = (boolean) recipeCheck.invoke(BartObj, input, Materials.Samarium); - } catch (InvocationTargetException | IllegalAccessException ignored) {} - - if (isOk) return; - try { - out.set(recipe, WerkstoffMaterialPool.SamariumOreConcentrate.get(OrePrefixes.dust, 2)); - } catch (IllegalAccessException e) { - e.printStackTrace(); + if (PlatinumSludgeOverHaul.checkRecipe(input, Materials.Samarium)) { + return; } + mutableRecipe + .gt5u$setRecipeOutputItem(WerkstoffMaterialPool.SamariumOreConcentrate.get(OrePrefixes.dust, 2)); } } diff --git a/src/main/java/com/github/bartimaeusnek/bartworks/common/loaders/StaticRecipeChangeLoaders.java b/src/main/java/com/github/bartimaeusnek/bartworks/common/loaders/StaticRecipeChangeLoaders.java index 91c077ccad..4271b43303 100644 --- a/src/main/java/com/github/bartimaeusnek/bartworks/common/loaders/StaticRecipeChangeLoaders.java +++ b/src/main/java/com/github/bartimaeusnek/bartworks/common/loaders/StaticRecipeChangeLoaders.java @@ -123,6 +123,7 @@ public class StaticRecipeChangeLoaders { } public static void unificationRecipeEnforcer() { + List<GT_Recipe> toRemove = new ArrayList<>(); for (Werkstoff werkstoff : Werkstoff.werkstoffHashSet) { StaticRecipeChangeLoaders.runMaterialLinker(werkstoff); if (werkstoff.getGenerationFeatures().enforceUnification) { @@ -142,7 +143,7 @@ public class StaticRecipeChangeLoaders { || replacement == null || replacement.getItem() == null) continue; for (RecipeMap<?> map : RecipeMap.ALL_RECIPE_MAPS.values()) { - List<GT_Recipe> toRemove = new ArrayList<>(); + toRemove.clear(); nextRecipe: for (GT_Recipe recipe : map.getAllRecipes()) { boolean removal = map.equals(RecipeMaps.fluidExtractionRecipes) || map.equals(RecipeMaps.fluidSolidifierRecipes); diff --git a/src/main/java/com/github/bartimaeusnek/bartworks/system/material/GT_Enhancement/PlatinumSludgeOverHaul.java b/src/main/java/com/github/bartimaeusnek/bartworks/system/material/GT_Enhancement/PlatinumSludgeOverHaul.java index 555d01684f..32aac70352 100644 --- a/src/main/java/com/github/bartimaeusnek/bartworks/system/material/GT_Enhancement/PlatinumSludgeOverHaul.java +++ b/src/main/java/com/github/bartimaeusnek/bartworks/system/material/GT_Enhancement/PlatinumSludgeOverHaul.java @@ -80,7 +80,6 @@ import static gregtech.api.util.GT_RecipeBuilder.TICKS; import static gregtech.api.util.GT_RecipeConstants.COIL_HEAT; import static gregtech.api.util.GT_RecipeConstants.UniversalChemical; -import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -93,18 +92,11 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.FurnaceRecipes; import net.minecraft.item.crafting.IRecipe; -import net.minecraft.item.crafting.ShapedRecipes; -import net.minecraft.item.crafting.ShapelessRecipes; -import net.minecraftforge.oredict.ShapedOreRecipe; -import net.minecraftforge.oredict.ShapelessOreRecipe; - -import org.apache.commons.lang3.reflect.FieldUtils; import com.github.bartimaeusnek.bartworks.MainMod; import com.github.bartimaeusnek.bartworks.system.material.BW_MetaGenerated_Items; import com.github.bartimaeusnek.bartworks.system.material.Werkstoff; import com.github.bartimaeusnek.bartworks.util.BW_Util; -import com.github.bartimaeusnek.bartworks.util.CachedReflectionUtils; import com.github.bartimaeusnek.crossmod.BartWorksCrossmod; import cpw.mods.fml.common.registry.GameRegistry; @@ -113,6 +105,7 @@ import gregtech.api.enums.ItemList; import gregtech.api.enums.Materials; import gregtech.api.enums.OrePrefixes; import gregtech.api.enums.TierEU; +import gregtech.api.interfaces.IRecipeMutableAccess; import gregtech.api.interfaces.ISubTagContainer; import gregtech.api.items.GT_Generic_Block; import gregtech.api.items.GT_Generic_Item; @@ -779,12 +772,7 @@ public class PlatinumSludgeOverHaul { .getRecipeList() .forEach(PlatinumSludgeOverHaul::setnewMaterialInRecipe); // gt crafting - try { - ((List<IRecipe>) FieldUtils.getDeclaredField(GT_ModHandler.class, "sBufferRecipeList", true) - .get(null)).forEach(PlatinumSludgeOverHaul::setnewMaterialInRecipe); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } + GT_ModHandler.sBufferRecipeList.forEach(PlatinumSludgeOverHaul::setnewMaterialInRecipe); // gt machines maploop: for (RecipeMap<?> map : RecipeMap.ALL_RECIPE_MAPS.values()) { if (map == fusionRecipes || map == unpackagerRecipes @@ -984,76 +972,36 @@ public class PlatinumSludgeOverHaul { } } - private static void setnewMaterialInRecipe(Object obj) { - String inputName = "output"; - String inputItemName = "input"; - if (!(obj instanceof ShapedOreRecipe) && !(obj instanceof ShapelessOreRecipe)) { - if (obj instanceof ShapedRecipes || obj instanceof ShapelessRecipes) { - inputName = "recipeOutput"; - inputItemName = "recipeItems"; - } else { - try { - if (Class.forName("gtPlusPlus.api.objects.minecraft.ShapedRecipe") - .isAssignableFrom(obj.getClass())) - obj = CachedReflectionUtils.getField(obj.getClass(), "mRecipe") - .get(obj); - } catch (ClassNotFoundException | IllegalAccessException e) { - e.printStackTrace(); - } - } - } - - IRecipe recipe = (IRecipe) obj; + private static void setnewMaterialInRecipe(IRecipe recipe) { ItemStack otpt = recipe.getRecipeOutput(); - Field out = CachedReflectionUtils.getDeclaredField(recipe.getClass(), inputName); - if (out == null) out = CachedReflectionUtils.getField(recipe.getClass(), inputName); + if (!(recipe instanceof IRecipeMutableAccess mutableRecipe)) { + return; + } - Field in = CachedReflectionUtils.getDeclaredField(recipe.getClass(), inputItemName); - if (in == null) in = CachedReflectionUtils.getField(recipe.getClass(), inputItemName); - if (in == null) return; + Object input = mutableRecipe.gt5u$getRecipeInputs(); - Object input; - try { - input = in.get(obj); - } catch (IllegalAccessException e) { - e.printStackTrace(); + if (input == null) { return; } - if (out != null && GT_Utility.areStacksEqual(otpt, Materials.Platinum.getDust(1), true)) { + if (GT_Utility.areStacksEqual(otpt, Materials.Platinum.getDust(1), true)) { if (PlatinumSludgeOverHaul.checkRecipe(input, Materials.Platinum)) return; - try { - out.set(recipe, PTMetallicPowder.get(dust, otpt.stackSize * 2)); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } else if (out != null && GT_Utility.areStacksEqual(otpt, Materials.Palladium.getDust(1), true)) { + mutableRecipe.gt5u$setRecipeOutputItem(PTMetallicPowder.get(dust, otpt.stackSize * 2)); + } else if (GT_Utility.areStacksEqual(otpt, Materials.Palladium.getDust(1), true)) { if (PlatinumSludgeOverHaul.checkRecipe(input, Materials.Palladium)) return; - try { - out.set(recipe, PDMetallicPowder.get(dust, otpt.stackSize * 2)); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } else if (out != null && GT_Utility.areStacksEqual(otpt, Materials.Iridium.getDust(1), true)) { + mutableRecipe.gt5u$setRecipeOutputItem(PDMetallicPowder.get(dust, otpt.stackSize * 2)); + } else if (GT_Utility.areStacksEqual(otpt, Materials.Iridium.getDust(1), true)) { if (PlatinumSludgeOverHaul.checkRecipe(input, Materials.Iridium)) return; - try { - out.set(recipe, IrLeachResidue.get(dust, otpt.stackSize)); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } else if (out != null && GT_Utility.areStacksEqual(otpt, Materials.Osmium.getDust(1), true)) { + mutableRecipe.gt5u$setRecipeOutputItem(IrLeachResidue.get(dust, otpt.stackSize)); + } else if (GT_Utility.areStacksEqual(otpt, Materials.Osmium.getDust(1), true)) { if (PlatinumSludgeOverHaul.checkRecipe(input, Materials.Osmium)) return; - try { - out.set(recipe, IrOsLeachResidue.get(dust, otpt.stackSize)); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } + mutableRecipe.gt5u$setRecipeOutputItem(IrOsLeachResidue.get(dust, otpt.stackSize)); } } @SuppressWarnings({ "rawtypes", "unchecked" }) - private static boolean checkRecipe(Object input, Materials mat) { + public static boolean checkRecipe(Object input, Materials mat) { if (input instanceof List || input instanceof Object[]) { Set lists = new HashSet(), stacks = new HashSet(); List ip = input instanceof List ? (List) input : new ArrayList(); diff --git a/src/main/java/goodgenerator/loader/NaquadahReworkRecipeLoader.java b/src/main/java/goodgenerator/loader/NaquadahReworkRecipeLoader.java index 2354ec61c2..46521fcaa1 100644 --- a/src/main/java/goodgenerator/loader/NaquadahReworkRecipeLoader.java +++ b/src/main/java/goodgenerator/loader/NaquadahReworkRecipeLoader.java @@ -55,25 +55,14 @@ import static gregtech.api.util.GT_RecipeConstants.UniversalChemical; import static gregtech.common.items.GT_MetaGenerated_Item_01.registerCauldronCleaningFor; import static gtPlusPlus.api.recipe.GTPPRecipeMaps.quantumForceTransformerRecipes; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import java.util.HashSet; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.IRecipe; -import net.minecraft.item.crafting.ShapedRecipes; -import net.minecraft.item.crafting.ShapelessRecipes; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.oredict.OreDictionary; -import net.minecraftforge.oredict.ShapedOreRecipe; -import net.minecraftforge.oredict.ShapelessOreRecipe; - -import org.apache.commons.lang3.reflect.FieldUtils; import com.github.bartimaeusnek.bartworks.system.material.GT_Enhancement.PlatinumSludgeOverHaul; import com.github.bartimaeusnek.bartworks.system.material.WerkstoffLoader; @@ -86,6 +75,7 @@ import gregtech.api.enums.ItemList; import gregtech.api.enums.Materials; import gregtech.api.enums.OrePrefixes; import gregtech.api.enums.TierEU; +import gregtech.api.interfaces.IRecipeMutableAccess; import gregtech.api.recipe.RecipeMaps; import gregtech.api.util.GT_Log; import gregtech.api.util.GT_OreDictUnificator; @@ -1260,146 +1250,30 @@ public class NaquadahReworkRecipeLoader { GT_Log.out.print("Crafting Table done!\n"); } - // I don't understand. . . - // I use and copy some private methods in Bartworks because his system runs well. - // Bartworks is under MIT License - /* - * Copyright (c) 2018-2020 bartimaeusnek 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. - */ public static void replaceInCraftTable(Object obj) { - - Constructor<?> cs = null; - PlatinumSludgeOverHaul BartObj = null; - try { - cs = PlatinumSludgeOverHaul.class.getDeclaredConstructor(); - cs.setAccessible(true); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } - - if (cs == null) return; - - try { - BartObj = (PlatinumSludgeOverHaul) cs.newInstance(); - } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { - e.printStackTrace(); - } - - Method recipeCheck = null; - - try { - recipeCheck = PlatinumSludgeOverHaul.class.getDeclaredMethod("checkRecipe", Object.class, Materials.class); - recipeCheck.setAccessible(true); - } catch (Exception e) { - e.printStackTrace(); - } - - String inputName = "output"; - String inputItemName = "input"; - if (!(obj instanceof ShapedOreRecipe || obj instanceof ShapelessOreRecipe)) { - if (obj instanceof ShapedRecipes || (obj instanceof ShapelessRecipes)) { - inputName = "recipeOutput"; - inputItemName = "recipeItems"; - } - } IRecipe recipe = (IRecipe) obj; ItemStack result = recipe.getRecipeOutput(); - - Field out = FieldUtils.getDeclaredField(recipe.getClass(), inputName, true); - if (out == null) out = FieldUtils.getField(recipe.getClass(), inputName, true); - - Field in = FieldUtils.getDeclaredField(recipe.getClass(), inputItemName, true); - if (in == null) in = FieldUtils.getField(recipe.getClass(), inputItemName, true); - if (in == null) return; - - // this part here is NOT MIT LICENSED BUT LICSENSED UNDER THE Apache License, Version 2.0! - try { - if (Modifier.isFinal(in.getModifiers())) { - // Do all JREs implement Field with a private ivar called "modifiers"? - Field modifiersField = Field.class.getDeclaredField("modifiers"); - boolean doForceAccess = !modifiersField.isAccessible(); - if (doForceAccess) { - modifiersField.setAccessible(true); - } - try { - modifiersField.setInt(in, in.getModifiers() & ~Modifier.FINAL); - } finally { - if (doForceAccess) { - modifiersField.setAccessible(false); - } - } - } - } catch (NoSuchFieldException ignored) { - // The field class contains always a modifiers field - } catch (IllegalAccessException ignored) { - // The modifiers field is made accessible - } - // END OF APACHE COMMONS COLLECTION COPY - - Object input; - try { - input = in.get(obj); - } catch (IllegalAccessException e) { - e.printStackTrace(); + if (!(recipe instanceof IRecipeMutableAccess mutableRecipe)) { return; } - if (out == null || recipeCheck == null) return; + Object input = mutableRecipe.gt5u$getRecipeInputs(); if (GT_Utility.areStacksEqual(result, Materials.Naquadah.getDust(1), true)) { - - recipeCheck.setAccessible(true); - boolean isOk = true; - - try { - isOk = (boolean) recipeCheck.invoke(BartObj, input, Materials.Naquadah); - } catch (InvocationTargetException | IllegalAccessException ignored) {} - - if (isOk) return; - try { - out.set(recipe, naquadahEarth.get(OrePrefixes.dust, 2)); - } catch (IllegalAccessException e) { - e.printStackTrace(); + if (PlatinumSludgeOverHaul.checkRecipe(input, Materials.Naquadah)) { + return; } + mutableRecipe.gt5u$setRecipeOutputItem(naquadahEarth.get(OrePrefixes.dust, 2)); } else if (GT_Utility.areStacksEqual(result, Materials.NaquadahEnriched.getDust(1), true)) { - - recipeCheck.setAccessible(true); - boolean isOk = true; - - try { - isOk = (boolean) recipeCheck.invoke(BartObj, input, Materials.NaquadahEnriched); - } catch (InvocationTargetException | IllegalAccessException ignored) {} - - if (isOk) return; - try { - out.set(recipe, enrichedNaquadahEarth.get(OrePrefixes.dust, 2)); - } catch (IllegalAccessException e) { - e.printStackTrace(); + if (PlatinumSludgeOverHaul.checkRecipe(input, Materials.NaquadahEnriched)) { + return; } + mutableRecipe.gt5u$setRecipeOutputItem(enrichedNaquadahEarth.get(OrePrefixes.dust, 2)); } else if (GT_Utility.areStacksEqual(result, Materials.Naquadria.getDust(1), true)) { - - recipeCheck.setAccessible(true); - boolean isOk = true; - - try { - isOk = (boolean) recipeCheck.invoke(BartObj, input, Materials.Naquadria); - } catch (InvocationTargetException | IllegalAccessException ignored) {} - - if (isOk) return; - try { - out.set(recipe, naquadriaEarth.get(OrePrefixes.dust, 2)); - } catch (IllegalAccessException e) { - e.printStackTrace(); + if (PlatinumSludgeOverHaul.checkRecipe(input, Materials.Naquadria)) { + return; } + mutableRecipe.gt5u$setRecipeOutputItem(naquadriaEarth.get(OrePrefixes.dust, 2)); } } } diff --git a/src/main/java/gregtech/api/interfaces/IRecipeMutableAccess.java b/src/main/java/gregtech/api/interfaces/IRecipeMutableAccess.java new file mode 100644 index 0000000000..5c6d931d5a --- /dev/null +++ b/src/main/java/gregtech/api/interfaces/IRecipeMutableAccess.java @@ -0,0 +1,18 @@ +package gregtech.api.interfaces; + +import net.minecraft.item.ItemStack; + +/** + * Mixed-in interface for recipe classes in Forge and Vanilla that allows mutating the input and output items. + */ +public interface IRecipeMutableAccess { + + /** @return Gets the current output item of the recipe */ + ItemStack gt5u$getRecipeOutputItem(); + + /** Sets a new output item on the recipe */ + void gt5u$setRecipeOutputItem(ItemStack newItem); + + /** @return The raw list or array of recipe inputs, the exact type depends on the underlying recipe type. */ + Object gt5u$getRecipeInputs(); +} diff --git a/src/main/java/gregtech/api/util/GT_ModHandler.java b/src/main/java/gregtech/api/util/GT_ModHandler.java index 8c43a5334b..45df4ffeea 100644 --- a/src/main/java/gregtech/api/util/GT_ModHandler.java +++ b/src/main/java/gregtech/api/util/GT_ModHandler.java @@ -93,8 +93,8 @@ public class GT_ModHandler { public static final List<IRecipe> sSingleNonBlockDamagableRecipeList = new ArrayList<>(1000); private static final Map<String, ItemStack> sIC2ItemMap = new HashMap<>(); - private static final List<IRecipe> sAllRecipeList = new ArrayList<>(5000), - sBufferRecipeList = new ArrayList<>(1000); + // public for bartworks + public static final List<IRecipe> sAllRecipeList = new ArrayList<>(5000), sBufferRecipeList = new ArrayList<>(1000); private static final List<ItemStack> delayedRemovalByOutput = new ArrayList<>(); private static final List<InventoryCrafting> delayedRemovalByRecipe = new ArrayList<>(); diff --git a/src/main/java/gregtech/mixin/Mixin.java b/src/main/java/gregtech/mixin/Mixin.java index 8ead56bf44..340868e015 100644 --- a/src/main/java/gregtech/mixin/Mixin.java +++ b/src/main/java/gregtech/mixin/Mixin.java @@ -41,6 +41,16 @@ public enum Mixin { .setApplyIf(() -> ConfigHandler.enabledPatches[3]) .setPhase(Phase.EARLY) .setSide(Side.BOTH)), + CraftingRecipeAccessorMixin(new Builder("Add accessors to crafting recipe types") + .addMixinClasses( + "minecraft.VanillaShapedRecipeMixin", + "minecraft.VanillaShapelessRecipeMixin", + "minecraft.ForgeShapedRecipeMixin", + "minecraft.ForgeShapelessRecipeMixin") + .addTargetedMod(VANILLA) + .setApplyIf(() -> true) + .setPhase(Phase.EARLY) + .setSide(Side.BOTH)), BlockStemMixin(new Builder("Stem Crop Block Accessor").addMixinClasses("minecraft.BlockStemMixin") .addTargetedMod(VANILLA) .setApplyIf(() -> true) diff --git a/src/main/java/gtPlusPlus/api/objects/minecraft/ShapedRecipe.java b/src/main/java/gtPlusPlus/api/objects/minecraft/ShapedRecipe.java index f799623dd6..4da6ef3a1f 100644 --- a/src/main/java/gtPlusPlus/api/objects/minecraft/ShapedRecipe.java +++ b/src/main/java/gtPlusPlus/api/objects/minecraft/ShapedRecipe.java @@ -4,12 +4,13 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraftforge.oredict.ShapedOreRecipe; +import gregtech.api.interfaces.IRecipeMutableAccess; import gtPlusPlus.api.objects.Logger; import gtPlusPlus.api.objects.data.AutoMap; import gtPlusPlus.api.objects.data.Pair; import gtPlusPlus.core.util.minecraft.ItemUtils; -public class ShapedRecipe { +public class ShapedRecipe implements IRecipeMutableAccess { private static final String CHARS = "abcdefghijklmnop"; public ShapedOreRecipe mRecipe; @@ -248,4 +249,19 @@ public class ShapedRecipe { t.printStackTrace(); } } + + @Override + public ItemStack gt5u$getRecipeOutputItem() { + return ((IRecipeMutableAccess) mRecipe).gt5u$getRecipeOutputItem(); + } + + @Override + public void gt5u$setRecipeOutputItem(ItemStack newItem) { + ((IRecipeMutableAccess) mRecipe).gt5u$setRecipeOutputItem(newItem); + } + + @Override + public Object gt5u$getRecipeInputs() { + return ((IRecipeMutableAccess) mRecipe).gt5u$getRecipeInputs(); + } } diff --git a/src/main/java/gtPlusPlus/core/common/CommonProxy.java b/src/main/java/gtPlusPlus/core/common/CommonProxy.java index 5d93141c56..12f0971e73 100644 --- a/src/main/java/gtPlusPlus/core/common/CommonProxy.java +++ b/src/main/java/gtPlusPlus/core/common/CommonProxy.java @@ -6,14 +6,19 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.world.World; import net.minecraftforge.client.IItemRenderer; +import net.minecraftforge.event.entity.living.LivingAttackEvent; +import baubles.common.container.InventoryBaubles; +import baubles.common.lib.PlayerHandler; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLLoadCompleteEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.event.FMLServerStartingEvent; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.network.simpleimpl.MessageContext; import cpw.mods.fml.common.registry.GameRegistry; +import gregtech.api.enums.Mods; import gtPlusPlus.api.objects.Logger; import gtPlusPlus.api.objects.data.AutoMap; import gtPlusPlus.api.objects.data.Pair; @@ -30,6 +35,7 @@ import gtPlusPlus.core.handler.events.EntityDeathHandler; import gtPlusPlus.core.handler.events.GeneralTooltipEventHandler; import gtPlusPlus.core.handler.events.PlayerSleepEventHandler; import gtPlusPlus.core.item.ModItems; +import gtPlusPlus.core.item.bauble.BaseBauble; import gtPlusPlus.core.lib.CORE; import gtPlusPlus.core.recipe.common.CI; import gtPlusPlus.core.tileentities.ModTileEntities; @@ -204,4 +210,34 @@ public class CommonProxy { public EntityPlayer getPlayerEntity(MessageContext ctx) { return ctx.getServerHandler().playerEntity; } + + @SuppressWarnings("unused") // used by the event bus + @SubscribeEvent + public void onPlayerAttacked(LivingAttackEvent event) { + if (Mods.Baubles.isModLoaded()) { + BaubleAttackHandler.run(event); + } + } + + // Prevent class loading errors if Baubles are missing + private static final class BaubleAttackHandler { + + public static void run(LivingAttackEvent event) { + if (!(event.entityLiving instanceof EntityPlayer player)) { + return; + } + InventoryBaubles baubles = PlayerHandler.getPlayerBaubles(player); + final ItemStack bauble1 = baubles.getStackInSlot(1); + if (bauble1.getItem() instanceof BaseBauble gtBauble && gtBauble.getDamageNegations() + .contains(event.source.damageType)) { + event.setCanceled(true); + return; + } + final ItemStack bauble2 = baubles.getStackInSlot(2); + if (bauble2.getItem() instanceof BaseBauble gtBauble && gtBauble.getDamageNegations() + .contains(event.source.damageType)) { + event.setCanceled(true); + } + } + } } diff --git a/src/main/java/gtPlusPlus/core/item/bauble/BaseBauble.java b/src/main/java/gtPlusPlus/core/item/bauble/BaseBauble.java index 92468aa6d8..76121ef266 100644 --- a/src/main/java/gtPlusPlus/core/item/bauble/BaseBauble.java +++ b/src/main/java/gtPlusPlus/core/item/bauble/BaseBauble.java @@ -9,21 +9,16 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.world.World; -import net.minecraftforge.event.entity.living.LivingAttackEvent; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import baubles.api.BaubleType; import baubles.api.IBauble; -import baubles.common.container.InventoryBaubles; -import baubles.common.lib.PlayerHandler; import cpw.mods.fml.common.Optional; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; import gregtech.api.enums.Mods; import gregtech.api.util.GT_LanguageManager; import gtPlusPlus.core.creative.AddToCreativeTab; -import gtPlusPlus.core.util.Utils; import gtPlusPlus.core.util.minecraft.NBTUtils; @Optional.InterfaceList( @@ -41,11 +36,14 @@ public class BaseBauble extends Item implements IBauble { public BaseBauble(BaubleType type) { this.mThisBauble = type; - Utils.registerEvent(this); this.setMaxStackSize(1); this.setCreativeTab(AddToCreativeTab.tabMisc); } + public List<String> getDamageNegations() { + return damageNegations; + } + @Override public String getItemStackDisplayName(final ItemStack tItem) { String key = "gtplusplus." + getUnlocalizedName() + ".name"; @@ -55,14 +53,6 @@ public class BaseBauble extends Item implements IBauble { return GT_LanguageManager.getTranslation(key); } - @SubscribeEvent - public void onPlayerAttacked(LivingAttackEvent event) { - if (event.entityLiving instanceof EntityPlayer player) { - if (getCorrectBauble(player) != null && damageNegations.contains(event.source.damageType)) - event.setCanceled(true); - } - } - @Override public boolean canEquip(ItemStack arg0, EntityLivingBase arg1) { return arg1 instanceof EntityPlayer; @@ -107,17 +97,6 @@ public class BaseBauble extends Item implements IBauble { .removeAttributeModifiers(attributes); } - public ItemStack getCorrectBauble(EntityPlayer player) { - InventoryBaubles baubles = PlayerHandler.getPlayerBaubles(player); - ItemStack stack1 = baubles.getStackInSlot(1); - ItemStack stack2 = baubles.getStackInSlot(2); - return isCorrectBauble(stack1) ? stack1 : isCorrectBauble(stack2) ? stack2 : null; - } - - private boolean isCorrectBauble(ItemStack stack) { - return stack != null && (stack.getItem() == this); - } - @Override public int getEntityLifespan(ItemStack itemStack, World world) { return Integer.MAX_VALUE; diff --git a/src/mixin/java/gregtech/mixin/mixins/early/minecraft/ForgeShapedRecipeMixin.java b/src/mixin/java/gregtech/mixin/mixins/early/minecraft/ForgeShapedRecipeMixin.java new file mode 100644 index 0000000000..041df1937f --- /dev/null +++ b/src/mixin/java/gregtech/mixin/mixins/early/minecraft/ForgeShapedRecipeMixin.java @@ -0,0 +1,34 @@ +package gregtech.mixin.mixins.early.minecraft; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.ShapedOreRecipe; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import gregtech.api.interfaces.IRecipeMutableAccess; + +@Mixin(value = ShapedOreRecipe.class, remap = false) +public class ForgeShapedRecipeMixin implements IRecipeMutableAccess { + + @Shadow + private ItemStack output; + + @Shadow + private Object[] input; + + @Override + public ItemStack gt5u$getRecipeOutputItem() { + return this.output; + } + + @Override + public void gt5u$setRecipeOutputItem(ItemStack newItem) { + this.output = newItem; + } + + @Override + public Object gt5u$getRecipeInputs() { + return this.input; + } +} diff --git a/src/mixin/java/gregtech/mixin/mixins/early/minecraft/ForgeShapelessRecipeMixin.java b/src/mixin/java/gregtech/mixin/mixins/early/minecraft/ForgeShapelessRecipeMixin.java new file mode 100644 index 0000000000..7bf4ba489e --- /dev/null +++ b/src/mixin/java/gregtech/mixin/mixins/early/minecraft/ForgeShapelessRecipeMixin.java @@ -0,0 +1,36 @@ +package gregtech.mixin.mixins.early.minecraft; + +import java.util.ArrayList; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.ShapelessOreRecipe; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import gregtech.api.interfaces.IRecipeMutableAccess; + +@Mixin(value = ShapelessOreRecipe.class, remap = false) +public class ForgeShapelessRecipeMixin implements IRecipeMutableAccess { + + @Shadow + private ItemStack output; + + @Shadow + private ArrayList<Object> input; + + @Override + public ItemStack gt5u$getRecipeOutputItem() { + return this.output; + } + + @Override + public void gt5u$setRecipeOutputItem(ItemStack newItem) { + this.output = newItem; + } + + @Override + public Object gt5u$getRecipeInputs() { + return this.input; + } +} diff --git a/src/mixin/java/gregtech/mixin/mixins/early/minecraft/VanillaShapedRecipeMixin.java b/src/mixin/java/gregtech/mixin/mixins/early/minecraft/VanillaShapedRecipeMixin.java new file mode 100644 index 0000000000..0eecaef6ea --- /dev/null +++ b/src/mixin/java/gregtech/mixin/mixins/early/minecraft/VanillaShapedRecipeMixin.java @@ -0,0 +1,36 @@ +package gregtech.mixin.mixins.early.minecraft; + +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.ShapedRecipes; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import gregtech.api.interfaces.IRecipeMutableAccess; + +@Mixin(ShapedRecipes.class) +public class VanillaShapedRecipeMixin implements IRecipeMutableAccess { + + @Shadow + private ItemStack recipeOutput; + + @Shadow + @Final + public ItemStack[] recipeItems; + + @Override + public ItemStack gt5u$getRecipeOutputItem() { + return this.recipeOutput; + } + + @Override + public void gt5u$setRecipeOutputItem(ItemStack newItem) { + this.recipeOutput = newItem; + } + + @Override + public Object gt5u$getRecipeInputs() { + return this.recipeItems; + } +} diff --git a/src/mixin/java/gregtech/mixin/mixins/early/minecraft/VanillaShapelessRecipeMixin.java b/src/mixin/java/gregtech/mixin/mixins/early/minecraft/VanillaShapelessRecipeMixin.java new file mode 100644 index 0000000000..926ae6630c --- /dev/null +++ b/src/mixin/java/gregtech/mixin/mixins/early/minecraft/VanillaShapelessRecipeMixin.java @@ -0,0 +1,38 @@ +package gregtech.mixin.mixins.early.minecraft; + +import java.util.List; + +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.ShapelessRecipes; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import gregtech.api.interfaces.IRecipeMutableAccess; + +@Mixin(ShapelessRecipes.class) +public class VanillaShapelessRecipeMixin implements IRecipeMutableAccess { + + @Shadow + private ItemStack recipeOutput; + + @Shadow + @Final + public List<ItemStack> recipeItems; + + @Override + public ItemStack gt5u$getRecipeOutputItem() { + return this.recipeOutput; + } + + @Override + public void gt5u$setRecipeOutputItem(ItemStack newItem) { + this.recipeOutput = newItem; + } + + @Override + public Object gt5u$getRecipeInputs() { + return this.recipeItems; + } +} |