From a26d89c876d1cbfee31825354b40f67c6e6f6b0f Mon Sep 17 00:00:00 2001 From: LexManos Date: Mon, 19 Jun 2017 15:02:18 -0700 Subject: [PATCH] First pass of registry rewrite. Tests do not run yet. Things of note: Removed the idea of substitutions, just register multiple items with the same name they will override each other like a normal map. Decoupled Forge registries from vanilla classes. They now use bouncer classes. MODDERS SHOULD NEVER USE THESE Introduced more stringent registry locking. As it sits things are only allowed to be registered during the RegistryEvent.Registry phases! This is to force modders to split up their registrations, and pave the way for calling these functions multiple times during a single MC lifecycle. ObjectHolder, Missing Mappings, etc... *should* now work for all registry types, nothing should be special cased to Blocks/Items anymore. Added optional generic dummy factory to registries, to allow registry creators the ability to dummy more then just Blocks. Re-worked the ItemStack transformer and applied it to ItemBlock and ItemBlockSpecial. Allowing us to cleanup reflective hacks in Block callbacks. Registry onAdd callback is now only fired on the ACTIVE registry, fixing any issues of temp registries overriding active objects. --- .../net/minecraft/block/Block.java.patch | 6 +- .../block/model/ModelBakery.java.patch | 4 +- .../renderer/color/BlockColors.java.patch | 2 +- .../renderer/color/ItemColors.java.patch | 2 +- .../enchantment/Enchantment.java.patch | 4 +- .../minecraft/entity/EntityList.java.patch | 12 +- .../monster/EntityZombieVillager.java.patch | 2 +- .../entity/passive/EntityVillager.java.patch | 4 +- .../net/minecraft/init/Bootstrap.java.patch | 2 +- .../net/minecraft/item/Item.java.patch | 6 +- .../net/minecraft/item/ItemBlock.java.patch | 9 +- .../item/ItemBlockSpecial.java.patch | 7 +- .../net/minecraft/item/ItemStack.java.patch | 2 +- .../item/crafting/CraftingManager.java.patch | 2 +- .../item/crafting/IRecipe.java.patch | 2 +- .../crafting/RecipeBookCloning.java.patch | 2 +- .../item/crafting/RecipeFireworks.java.patch | 2 +- .../item/crafting/RecipeRepairItem.java.patch | 2 +- .../crafting/RecipeTippedArrow.java.patch | 2 +- .../item/crafting/RecipesArmorDyes.java.patch | 2 +- .../item/crafting/RecipesBanners.java.patch | 4 +- .../crafting/RecipesMapCloning.java.patch | 2 +- .../item/crafting/ShapedRecipes.java.patch | 2 +- .../item/crafting/ShapelessRecipes.java.patch | 2 +- .../item/crafting/ShieldRecipes.java.patch | 2 +- .../crafting/ShulkerBoxRecipes.java.patch | 2 +- .../net/minecraft/potion/Potion.java.patch | 4 +- .../minecraft/potion/PotionType.java.patch | 4 +- .../net/minecraft/stats/StatList.java.patch | 32 +- .../tileentity/TileEntity.java.patch | 8 +- .../net/minecraft/util/SoundEvent.java.patch | 4 +- .../minecraft/world/biome/Biome.java.patch | 4 +- .../client/model/ModelLoader.java | 24 +- .../common/ForgeModContainer.java | 18 +- .../common/crafting/CraftingHelper.java | 17 +- .../minecraftforge/event/RegistryEvent.java | 165 ++- .../minecraftforge/fluids/FluidRegistry.java | 6 +- .../net/minecraftforge/fluids/FluidStack.java | 4 +- .../fml/client/FMLClientHandler.java | 4 +- .../fml/common/FMLContainer.java | 139 +-- .../net/minecraftforge/fml/common/Loader.java | 87 +- .../FieldRedirectTransformer.java | 119 +++ .../ItemBlockSpecialTransformer.java} | 14 +- .../transformers/ItemBlockTransformer.java | 28 + .../transformers/ItemStackTransformer.java | 88 +- .../common/event/FMLMissingMappingsEvent.java | 218 ---- .../fml/common/eventhandler/EventBus.java | 1 + .../common/eventhandler/IContextSetter.java | 7 +- .../fml/common/launcher/FMLDeobfTweaker.java | 2 + .../fml/common/network/ByteBufUtils.java | 50 +- .../handshake/FMLHandshakeClientState.java | 25 +- .../handshake/FMLHandshakeMessage.java | 30 +- .../handshake/FMLHandshakeServerState.java | 9 +- .../network/handshake/NetworkDispatcher.java | 17 +- .../fml/common/registry/EntityEntry.java | 2 +- .../FMLControlledNamespacedRegistry.java | 950 ------------------ .../fml/common/registry/FinalFieldHelper.java | 59 -- .../fml/common/registry/ForgeRegistries.java | 4 +- .../fml/common/registry/GameData.java | 465 --------- .../fml/common/registry/GameRegistry.java | 145 +-- .../registry/LegacyNamespacedRegistry.java | 55 - .../registry/PersistentRegistryManager.java | 857 ---------------- .../fml/common/registry/VillagerRegistry.java | 37 +- .../minecraftforge/oredict/OreDictionary.java | 9 +- .../oredict/ShapedOreRecipe.java | 2 +- .../oredict/ShapelessOreRecipe.java | 2 +- .../registries/ForgeRegistry.java | 657 ++++++++++++ .../minecraftforge/registries/GameData.java | 670 ++++++++++++ .../IForgeRegistry.java | 20 +- .../IForgeRegistryEntry.java | 4 +- .../registries/IForgeRegistryInternal.java | 8 + .../registries/IForgeRegistryModifiable.java | 10 + .../registries/ILockableRegistry.java | 8 + .../IRegistryDelegate.java} | 58 +- .../NamespacedDefaultedWrapper.java | 126 +++ .../registries/NamespacedWrapper.java | 122 +++ .../ObjectHolderRef.java | 75 +- .../ObjectHolderRegistry.java | 14 +- .../RegistryBuilder.java | 118 +-- .../registries/RegistryDelegate.java | 48 + .../registries/RegistryManager.java | 127 +++ src/main/resources/forge_at.cfg | 4 - .../debug/CanApplyAtEnchantingTableTest.java | 17 +- .../debug/ClientCommandTest.java | 5 +- .../debug/CustomSpriteTest.java | 15 +- .../minecraftforge/debug/DynBucketTest.java | 119 ++- .../debug/FluidPlacementTest.java | 49 +- .../ItemCanDestroyBlocksInCreativeTest.java | 38 +- .../debug/ItemLayerModelDebug.java | 44 +- .../minecraftforge/debug/ItemTileDebug.java | 46 +- .../debug/ModelAnimationDebug.java | 54 +- .../debug/ModelBakeEventDebug.java | 63 +- .../minecraftforge/debug/ModelFluidDebug.java | 139 ++- .../debug/ModelLoaderRegistryDebug.java | 138 +-- .../debug/MultiLayerModelDebug.java | 95 +- .../debug/NBTShareTagItemTest.java | 52 +- .../debug/NoBedSleepingTest.java | 38 +- .../debug/NoPotionEffectRenderTest.java | 6 +- .../debug/ObjectHolderTest.java | 101 +- .../debug/PotionCurativeItemDebug.java | 53 +- .../debug/PotionRegistryDebug.java | 11 +- .../debug/TileEntityLoadingTest.java | 38 +- .../debug/WrenchRotateDebug.java | 52 +- .../registry/BlockStateMappingsTest.java | 2 + .../registry/DummyBlockReplacementTest.java | 33 +- .../fml/common/registry/FreezingTests.java | 102 +- ...temBlockSubstitutionRemoveRestoreTest.java | 24 +- .../registry/SubstitutionInjectionTest.java | 103 +- .../SubstitutionRemoveRestoreTest.java | 51 +- .../common/registry/VanillaRegistryTests.java | 23 +- 110 files changed, 3275 insertions(+), 4110 deletions(-) create mode 100644 src/main/java/net/minecraftforge/fml/common/asm/transformers/FieldRedirectTransformer.java rename src/main/java/net/minecraftforge/fml/common/{registry/IncompatibleSubstitutionException.java => asm/transformers/ItemBlockSpecialTransformer.java} (60%) create mode 100644 src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockTransformer.java delete mode 100644 src/main/java/net/minecraftforge/fml/common/event/FMLMissingMappingsEvent.java delete mode 100644 src/main/java/net/minecraftforge/fml/common/registry/FMLControlledNamespacedRegistry.java delete mode 100644 src/main/java/net/minecraftforge/fml/common/registry/FinalFieldHelper.java delete mode 100644 src/main/java/net/minecraftforge/fml/common/registry/GameData.java delete mode 100644 src/main/java/net/minecraftforge/fml/common/registry/LegacyNamespacedRegistry.java delete mode 100644 src/main/java/net/minecraftforge/fml/common/registry/PersistentRegistryManager.java create mode 100644 src/main/java/net/minecraftforge/registries/ForgeRegistry.java create mode 100644 src/main/java/net/minecraftforge/registries/GameData.java rename src/main/java/net/minecraftforge/{fml/common/registry => registries}/IForgeRegistry.java (80%) rename src/main/java/net/minecraftforge/{fml/common/registry => registries}/IForgeRegistryEntry.java (96%) create mode 100644 src/main/java/net/minecraftforge/registries/IForgeRegistryInternal.java create mode 100644 src/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java create mode 100644 src/main/java/net/minecraftforge/registries/ILockableRegistry.java rename src/main/java/net/minecraftforge/{fml/common/registry/RegistryDelegate.java => registries/IRegistryDelegate.java} (57%) create mode 100644 src/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java create mode 100644 src/main/java/net/minecraftforge/registries/NamespacedWrapper.java rename src/main/java/net/minecraftforge/{fml/common/registry => registries}/ObjectHolderRef.java (64%) rename src/main/java/net/minecraftforge/{fml/common/registry => registries}/ObjectHolderRegistry.java (94%) rename src/main/java/net/minecraftforge/{fml/common/registry => registries}/RegistryBuilder.java (52%) create mode 100644 src/main/java/net/minecraftforge/registries/RegistryDelegate.java create mode 100644 src/main/java/net/minecraftforge/registries/RegistryManager.java diff --git a/patches/minecraft/net/minecraft/block/Block.java.patch b/patches/minecraft/net/minecraft/block/Block.java.patch index 180abb1c55..bb6fe01744 100644 --- a/patches/minecraft/net/minecraft/block/Block.java.patch +++ b/patches/minecraft/net/minecraft/block/Block.java.patch @@ -5,14 +5,14 @@ import net.minecraftforge.fml.relauncher.SideOnly; -public class Block -+public class Block extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl ++public class Block extends net.minecraftforge.registries.IForgeRegistryEntry.Impl { private static final ResourceLocation field_176230_a = new ResourceLocation("air"); - public static final RegistryNamespacedDefaultedByKey field_149771_c = new RegistryNamespacedDefaultedByKey(field_176230_a); - public static final ObjectIntIdentityMap field_176229_d = new ObjectIntIdentityMap(); -+ public static final RegistryNamespacedDefaultedByKey field_149771_c = net.minecraftforge.fml.common.registry.GameData.getBlockRegistry(); ++ public static final RegistryNamespacedDefaultedByKey field_149771_c = net.minecraftforge.registries.GameData.getWrapperDefaulted(Block.class); + @Deprecated //Modders: DO NOT use this! Use GameRegistry -+ public static final ObjectIntIdentityMap field_176229_d = net.minecraftforge.fml.common.registry.GameData.getBlockStateIDMap(); ++ public static final ObjectIntIdentityMap field_176229_d = net.minecraftforge.registries.GameData.getBlockStateIDMap(); public static final AxisAlignedBB field_185505_j = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); @Nullable public static final AxisAlignedBB field_185506_k = null; diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/ModelBakery.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/ModelBakery.java.patch index 0b07c47e66..fc4ccfcd08 100644 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/ModelBakery.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/block/model/ModelBakery.java.patch @@ -75,7 +75,7 @@ this.field_177613_u.put(Items.field_179570_aq, Lists.newArrayList("oak_door")); this.field_177613_u.put(Items.field_151124_az, Lists.newArrayList("oak_boat")); this.field_177613_u.put(Items.field_190929_cY, Lists.newArrayList("totem")); -+ for (Entry, Set> e : customVariantNames.entrySet()) ++ for (Entry, Set> e : customVariantNames.entrySet()) + { + this.field_177613_u.put(e.getKey().get(), Lists.newArrayList(e.getValue().iterator())); + } @@ -155,7 +155,7 @@ + this.field_188642_k.put(definition, locations); + } + -+ private static Map, Set> customVariantNames = Maps.newHashMap(); ++ private static Map, Set> customVariantNames = Maps.newHashMap(); + + public static void registerItemVariants(Item item, ResourceLocation... names) + { diff --git a/patches/minecraft/net/minecraft/client/renderer/color/BlockColors.java.patch b/patches/minecraft/net/minecraft/client/renderer/color/BlockColors.java.patch index e506385f19..ebd19d26c7 100644 --- a/patches/minecraft/net/minecraft/client/renderer/color/BlockColors.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/color/BlockColors.java.patch @@ -6,7 +6,7 @@ { - private final ObjectIntIdentityMap field_186725_a = new ObjectIntIdentityMap(32); + // FORGE: Use RegistryDelegates as non-Vanilla block ids are not constant -+ private final java.util.Map, IBlockColor> blockColorMap = com.google.common.collect.Maps.newHashMap(); ++ private final java.util.Map, IBlockColor> blockColorMap = com.google.common.collect.Maps.newHashMap(); public static BlockColors func_186723_a() { diff --git a/patches/minecraft/net/minecraft/client/renderer/color/ItemColors.java.patch b/patches/minecraft/net/minecraft/client/renderer/color/ItemColors.java.patch index f09b43255f..37be2b90c3 100644 --- a/patches/minecraft/net/minecraft/client/renderer/color/ItemColors.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/color/ItemColors.java.patch @@ -6,7 +6,7 @@ { - private final ObjectIntIdentityMap field_186732_a = new ObjectIntIdentityMap(32); + // FORGE: Use RegistryDelegates as non-Vanilla item ids are not constant -+ private final java.util.Map, IItemColor> itemColorMap = com.google.common.collect.Maps.newHashMap(); ++ private final java.util.Map, IItemColor> itemColorMap = com.google.common.collect.Maps.newHashMap(); public static ItemColors func_186729_a(final BlockColors p_186729_0_) { diff --git a/patches/minecraft/net/minecraft/enchantment/Enchantment.java.patch b/patches/minecraft/net/minecraft/enchantment/Enchantment.java.patch index f500df0244..63b50dc7d3 100644 --- a/patches/minecraft/net/minecraft/enchantment/Enchantment.java.patch +++ b/patches/minecraft/net/minecraft/enchantment/Enchantment.java.patch @@ -5,10 +5,10 @@ import net.minecraft.util.text.translation.I18n; -public abstract class Enchantment -+public abstract class Enchantment extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl ++public abstract class Enchantment extends net.minecraftforge.registries.IForgeRegistryEntry.Impl { - public static final RegistryNamespaced field_185264_b = new RegistryNamespaced(); -+ public static final RegistryNamespaced field_185264_b = net.minecraftforge.fml.common.registry.GameData.getEnchantmentRegistry(); ++ public static final RegistryNamespaced field_185264_b = net.minecraftforge.registries.GameData.getWrapper(Enchantment.class); private final EntityEquipmentSlot[] field_185263_a; private final Enchantment.Rarity field_77333_a; @Nullable diff --git a/patches/minecraft/net/minecraft/entity/EntityList.java.patch b/patches/minecraft/net/minecraft/entity/EntityList.java.patch index 86a49450e9..26b7f0020d 100644 --- a/patches/minecraft/net/minecraft/entity/EntityList.java.patch +++ b/patches/minecraft/net/minecraft/entity/EntityList.java.patch @@ -44,7 +44,7 @@ public static Class func_90035_a(int p_90035_0_) { - return (Class)field_191308_b.func_148754_a(p_90035_0_); -+ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.GameData.getEntityRegistry().func_148754_a(p_90035_0_); ++ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.registries.GameData.getEntityRegistry().getValue(p_90035_0_); + return entry == null ? null : entry.getEntityClass(); } @@ -60,7 +60,7 @@ + public static int getID(Class cls) + { + net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.EntityRegistry.getEntry(cls); -+ return entry == null ? -1 : net.minecraftforge.fml.common.registry.GameData.getEntityRegistry().getId(entry); ++ return entry == null ? -1 : net.minecraftforge.registries.GameData.getEntityRegistry().getID(entry); + } + + public static Class getClass(ResourceLocation key) @@ -86,7 +86,7 @@ public static Entity func_75616_a(int p_75616_0_, World p_75616_1_) { - return func_191304_a(func_90035_a(p_75616_0_), p_75616_1_); -+ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.fml.common.registry.GameData.getEntityRegistry().func_148754_a(p_75616_0_); ++ net.minecraftforge.fml.common.registry.EntityEntry entry = net.minecraftforge.registries.GameData.getEntityRegistry().getValue(p_75616_0_); + return entry == null ? null : entry.newInstance(p_75616_1_); } @@ -134,7 +134,7 @@ } private static void func_191303_a(int p_191303_0_, String p_191303_1_, Class p_191303_2_, String p_191303_3_) -@@ -394,22 +420,19 @@ +@@ -394,22 +421,17 @@ else { ResourceLocation resourcelocation = new ResourceLocation(p_191303_1_); @@ -147,9 +147,7 @@ - } - - field_191311_g.set(p_191303_0_, p_191303_3_); -+ net.minecraftforge.fml.common.registry.EntityEntry entry = -+ new net.minecraftforge.fml.common.registry.EntityEntry(p_191303_2_, p_191303_3_); -+ net.minecraftforge.fml.common.registry.GameData.getEntityRegistry().func_177775_a(p_191303_0_, resourcelocation, entry); ++ net.minecraftforge.registries.GameData.registerEntity(p_191303_0_, resourcelocation, p_191303_2_, p_191303_3_); } } diff --git a/patches/minecraft/net/minecraft/entity/monster/EntityZombieVillager.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntityZombieVillager.java.patch index 3110ae5813..a54d827189 100644 --- a/patches/minecraft/net/minecraft/entity/monster/EntityZombieVillager.java.patch +++ b/patches/minecraft/net/minecraft/entity/monster/EntityZombieVillager.java.patch @@ -30,7 +30,7 @@ this.func_190733_a(p_70037_1_.func_74762_e("Profession")); + if (p_70037_1_.func_74764_b("ProfessionName")) + { -+ net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession p = net.minecraftforge.fml.common.registry.VillagerRegistry.instance().getRegistry().getValue(new net.minecraft.util.ResourceLocation(p_70037_1_.func_74779_i("ProfessionName"))); ++ net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession p = net.minecraftforge.fml.common.registry.ForgeRegistries.VILLAGER_PROFESSIONS.getValue(new net.minecraft.util.ResourceLocation(p_70037_1_.func_74779_i("ProfessionName"))); + if (p == null) p = net.minecraftforge.fml.common.registry.VillagerRegistry.FARMER; + this.setForgeProfession(p); + } diff --git a/patches/minecraft/net/minecraft/entity/passive/EntityVillager.java.patch b/patches/minecraft/net/minecraft/entity/passive/EntityVillager.java.patch index d41728b6aa..1e07c7b2f2 100644 --- a/patches/minecraft/net/minecraft/entity/passive/EntityVillager.java.patch +++ b/patches/minecraft/net/minecraft/entity/passive/EntityVillager.java.patch @@ -33,9 +33,9 @@ + if (p_70037_1_.func_74764_b("ProfessionName")) + { + net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession p = -+ net.minecraftforge.fml.common.registry.VillagerRegistry.instance().getRegistry().getValue(new net.minecraft.util.ResourceLocation(p_70037_1_.func_74779_i("ProfessionName"))); ++ net.minecraftforge.fml.common.registry.ForgeRegistries.VILLAGER_PROFESSIONS.getValue(new net.minecraft.util.ResourceLocation(p_70037_1_.func_74779_i("ProfessionName"))); + if (p == null) -+ p = net.minecraftforge.fml.common.registry.VillagerRegistry.instance().getRegistry().getValue(new net.minecraft.util.ResourceLocation("minecraft:farmer")); ++ p = net.minecraftforge.fml.common.registry.ForgeRegistries.VILLAGER_PROFESSIONS.getValue(new net.minecraft.util.ResourceLocation("minecraft:farmer")); + this.setProfession(p); + } this.field_70956_bz = p_70037_1_.func_74762_e("Riches"); diff --git a/patches/minecraft/net/minecraft/init/Bootstrap.java.patch b/patches/minecraft/net/minecraft/init/Bootstrap.java.patch index ff0511f057..59de3ce4b4 100644 --- a/patches/minecraft/net/minecraft/init/Bootstrap.java.patch +++ b/patches/minecraft/net/minecraft/init/Bootstrap.java.patch @@ -15,7 +15,7 @@ } } + -+ net.minecraftforge.fml.common.registry.GameData.vanillaSnapshot(); ++ net.minecraftforge.registries.GameData.vanillaSnapshot(); } } diff --git a/patches/minecraft/net/minecraft/item/Item.java.patch b/patches/minecraft/net/minecraft/item/Item.java.patch index d7f478eecc..21fea93a7a 100644 --- a/patches/minecraft/net/minecraft/item/Item.java.patch +++ b/patches/minecraft/net/minecraft/item/Item.java.patch @@ -5,12 +5,12 @@ import net.minecraftforge.fml.relauncher.SideOnly; -public class Item -+public class Item extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl ++public class Item extends net.minecraftforge.registries.IForgeRegistryEntry.Impl { - public static final RegistryNamespaced field_150901_e = new RegistryNamespaced(); - private static final Map field_179220_a = Maps.newHashMap(); -+ public static final RegistryNamespaced field_150901_e = net.minecraftforge.fml.common.registry.GameData.getItemRegistry(); -+ private static final Map field_179220_a = net.minecraftforge.fml.common.registry.GameData.getBlockItemMap(); ++ public static final RegistryNamespaced field_150901_e = net.minecraftforge.registries.GameData.getWrapper(Item.class); ++ private static final Map field_179220_a = net.minecraftforge.registries.GameData.getBlockItemMap(); private static final IItemPropertyGetter field_185046_b = new IItemPropertyGetter() { @SideOnly(Side.CLIENT) diff --git a/patches/minecraft/net/minecraft/item/ItemBlock.java.patch b/patches/minecraft/net/minecraft/item/ItemBlock.java.patch index e1676fd26c..deb86debf0 100644 --- a/patches/minecraft/net/minecraft/item/ItemBlock.java.patch +++ b/patches/minecraft/net/minecraft/item/ItemBlock.java.patch @@ -37,8 +37,15 @@ { p_179222_3_ = EnumFacing.UP; } -@@ -175,4 +163,29 @@ +@@ -173,6 +161,36 @@ + + public Block func_179223_d() { ++ return this.getBlockRaw() == null ? null : this.getBlockRaw().delegate.get(); ++ } ++ ++ private Block getBlockRaw() ++ { return this.field_150939_a; } + diff --git a/patches/minecraft/net/minecraft/item/ItemBlockSpecial.java.patch b/patches/minecraft/net/minecraft/item/ItemBlockSpecial.java.patch index 7bf822c609..57c528072f 100644 --- a/patches/minecraft/net/minecraft/item/ItemBlockSpecial.java.patch +++ b/patches/minecraft/net/minecraft/item/ItemBlockSpecial.java.patch @@ -18,13 +18,18 @@ p_180614_2_.func_184133_a(p_180614_1_, p_180614_3_, soundtype.func_185841_e(), SoundCategory.BLOCKS, (soundtype.func_185843_a() + 1.0F) / 2.0F, soundtype.func_185847_b() * 0.8F); itemstack.func_190918_g(1); return EnumActionResult.SUCCESS; -@@ -75,4 +75,9 @@ +@@ -75,4 +75,14 @@ return EnumActionResult.FAIL; } } + + public Block getBlock() + { ++ return this.getBlockRaw() == null ? null : this.getBlockRaw().delegate.get(); ++ } ++ ++ private Block getBlockRaw() ++ { + return this.field_150935_a; + } } diff --git a/patches/minecraft/net/minecraft/item/ItemStack.java.patch b/patches/minecraft/net/minecraft/item/ItemStack.java.patch index 34fea415b1..933386e65e 100644 --- a/patches/minecraft/net/minecraft/item/ItemStack.java.patch +++ b/patches/minecraft/net/minecraft/item/ItemStack.java.patch @@ -13,7 +13,7 @@ private Block field_179550_j; private boolean field_179551_k; -+ private net.minecraftforge.fml.common.registry.RegistryDelegate delegate; ++ private net.minecraftforge.registries.IRegistryDelegate delegate; + private net.minecraftforge.common.capabilities.CapabilityDispatcher capabilities; + private NBTTagCompound capNBT; + diff --git a/patches/minecraft/net/minecraft/item/crafting/CraftingManager.java.patch b/patches/minecraft/net/minecraft/item/crafting/CraftingManager.java.patch index 421891dfa5..de4592198a 100644 --- a/patches/minecraft/net/minecraft/item/crafting/CraftingManager.java.patch +++ b/patches/minecraft/net/minecraft/item/crafting/CraftingManager.java.patch @@ -5,7 +5,7 @@ private static final Logger field_192422_a = LogManager.getLogger(); private static int field_193381_c; - public static final RegistryNamespaced field_193380_a = new RegistryNamespaced(); -+ public static final RegistryNamespaced field_193380_a = net.minecraftforge.fml.common.registry.GameData.getRecipeRegistry(); ++ public static final RegistryNamespaced field_193380_a = net.minecraftforge.registries.GameData.getWrapper(IRecipe.class); public static boolean func_193377_a() { diff --git a/patches/minecraft/net/minecraft/item/crafting/IRecipe.java.patch b/patches/minecraft/net/minecraft/item/crafting/IRecipe.java.patch index 1b6969d110..635aad3edb 100644 --- a/patches/minecraft/net/minecraft/item/crafting/IRecipe.java.patch +++ b/patches/minecraft/net/minecraft/item/crafting/IRecipe.java.patch @@ -8,7 +8,7 @@ -import net.minecraftforge.fml.relauncher.SideOnly; -public interface IRecipe -+public interface IRecipe extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry ++public interface IRecipe extends net.minecraftforge.registries.IForgeRegistryEntry { boolean func_77569_a(InventoryCrafting p_77569_1_, World p_77569_2_); diff --git a/patches/minecraft/net/minecraft/item/crafting/RecipeBookCloning.java.patch b/patches/minecraft/net/minecraft/item/crafting/RecipeBookCloning.java.patch index b4939fa032..3d6e9fbf1e 100644 --- a/patches/minecraft/net/minecraft/item/crafting/RecipeBookCloning.java.patch +++ b/patches/minecraft/net/minecraft/item/crafting/RecipeBookCloning.java.patch @@ -8,7 +8,7 @@ -import net.minecraftforge.fml.relauncher.SideOnly; -public class RecipeBookCloning implements IRecipe -+public class RecipeBookCloning extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl implements IRecipe ++public class RecipeBookCloning extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { public boolean func_77569_a(InventoryCrafting p_77569_1_, World p_77569_2_) { diff --git a/patches/minecraft/net/minecraft/item/crafting/RecipeFireworks.java.patch b/patches/minecraft/net/minecraft/item/crafting/RecipeFireworks.java.patch index ab0d42210f..b48e353237 100644 --- a/patches/minecraft/net/minecraft/item/crafting/RecipeFireworks.java.patch +++ b/patches/minecraft/net/minecraft/item/crafting/RecipeFireworks.java.patch @@ -8,7 +8,7 @@ -import net.minecraftforge.fml.relauncher.SideOnly; -public class RecipeFireworks implements IRecipe -+public class RecipeFireworks extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl implements IRecipe ++public class RecipeFireworks extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { private ItemStack field_92102_a = ItemStack.field_190927_a; diff --git a/patches/minecraft/net/minecraft/item/crafting/RecipeRepairItem.java.patch b/patches/minecraft/net/minecraft/item/crafting/RecipeRepairItem.java.patch index a4d76b0125..7fa875c4d0 100644 --- a/patches/minecraft/net/minecraft/item/crafting/RecipeRepairItem.java.patch +++ b/patches/minecraft/net/minecraft/item/crafting/RecipeRepairItem.java.patch @@ -8,7 +8,7 @@ -import net.minecraftforge.fml.relauncher.SideOnly; -public class RecipeRepairItem implements IRecipe -+public class RecipeRepairItem extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl implements IRecipe ++public class RecipeRepairItem extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { public boolean func_77569_a(InventoryCrafting p_77569_1_, World p_77569_2_) { diff --git a/patches/minecraft/net/minecraft/item/crafting/RecipeTippedArrow.java.patch b/patches/minecraft/net/minecraft/item/crafting/RecipeTippedArrow.java.patch index 8fc339216d..7447209fae 100644 --- a/patches/minecraft/net/minecraft/item/crafting/RecipeTippedArrow.java.patch +++ b/patches/minecraft/net/minecraft/item/crafting/RecipeTippedArrow.java.patch @@ -8,7 +8,7 @@ -import net.minecraftforge.fml.relauncher.SideOnly; -public class RecipeTippedArrow implements IRecipe -+public class RecipeTippedArrow extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl implements IRecipe ++public class RecipeTippedArrow extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { public boolean func_77569_a(InventoryCrafting p_77569_1_, World p_77569_2_) { diff --git a/patches/minecraft/net/minecraft/item/crafting/RecipesArmorDyes.java.patch b/patches/minecraft/net/minecraft/item/crafting/RecipesArmorDyes.java.patch index 11ef5a6706..764e30c7e4 100644 --- a/patches/minecraft/net/minecraft/item/crafting/RecipesArmorDyes.java.patch +++ b/patches/minecraft/net/minecraft/item/crafting/RecipesArmorDyes.java.patch @@ -8,7 +8,7 @@ -import net.minecraftforge.fml.relauncher.SideOnly; -public class RecipesArmorDyes implements IRecipe -+public class RecipesArmorDyes extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl implements IRecipe ++public class RecipesArmorDyes extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { public boolean func_77569_a(InventoryCrafting p_77569_1_, World p_77569_2_) { diff --git a/patches/minecraft/net/minecraft/item/crafting/RecipesBanners.java.patch b/patches/minecraft/net/minecraft/item/crafting/RecipesBanners.java.patch index b9be93622c..211a1bf980 100644 --- a/patches/minecraft/net/minecraft/item/crafting/RecipesBanners.java.patch +++ b/patches/minecraft/net/minecraft/item/crafting/RecipesBanners.java.patch @@ -10,7 +10,7 @@ public class RecipesBanners { - public static class RecipeAddPattern implements IRecipe -+ public static class RecipeAddPattern extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl implements IRecipe ++ public static class RecipeAddPattern extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { public boolean func_77569_a(InventoryCrafting p_77569_1_, World p_77569_2_) { @@ -102,7 +102,7 @@ } - public static class RecipeDuplicatePattern implements IRecipe -+ public static class RecipeDuplicatePattern extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl implements IRecipe ++ public static class RecipeDuplicatePattern extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { public boolean func_77569_a(InventoryCrafting p_77569_1_, World p_77569_2_) { diff --git a/patches/minecraft/net/minecraft/item/crafting/RecipesMapCloning.java.patch b/patches/minecraft/net/minecraft/item/crafting/RecipesMapCloning.java.patch index 537f3f7e01..d8da106418 100644 --- a/patches/minecraft/net/minecraft/item/crafting/RecipesMapCloning.java.patch +++ b/patches/minecraft/net/minecraft/item/crafting/RecipesMapCloning.java.patch @@ -8,7 +8,7 @@ -import net.minecraftforge.fml.relauncher.SideOnly; -public class RecipesMapCloning implements IRecipe -+public class RecipesMapCloning extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl implements IRecipe ++public class RecipesMapCloning extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { public boolean func_77569_a(InventoryCrafting p_77569_1_, World p_77569_2_) { diff --git a/patches/minecraft/net/minecraft/item/crafting/ShapedRecipes.java.patch b/patches/minecraft/net/minecraft/item/crafting/ShapedRecipes.java.patch index dbb896f9e4..657a2822d3 100644 --- a/patches/minecraft/net/minecraft/item/crafting/ShapedRecipes.java.patch +++ b/patches/minecraft/net/minecraft/item/crafting/ShapedRecipes.java.patch @@ -8,7 +8,7 @@ -import net.minecraftforge.fml.relauncher.SideOnly; -public class ShapedRecipes implements IRecipe -+public class ShapedRecipes extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl implements IRecipe ++public class ShapedRecipes extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { public final int field_77576_b; public final int field_77577_c; diff --git a/patches/minecraft/net/minecraft/item/crafting/ShapelessRecipes.java.patch b/patches/minecraft/net/minecraft/item/crafting/ShapelessRecipes.java.patch index 4c9e94b1f0..4d243ecbe0 100644 --- a/patches/minecraft/net/minecraft/item/crafting/ShapelessRecipes.java.patch +++ b/patches/minecraft/net/minecraft/item/crafting/ShapelessRecipes.java.patch @@ -8,7 +8,7 @@ -import net.minecraftforge.fml.relauncher.SideOnly; -public class ShapelessRecipes implements IRecipe -+public class ShapelessRecipes extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl implements IRecipe ++public class ShapelessRecipes extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { private final ItemStack field_77580_a; public final NonNullList field_77579_b; diff --git a/patches/minecraft/net/minecraft/item/crafting/ShieldRecipes.java.patch b/patches/minecraft/net/minecraft/item/crafting/ShieldRecipes.java.patch index b49212edc7..8f3c0b42e5 100644 --- a/patches/minecraft/net/minecraft/item/crafting/ShieldRecipes.java.patch +++ b/patches/minecraft/net/minecraft/item/crafting/ShieldRecipes.java.patch @@ -10,7 +10,7 @@ public class ShieldRecipes { - public static class Decoration implements IRecipe -+ public static class Decoration extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl implements IRecipe ++ public static class Decoration extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { public boolean func_77569_a(InventoryCrafting p_77569_1_, World p_77569_2_) { diff --git a/patches/minecraft/net/minecraft/item/crafting/ShulkerBoxRecipes.java.patch b/patches/minecraft/net/minecraft/item/crafting/ShulkerBoxRecipes.java.patch index 9e713722ea..4ce265c5c3 100644 --- a/patches/minecraft/net/minecraft/item/crafting/ShulkerBoxRecipes.java.patch +++ b/patches/minecraft/net/minecraft/item/crafting/ShulkerBoxRecipes.java.patch @@ -10,7 +10,7 @@ public class ShulkerBoxRecipes { - public static class ShulkerBoxColoring implements IRecipe -+ public static class ShulkerBoxColoring extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl implements IRecipe ++ public static class ShulkerBoxColoring extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe { public boolean func_77569_a(InventoryCrafting p_77569_1_, World p_77569_2_) { diff --git a/patches/minecraft/net/minecraft/potion/Potion.java.patch b/patches/minecraft/net/minecraft/potion/Potion.java.patch index aca33d9f31..e31341268f 100644 --- a/patches/minecraft/net/minecraft/potion/Potion.java.patch +++ b/patches/minecraft/net/minecraft/potion/Potion.java.patch @@ -5,10 +5,10 @@ import net.minecraftforge.fml.relauncher.SideOnly; -public class Potion -+public class Potion extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl ++public class Potion extends net.minecraftforge.registries.IForgeRegistryEntry.Impl { - public static final RegistryNamespaced field_188414_b = new RegistryNamespaced(); -+ public static final RegistryNamespaced field_188414_b = net.minecraftforge.fml.common.registry.GameData.getPotionRegistry(); ++ public static final RegistryNamespaced field_188414_b = net.minecraftforge.registries.GameData.getWrapper(Potion.class); private final Map field_111188_I = Maps.newHashMap(); private final boolean field_76418_K; private final int field_76414_N; diff --git a/patches/minecraft/net/minecraft/potion/PotionType.java.patch b/patches/minecraft/net/minecraft/potion/PotionType.java.patch index 935876ae8c..0af4665e36 100644 --- a/patches/minecraft/net/minecraft/potion/PotionType.java.patch +++ b/patches/minecraft/net/minecraft/potion/PotionType.java.patch @@ -5,12 +5,12 @@ import net.minecraft.util.registry.RegistryNamespacedDefaultedByKey; -public class PotionType -+public class PotionType extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl ++public class PotionType extends net.minecraftforge.registries.IForgeRegistryEntry.Impl { + @Deprecated // unused private static final ResourceLocation field_185177_b = new ResourceLocation("empty"); - public static final RegistryNamespacedDefaultedByKey field_185176_a = new RegistryNamespacedDefaultedByKey(field_185177_b); -+ public static final RegistryNamespacedDefaultedByKey field_185176_a = net.minecraftforge.fml.common.registry.GameData.getPotionTypesRegistry(); ++ public static final RegistryNamespacedDefaultedByKey field_185176_a = net.minecraftforge.registries.GameData.getWrapperDefaulted(PotionType.class); private static int field_185178_c; private final String field_185179_d; private final ImmutableList field_185180_e; diff --git a/patches/minecraft/net/minecraft/stats/StatList.java.patch b/patches/minecraft/net/minecraft/stats/StatList.java.patch index 906adf5053..efabe0caf5 100644 --- a/patches/minecraft/net/minecraft/stats/StatList.java.patch +++ b/patches/minecraft/net/minecraft/stats/StatList.java.patch @@ -1,6 +1,6 @@ --- ../src-base/minecraft/net/minecraft/stats/StatList.java +++ ../src-work/minecraft/net/minecraft/stats/StatList.java -@@ -162,12 +162,12 @@ +@@ -162,7 +162,7 @@ } } @@ -9,13 +9,7 @@ } private static void func_151181_c() - { -- for (Block block : Block.field_149771_c) -+ for (Block block : net.minecraftforge.fml.common.registry.GameData.getBlockRegistry().typeSafeIterable()) - { - Item item = Item.func_150898_a(block); - -@@ -184,12 +184,12 @@ +@@ -184,7 +184,7 @@ } } @@ -24,13 +18,7 @@ } private static void func_75925_c() - { -- for (Item item : Item.field_150901_e) -+ for (Item item : net.minecraftforge.fml.common.registry.GameData.getItemRegistry().typeSafeIterable()) - { - if (item != null) - { -@@ -208,12 +208,12 @@ +@@ -208,7 +208,7 @@ } } @@ -39,13 +27,7 @@ } private static void func_151179_e() - { -- for (Item item : Item.field_150901_e) -+ for (Item item : net.minecraftforge.fml.common.registry.GameData.getItemRegistry().typeSafeIterable()) - { - if (item != null) - { -@@ -227,12 +227,12 @@ +@@ -227,7 +227,7 @@ } } @@ -54,12 +36,6 @@ } private static void func_188054_f() - { -- for (Item item : Item.field_150901_e) -+ for (Item item : net.minecraftforge.fml.common.registry.GameData.getItemRegistry().typeSafeIterable()) - { - if (item != null) - { @@ -247,7 +247,7 @@ } } diff --git a/patches/minecraft/net/minecraft/tileentity/TileEntity.java.patch b/patches/minecraft/net/minecraft/tileentity/TileEntity.java.patch index 613ac20443..ee4616fc7f 100644 --- a/patches/minecraft/net/minecraft/tileentity/TileEntity.java.patch +++ b/patches/minecraft/net/minecraft/tileentity/TileEntity.java.patch @@ -1,6 +1,6 @@ --- ../src-base/minecraft/net/minecraft/tileentity/TileEntity.java +++ ../src-work/minecraft/net/minecraft/tileentity/TileEntity.java -@@ -21,10 +21,10 @@ +@@ -21,7 +21,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -8,11 +8,7 @@ +public abstract class TileEntity implements net.minecraftforge.common.capabilities.ICapabilitySerializable { private static final Logger field_145852_a = LogManager.getLogger(); -- private static final RegistryNamespaced < ResourceLocation, Class > field_190562_f = new RegistryNamespaced < ResourceLocation, Class > (); -+ private static final RegistryNamespaced < ResourceLocation, Class > field_190562_f = net.minecraftforge.fml.common.registry.GameData.getTileEntityRegistry(); - protected World field_145850_b; - protected BlockPos field_174879_c = BlockPos.field_177992_a; - protected boolean field_145846_f; + private static final RegistryNamespaced < ResourceLocation, Class > field_190562_f = new RegistryNamespaced < ResourceLocation, Class > (); @@ -60,6 +60,8 @@ public void func_145839_a(NBTTagCompound p_145839_1_) { diff --git a/patches/minecraft/net/minecraft/util/SoundEvent.java.patch b/patches/minecraft/net/minecraft/util/SoundEvent.java.patch index 57c472974f..e1970495c2 100644 --- a/patches/minecraft/net/minecraft/util/SoundEvent.java.patch +++ b/patches/minecraft/net/minecraft/util/SoundEvent.java.patch @@ -5,10 +5,10 @@ import net.minecraftforge.fml.relauncher.SideOnly; -public class SoundEvent -+public class SoundEvent extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl ++public class SoundEvent extends net.minecraftforge.registries.IForgeRegistryEntry.Impl { - public static final RegistryNamespaced field_187505_a = new RegistryNamespaced(); -+ public static final RegistryNamespaced field_187505_a = net.minecraftforge.fml.common.registry.GameData.getSoundEventRegistry(); ++ public static final RegistryNamespaced field_187505_a = net.minecraftforge.registries.GameData.getWrapper(SoundEvent.class); private final ResourceLocation field_187506_b; private static int field_187507_c; diff --git a/patches/minecraft/net/minecraft/world/biome/Biome.java.patch b/patches/minecraft/net/minecraft/world/biome/Biome.java.patch index e8ff693f81..16852b1669 100644 --- a/patches/minecraft/net/minecraft/world/biome/Biome.java.patch +++ b/patches/minecraft/net/minecraft/world/biome/Biome.java.patch @@ -5,7 +5,7 @@ import org.apache.logging.log4j.Logger; -public abstract class Biome -+public abstract class Biome extends net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl ++public abstract class Biome extends net.minecraftforge.registries.IForgeRegistryEntry.Impl { private static final Logger field_150586_aC = LogManager.getLogger(); protected static final IBlockState field_185365_a = Blocks.field_150348_b.func_176223_P(); @@ -14,7 +14,7 @@ protected static final WorldGenBigTree field_76758_O = new WorldGenBigTree(false); protected static final WorldGenSwamp field_76763_Q = new WorldGenSwamp(); - public static final RegistryNamespaced field_185377_q = new RegistryNamespaced(); -+ public static final RegistryNamespaced field_185377_q = net.minecraftforge.fml.common.registry.GameData.getBiomeRegistry(); ++ public static final RegistryNamespaced field_185377_q = net.minecraftforge.registries.GameData.getWrapper(Biome.class); private final String field_76791_y; private final float field_76748_D; private final float field_76749_E; diff --git a/src/main/java/net/minecraftforge/client/model/ModelLoader.java b/src/main/java/net/minecraftforge/client/model/ModelLoader.java index 1a2e4eb647..7e8adb1819 100644 --- a/src/main/java/net/minecraftforge/client/model/ModelLoader.java +++ b/src/main/java/net/minecraftforge/client/model/ModelLoader.java @@ -98,8 +98,9 @@ import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.ProgressManager; import net.minecraftforge.fml.common.ProgressManager.ProgressBar; -import net.minecraftforge.fml.common.registry.GameData; -import net.minecraftforge.fml.common.registry.RegistryDelegate; +import net.minecraftforge.fml.common.registry.ForgeRegistries; +import net.minecraftforge.registries.GameData; +import net.minecraftforge.registries.IRegistryDelegate; import org.apache.commons.lang3.tuple.Pair; @@ -1015,7 +1016,7 @@ public final class ModelLoader extends ModelBakery Map modelErrors = Maps.newHashMap(); Set printedBlockStateErrors = Sets.newHashSet(); Multimap reverseBlockMap = null; - Multimap reverseItemMap = null; + Multimap reverseItemMap = HashMultimap.create(); if(enableVerboseMissingInfo) { reverseBlockMap = HashMultimap.create(); @@ -1023,15 +1024,14 @@ public final class ModelLoader extends ModelBakery { reverseBlockMap.put(entry.getValue(), entry.getKey()); } - reverseItemMap = HashMultimap.create(); - for(Item item : GameData.getItemRegistry().typeSafeIterable()) + ForgeRegistries.ITEMS.forEach(item -> { for(String s : getVariantNames(item)) { ModelResourceLocation memory = getInventoryVariant(s); reverseItemMap.put(memory, item.getRegistryName().toString()); } - } + }); } for(Map.Entry entry : loadingExceptions.entrySet()) @@ -1133,7 +1133,7 @@ public final class ModelLoader extends ModelBakery isLoading = false; } - private static final Map, IStateMapper> customStateMappers = Maps.newHashMap(); + private static final Map, IStateMapper> customStateMappers = Maps.newHashMap(); /** * Adds a custom IBlockState -> model variant logic. @@ -1148,14 +1148,14 @@ public final class ModelLoader extends ModelBakery */ public static void onRegisterAllBlocks(BlockModelShapes shapes) { - for (Entry, IStateMapper> e : customStateMappers.entrySet()) + for (Entry, IStateMapper> e : customStateMappers.entrySet()) { shapes.registerBlockWithStateMapper(e.getKey().get(), e.getValue()); } } - private static final Map, ItemMeshDefinition> customMeshDefinitions = com.google.common.collect.Maps.newHashMap(); - private static final Map, Integer>, ModelResourceLocation> customModels = com.google.common.collect.Maps.newHashMap(); + private static final Map, ItemMeshDefinition> customMeshDefinitions = com.google.common.collect.Maps.newHashMap(); + private static final Map, Integer>, ModelResourceLocation> customModels = com.google.common.collect.Maps.newHashMap(); /** * Adds a simple mapping from Item + metadata to the model variant. @@ -1196,11 +1196,11 @@ public final class ModelLoader extends ModelBakery */ public static void onRegisterItems(ItemModelMesher mesher) { - for (Map.Entry, ItemMeshDefinition> e : customMeshDefinitions.entrySet()) + for (Map.Entry, ItemMeshDefinition> e : customMeshDefinitions.entrySet()) { mesher.register(e.getKey().get(), e.getValue()); } - for (Entry, Integer>, ModelResourceLocation> e : customModels.entrySet()) + for (Entry, Integer>, ModelResourceLocation> e : customModels.entrySet()) { mesher.register(e.getKey().getLeft().get(), e.getKey().getRight(), e.getValue()); } diff --git a/src/main/java/net/minecraftforge/common/ForgeModContainer.java b/src/main/java/net/minecraftforge/common/ForgeModContainer.java index 734c3e87f1..d15089886d 100644 --- a/src/main/java/net/minecraftforge/common/ForgeModContainer.java +++ b/src/main/java/net/minecraftforge/common/ForgeModContainer.java @@ -46,6 +46,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import net.minecraft.crash.ICrashReportDetail; +import net.minecraft.item.Item; import net.minecraft.item.crafting.Ingredient; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; @@ -60,6 +61,8 @@ import net.minecraftforge.common.config.Property; import net.minecraftforge.common.model.animation.CapabilityAnimation; import net.minecraftforge.common.network.ForgeNetworkHandler; import net.minecraftforge.energy.CapabilityEnergy; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.event.RegistryEvent.MissingMappings; import net.minecraftforge.event.terraingen.DeferredBiomeDecorator; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; @@ -90,7 +93,6 @@ import net.minecraftforge.fml.common.WorldAccessContainer; import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData; import net.minecraftforge.fml.common.event.FMLConstructionEvent; import net.minecraftforge.fml.common.event.FMLLoadCompleteEvent; -import net.minecraftforge.fml.common.event.FMLMissingMappingsEvent; import net.minecraftforge.fml.common.event.FMLModIdMappingEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; @@ -380,12 +382,12 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC } } - @Subscribe - public void missingMapping(FMLMissingMappingsEvent event) + @SubscribeEvent + public void missingMapping(RegistryEvent.MissingMappings event) { - for (FMLMissingMappingsEvent.MissingMapping entry : event.getAll()) + for (MissingMappings.Mapping entry : event.getAllMappings()) { - if (entry.name.equals("minecraft:totem")) //This item changed from 1.11 -> 1.11.2 + if (entry.key.toString().equals("minecraft:totem")) //This item changed from 1.11 -> 1.11.2 { ResourceLocation newTotem = new ResourceLocation("minecraft:totem_of_undying"); entry.remap(ForgeRegistries.ITEMS.getValue(newTotem)); @@ -459,13 +461,17 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC { ForgeVersion.startVersionCheck(); } + } + @SubscribeEvent + public void registrItems(RegistryEvent.Register event) + { // Add and register the forge universal bucket, if it's enabled if(FluidRegistry.isUniversalBucketEnabled()) { universalBucket = new UniversalBucket(); universalBucket.setUnlocalizedName("forge.bucketFilled"); - GameRegistry.register(universalBucket.setRegistryName(ForgeVersion.MOD_ID, "bucketFilled")); + event.getRegistry().register(universalBucket.setRegistryName(ForgeVersion.MOD_ID, "bucketFilled")); MinecraftForge.EVENT_BUS.register(universalBucket); } } diff --git a/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java b/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java index 915acb78e9..745abc16ed 100644 --- a/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java +++ b/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java @@ -71,11 +71,13 @@ import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.ModContainer; import net.minecraftforge.fml.common.registry.ForgeRegistries; -import net.minecraftforge.fml.common.registry.GameData; import net.minecraftforge.oredict.OreDictionary; import net.minecraftforge.oredict.OreIngredient; import net.minecraftforge.oredict.ShapedOreRecipe; import net.minecraftforge.oredict.ShapelessOreRecipe; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.GameData; +import net.minecraftforge.registries.RegistryManager; public class CraftingHelper { @@ -597,20 +599,17 @@ public class CraftingHelper { //TODO: Figure out how to remove recipes, and override them. This relies on cpw to help. //For now this is only done one after mod init, I want to move this to ServerInit and re-do it many times. init(); + ForgeRegistry reg = (ForgeRegistry)ForgeRegistries.RECIPES; if (DEBUG_LOAD_MINECRAFT) - { - Iterator itr = GameData.getRecipeRegistry().iterator(); - while(itr.hasNext()) - { - itr.next(); - itr.remove(); - } - } + reg.clear(); + else + GameData.revert(RegistryManager.FROZEN, GameData.RECIPES, false); //ModContainer old = Loader.instance().activeModContainer(); Loader.instance().setActiveModContainer(null); Loader.instance().getActiveModList().forEach((mod) -> loadFactories(mod)); Loader.instance().getActiveModList().forEach((mod) -> loadRecipes(mod)); Loader.instance().setActiveModContainer(null); + reg.freeze(); } private static void loadFactories(ModContainer mod) diff --git a/src/main/java/net/minecraftforge/event/RegistryEvent.java b/src/main/java/net/minecraftforge/event/RegistryEvent.java index 50d09ab092..9d0ebbaca5 100644 --- a/src/main/java/net/minecraftforge/event/RegistryEvent.java +++ b/src/main/java/net/minecraftforge/event/RegistryEvent.java @@ -19,13 +19,19 @@ package net.minecraftforge.event; +import java.util.Collection; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.Validate; + +import com.google.common.collect.ImmutableList; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.common.ModContainer; import net.minecraftforge.fml.common.eventhandler.Event; import net.minecraftforge.fml.common.eventhandler.GenericEvent; import net.minecraftforge.fml.common.eventhandler.IContextSetter; -import net.minecraftforge.fml.common.registry.IForgeRegistry; -import net.minecraftforge.fml.common.registry.IForgeRegistryEntry; -import net.minecraftforge.fml.common.registry.PersistentRegistryManager; +import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.IForgeRegistryEntry; /** @@ -37,9 +43,10 @@ public class RegistryEvent> extends GenericEven super(clazz); } /** - * Register new registries when you receive this event, through the {@link PersistentRegistryManager} + * Register new registries when you receive this event, through the {@link RecipeBuilder} */ - public static class NewRegistry extends Event { + public static class NewRegistry extends Event + { } /** @@ -53,14 +60,15 @@ public class RegistryEvent> extends GenericEven * ObjectHolders will reload between Blocks and Items, and after all registries have been visited. * @param The registry top level type */ - public static class Register> extends RegistryEvent { + public static class Register> extends RegistryEvent + { private final IForgeRegistry registry; - private final ResourceLocation location; + private final ResourceLocation name; - public Register(ResourceLocation location, IForgeRegistry registry) + public Register(ResourceLocation name, IForgeRegistry registry) { super(registry.getRegistrySuperType()); - this.location = location; + this.name = name; this.registry = registry; } @@ -69,10 +77,145 @@ public class RegistryEvent> extends GenericEven return registry; } - public ResourceLocation getLocation() + public ResourceLocation getName() { - return location; + return name; } } + + public static class MissingMappings> extends RegistryEvent + { + private final IForgeRegistry registry; + private final ResourceLocation name; + private final ImmutableList> mappings; + private ModContainer activeMod; + + public MissingMappings(ResourceLocation name, IForgeRegistry registry, Collection> missed) + { + super(registry.getRegistrySuperType()); + this.registry = registry; + this.name = name; + this.mappings = ImmutableList.copyOf(missed); + } + + public ResourceLocation getName() + { + return this.name; + } + + public IForgeRegistry getRegistry() + { + return this.registry; + } + + public ImmutableList> getMappings() + { + return ImmutableList.copyOf(this.mappings.stream().filter(e -> e.key.getResourceDomain().equals(this.activeMod.getModId())).collect(Collectors.toList())); + } + + public ImmutableList> getAllMappings() + { + return this.mappings; + } + + /** + * Actions you can take with this missing mapping. + *
    + *
  • {@link #IGNORE} means this missing mapping will be ignored. + *
  • {@link #WARN} means this missing mapping will generate a warning. + *
  • {@link #FAIL} means this missing mapping will prevent the world from loading. + *
+ */ + public enum Action + { + /** + * Take the default action + */ + DEFAULT, + /** + * Ignore this missing mapping. This means the mapping will be abandoned + */ + IGNORE, + /** + * Generate a warning but allow loading to continue + */ + WARN, + /** + * Fail to load + */ + FAIL, + /** + * Remap this name to a new name (add a migration mapping) + */ + REMAP + } + + public static class Mapping> + { + public final IForgeRegistry registry; + public final ResourceLocation key; + public final int id; + private Action action = Action.DEFAULT; + private T target; + + public Mapping(IForgeRegistry registry, ResourceLocation key, int id) + { + this.registry = registry; + this.key = key; + this.id = id; + } + + /** + * Ignore the missing item. + */ + public void ignore() + { + action = Action.IGNORE; + } + + /** + * Warn the user about the missing item. + */ + public void warn() + { + action = Action.WARN; + } + + /** + * Prevent the world from loading due to the missing item. + */ + public void fail() + { + action = Action.FAIL; + } + + /** + * Remap the missing entry to the specified object. + * + * Use this if you have renamed an entry. + * Existing references using the old name will point to the new one. + * + * @param target Entry to remap to. + */ + public void remap(T target) + { + Validate.notNull(target, "Remap target can not be null"); + Validate.isTrue(registry.getKey(target) != null, String.format("The specified entry %s hasn't been registered in registry yet.", target)); + action = Action.REMAP; + this.target = target; + } + + // internal + public Action getAction() + { + return this.action; + } + + public T getTarget() + { + return target; + } + } + } } diff --git a/src/main/java/net/minecraftforge/fluids/FluidRegistry.java b/src/main/java/net/minecraftforge/fluids/FluidRegistry.java index d1b42314d9..82ad976764 100644 --- a/src/main/java/net/minecraftforge/fluids/FluidRegistry.java +++ b/src/main/java/net/minecraftforge/fluids/FluidRegistry.java @@ -47,7 +47,7 @@ import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.ModContainer; import net.minecraftforge.fml.common.eventhandler.Event; -import net.minecraftforge.fml.common.registry.RegistryDelegate; +import net.minecraftforge.registries.IRegistryDelegate; import javax.annotation.Nullable; @@ -411,13 +411,13 @@ public abstract class FluidRegistry } } - static RegistryDelegate makeDelegate(Fluid fl) + static IRegistryDelegate makeDelegate(Fluid fl) { return delegates.get(fl); } - private static class FluidDelegate implements RegistryDelegate + private static class FluidDelegate implements IRegistryDelegate { private String name; private Fluid fluid; diff --git a/src/main/java/net/minecraftforge/fluids/FluidStack.java b/src/main/java/net/minecraftforge/fluids/FluidStack.java index 537e9d41c3..29f42f6b9e 100644 --- a/src/main/java/net/minecraftforge/fluids/FluidStack.java +++ b/src/main/java/net/minecraftforge/fluids/FluidStack.java @@ -24,7 +24,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.Constants; import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.registry.RegistryDelegate; +import net.minecraftforge.registries.IRegistryDelegate; import javax.annotation.Nullable; @@ -40,7 +40,7 @@ public class FluidStack { public int amount; public NBTTagCompound tag; - private RegistryDelegate fluidDelegate; + private IRegistryDelegate fluidDelegate; public FluidStack(Fluid fluid, int amount) { diff --git a/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java b/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java index 79b6f67d24..2d8725df87 100644 --- a/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java +++ b/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java @@ -106,9 +106,9 @@ import net.minecraftforge.fml.common.WrongMinecraftVersionException; import net.minecraftforge.fml.common.eventhandler.EventBus; import net.minecraftforge.fml.common.network.FMLNetworkEvent; import net.minecraftforge.fml.common.network.internal.FMLNetworkHandler; -import net.minecraftforge.fml.common.registry.PersistentRegistryManager; import net.minecraftforge.fml.common.toposort.ModSortingException; import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.registries.GameData; import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.Level; @@ -735,7 +735,7 @@ public class FMLClientHandler implements IFMLSidedHandler // ONLY revert a non-local connection if (client != null && !client.isLocalChannel()) { - PersistentRegistryManager.revertToFrozen(); + GameData.revertToFrozen(); } } diff --git a/src/main/java/net/minecraftforge/fml/common/FMLContainer.java b/src/main/java/net/minecraftforge/fml/common/FMLContainer.java index 406d03c1b2..e62741a331 100644 --- a/src/main/java/net/minecraftforge/fml/common/FMLContainer.java +++ b/src/main/java/net/minecraftforge/fml/common/FMLContainer.java @@ -22,12 +22,8 @@ package net.minecraftforge.fml.common; import java.io.File; import java.security.cert.Certificate; import java.util.Arrays; -import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; - import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; @@ -43,13 +39,16 @@ import net.minecraftforge.fml.common.network.NetworkCheckHandler; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.common.network.internal.FMLNetworkHandler; import net.minecraftforge.fml.common.registry.ForgeRegistries; -import net.minecraftforge.fml.common.registry.PersistentRegistryManager; -import net.minecraftforge.fml.common.registry.VillagerRegistry; import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.GameData; +import net.minecraftforge.registries.RegistryManager; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; @@ -122,13 +121,9 @@ public final class FMLContainer extends DummyModContainer implements WorldAccess NBTTagCompound registries = new NBTTagCompound(); fmlData.setTag("Registries", registries); FMLLog.log.debug("Gathering id map for writing to world save {}", info.getWorldName()); - PersistentRegistryManager.GameDataSnapshot dataSnapshot = PersistentRegistryManager.takeSnapshot(); - for (Map.Entry e : dataSnapshot.entries.entrySet()) + for (Map.Entry e : RegistryManager.ACTIVE.takeSnapshot(true).entrySet()) { - if (!e.getValue().saveToDisc) //Skip registries that don't need to persist, Currently Recipes. - continue; - NBTTagCompound data = new NBTTagCompound(); registries.setTag(e.getKey().toString(), data); @@ -152,15 +147,6 @@ public final class FMLContainer extends DummyModContainer implements WorldAccess } data.setTag("aliases", aliases); - NBTTagList subs = new NBTTagList(); - for (ResourceLocation entry : e.getValue().substitutions) - { - NBTTagCompound tag = new NBTTagCompound(); - tag.setString("K", entry.toString()); - subs.appendTag(tag); - } - data.setTag("substitutions", subs); - int[] blocked = new int[e.getValue().blocked.size()]; int idx = 0; for (Integer i : e.getValue().blocked) @@ -204,116 +190,37 @@ public final class FMLContainer extends DummyModContainer implements WorldAccess } } - List failedElements = null; + Multimap failedElements = null; - if (tag.hasKey("ModItemData")) // Pre 1.7 + if (tag.hasKey("ModItemData") || tag.hasKey("ItemData")) // Pre 1.7 { StartupQuery.notify("This save predates 1.7.10, it can no longer be loaded here. Please load in 1.7.10 or 1.8 first"); StartupQuery.abort(); } - else if (tag.hasKey("ItemData")) // 1.7 - { - if (!tag.hasKey("BlockedItemIds")) // no blocked id info -> old 1.7 save - { - StartupQuery.notify("This save predates 1.7.10, it can no longer be loaded here. Please load in 1.7.10 or 1.8 first"); - StartupQuery.abort(); - } - PersistentRegistryManager.GameDataSnapshot snapshot = new PersistentRegistryManager.GameDataSnapshot(); - PersistentRegistryManager.GameDataSnapshot.Entry blocks = new PersistentRegistryManager.GameDataSnapshot.Entry(); - PersistentRegistryManager.GameDataSnapshot.Entry items = new PersistentRegistryManager.GameDataSnapshot.Entry(); - snapshot.entries.put(PersistentRegistryManager.BLOCKS, blocks); - snapshot.entries.put(PersistentRegistryManager.ITEMS, items); - - NBTTagList list = tag.getTagList("ItemData", 10); - for (int i = 0; i < list.tagCount(); i++) - { - NBTTagCompound e = list.getCompoundTagAt(i); - String name = e.getString("K"); - - if (name.charAt(0) == '\u0001') - blocks.ids.put(new ResourceLocation(name.substring(1)), e.getInteger("V")); - else if (name.charAt(0) == '\u0002') - items.ids.put(new ResourceLocation(name.substring(1)), e.getInteger("V")); - } - - Set blockedIds = new HashSet(); - for (int id : tag.getIntArray("BlockedItemIds")) - { - blockedIds.add(id); - } - blocks.blocked.addAll(blockedIds); - items.blocked.addAll(blockedIds); - - list = tag.getTagList("BlockAliases", 10); - for (int i = 0; i < list.tagCount(); i++) - { - NBTTagCompound dataTag = list.getCompoundTagAt(i); - blocks.aliases.put(new ResourceLocation(dataTag.getString("K")), new ResourceLocation(dataTag.getString("V"))); - } - - if (tag.hasKey("BlockSubstitutions", 9)) - { - list = tag.getTagList("BlockSubstitutions", 10); - for (int i = 0; i < list.tagCount(); i++) - { - NBTTagCompound dataTag = list.getCompoundTagAt(i); - blocks.substitutions.add(new ResourceLocation(dataTag.getString("K"))); - } - } - - list = tag.getTagList("ItemAliases", 10); - for (int i = 0; i < list.tagCount(); i++) - { - NBTTagCompound dataTag = list.getCompoundTagAt(i); - items.aliases.put(new ResourceLocation(dataTag.getString("K")), new ResourceLocation(dataTag.getString("V"))); - } - - if (tag.hasKey("ItemSubstitutions", 9)) - { - list = tag.getTagList("ItemSubstitutions", 10); - for (int i = 0; i < list.tagCount(); i++) - { - NBTTagCompound dataTag = list.getCompoundTagAt(i); - items.substitutions.add(new ResourceLocation(dataTag.getString("K"))); - } - } - failedElements = PersistentRegistryManager.injectSnapshot(snapshot, true, true); - } else if (tag.hasKey("Registries")) // 1.8, genericed out the 'registries' list { - PersistentRegistryManager.GameDataSnapshot snapshot = new PersistentRegistryManager.GameDataSnapshot(); + Map snapshot = Maps.newHashMap(); NBTTagCompound regs = tag.getCompoundTag("Registries"); for (String key : regs.getKeySet()) { - PersistentRegistryManager.GameDataSnapshot.Entry entry = new PersistentRegistryManager.GameDataSnapshot.Entry(); - ResourceLocation entryLoc; - if ("fml:blocks".equals(key)) entryLoc = PersistentRegistryManager.BLOCKS; - else if ("fml:items".equals(key)) entryLoc = PersistentRegistryManager.ITEMS; - else if ("fmlgr:villagerprofessions".equals(key)) entryLoc = VillagerRegistry.PROFESSIONS; - else entryLoc = new ResourceLocation(key); - snapshot.entries.put(entryLoc, entry); + ForgeRegistry.Snapshot entry = new ForgeRegistry.Snapshot(); + NBTTagCompound ent = regs.getCompoundTag(key); + snapshot.put(new ResourceLocation(key), entry); - NBTTagList list = regs.getCompoundTag(key).getTagList("ids", 10); + NBTTagList list = ent.getTagList("ids", 10); for (int x = 0; x < list.tagCount(); x++) { NBTTagCompound e = list.getCompoundTagAt(x); entry.ids.put(new ResourceLocation(e.getString("K")), e.getInteger("V")); } - list = regs.getCompoundTag(key).getTagList("aliases", 10); + list = ent.getTagList("aliases", 10); for (int x = 0; x < list.tagCount(); x++) { NBTTagCompound e = list.getCompoundTagAt(x); entry.aliases.put(new ResourceLocation(e.getString("K")), new ResourceLocation(e.getString("V"))); } - list = regs.getCompoundTag(key).getTagList("substitutions", 10); - for (int x = 0; x < list.tagCount(); x++) - { - NBTTagCompound e = list.getCompoundTagAt(x); - entry.substitutions.add(new ResourceLocation(e.getString("K"))); - } - int[] blocked = regs.getCompoundTag(key).getIntArray("blocked"); for (int i : blocked) { @@ -330,19 +237,23 @@ public final class FMLContainer extends DummyModContainer implements WorldAccess } } } - failedElements = PersistentRegistryManager.injectSnapshot(snapshot, true, true); + failedElements = GameData.injectSnapshot(snapshot, true, true); } if (failedElements != null && !failedElements.isEmpty()) { - String text = "Forge Mod Loader could not load this save.\n\n" + - "There are "+failedElements.size()+" unassigned blocks and items in this save.\n" + - "You will not be able to load until they are present again.\n\n" + - "Missing Blocks/Items:\n"; + StringBuilder buf = new StringBuilder(); + buf.append("Forge Mod Loader could not load this save.\n\n") + .append("There are ").append(failedElements.size()).append(" unassigned registry entries in this save.\n") + .append("You will not be able to load until they are present again.\n\n"); - for (String s : failedElements) text += s + "\n"; + failedElements.asMap().forEach((name, entries) -> + { + buf.append("Missing ").append(name).append(":\n"); + entries.forEach(rl -> buf.append(" ").append(rl).append("\n")); + }); - StartupQuery.notify(text); + StartupQuery.notify(buf.toString()); StartupQuery.abort(); } } diff --git a/src/main/java/net/minecraftforge/fml/common/Loader.java b/src/main/java/net/minecraftforge/fml/common/Loader.java index 4af615b7e5..54efe5f022 100644 --- a/src/main/java/net/minecraftforge/fml/common/Loader.java +++ b/src/main/java/net/minecraftforge/fml/common/Loader.java @@ -45,13 +45,10 @@ import net.minecraftforge.fml.common.discovery.ASMDataTable; import net.minecraftforge.fml.common.discovery.ModDiscoverer; import net.minecraftforge.fml.common.event.FMLInterModComms; import net.minecraftforge.fml.common.event.FMLLoadEvent; -import net.minecraftforge.fml.common.event.FMLMissingMappingsEvent; import net.minecraftforge.fml.common.event.FMLModIdMappingEvent; -import net.minecraftforge.fml.common.event.FMLMissingMappingsEvent.MissingMapping; import net.minecraftforge.fml.common.functions.ArtifactVersionNameFunction; import net.minecraftforge.fml.common.functions.ModIdFunction; import net.minecraftforge.fml.common.registry.*; -import net.minecraftforge.fml.common.registry.GameRegistry.Type; import net.minecraftforge.fml.common.toposort.ModSorter; import net.minecraftforge.fml.common.toposort.ModSortingException; import net.minecraftforge.fml.common.toposort.TopologicalSort; @@ -60,6 +57,8 @@ import net.minecraftforge.fml.common.versioning.ArtifactVersion; import net.minecraftforge.fml.common.versioning.VersionParser; import net.minecraftforge.fml.relauncher.ModListHelper; import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.registries.GameData; +import net.minecraftforge.registries.ObjectHolderRegistry; import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.Level; @@ -639,11 +638,11 @@ public class Loader FMLLog.log.warn("There were errors previously. Not beginning mod initialization phase"); return; } - PersistentRegistryManager.fireCreateRegistryEvents(); + GameData.fireCreateRegistryEvents(); ObjectHolderRegistry.INSTANCE.findObjectHolders(discoverer.getASMTable()); ItemStackHolderInjector.INSTANCE.findHolders(discoverer.getASMTable()); CapabilityManager.INSTANCE.injectCapabilities(discoverer.getASMTable()); - PersistentRegistryManager.fireRegistryEvents(); + GameData.fireRegistryEvents(); FMLCommonHandler.instance().fireSidedRegistryEvents(); modController.distributeStateMessage(LoaderState.PREINITIALIZATION, discoverer.getASMTable(), canonicalConfigDir); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); @@ -836,7 +835,7 @@ public class Loader progressBar.step("Finishing up"); modController.transition(LoaderState.AVAILABLE, false); modController.distributeStateMessage(LoaderState.AVAILABLE); - PersistentRegistryManager.freezeData(); + GameData.freezeData(); FMLLog.log.info("Forge Mod Loader has successfully loaded {} mod{}", mods.size(), mods.size() == 1 ? "" : "s"); progressBar.step("Completing Minecraft initialization"); } @@ -938,7 +937,7 @@ public class Loader public void serverStopped() { - PersistentRegistryManager.revertToFrozen(); + GameData.revertToFrozen(); modController.distributeStateMessage(LoaderState.SERVER_STOPPED); modController.transition(LoaderState.SERVER_STOPPED, true); modController.transition(LoaderState.AVAILABLE, true); @@ -1004,80 +1003,6 @@ public class Loader return true; } - /** - * Fire a FMLMissingMappingsEvent to let mods determine how blocks/items defined in the world - * save, but missing from the runtime, are to be handled. - * - * @param missingBlocks Map containing the missing block names with their associated id. Remapped blocks will be removed from it. - * @param missingItems Map containing the missing block names with their associated id. Remapped items will be removed from it. - * @param isLocalWorld Whether this is executing for a world load (local/server) or a client. - * @param remapBlocks Returns a map containing the remapped block names and an array containing the original and new id for the block. - * @param remapItems Returns a map containing the remapped item names and an array containing the original and new id for the item. - * @return List with the names of the failed remappings. - */ - public List fireMissingMappingEvent(Map missingBlocks, Map missingItems, boolean isLocalWorld, Map remapBlocks, Map remapItems) - { - if (missingBlocks.isEmpty() && missingItems.isEmpty()) // nothing to do - { - return ImmutableList.of(); - } - - FMLLog.log.debug("There are {} mappings missing - attempting a mod remap", missingBlocks.size() + missingItems.size()); - ArrayListMultimap missingMappings = ArrayListMultimap.create(); - - for (Map.Entry mapping : missingBlocks.entrySet()) - { - MissingMapping m = new MissingMapping(GameRegistry.Type.BLOCK, mapping.getKey(), mapping.getValue()); - missingMappings.put(m.resourceLocation.getResourceDomain(), m); - } - for (Map.Entry mapping : missingItems.entrySet()) - { - MissingMapping m = new MissingMapping(GameRegistry.Type.ITEM, mapping.getKey(), mapping.getValue()); - missingMappings.put(m.resourceLocation.getResourceDomain(), m); - } - - FMLMissingMappingsEvent missingEvent = new FMLMissingMappingsEvent(missingMappings); - modController.propogateStateMessage(missingEvent); - - if (isLocalWorld) // local world, warn about entries still being set to the default action - { - boolean didWarn = false; - - for (MissingMapping mapping : missingMappings.values()) - { - if (mapping.getAction() == FMLMissingMappingsEvent.Action.DEFAULT) - { - if (!didWarn) - { - FMLLog.log.fatal("There are unidentified mappings in this world - we are going to attempt to process anyway"); - didWarn = true; - } - - FMLLog.log.fatal("Unidentified {}: {}, id {}", mapping.type == Type.BLOCK ? "block" : "item", mapping.name, mapping.id); - } - } - } - else // remote world, fail on entries with the default action - { - List missedMapping = new ArrayList(); - - for (MissingMapping mapping : missingMappings.values()) - { - if (mapping.getAction() == FMLMissingMappingsEvent.Action.DEFAULT) - { - missedMapping.add(mapping.name); - } - } - - if (!missedMapping.isEmpty()) - { - return ImmutableList.copyOf(missedMapping); - } - } - - return PersistentRegistryManager.processIdRematches(missingMappings.values(), isLocalWorld, missingBlocks, missingItems, remapBlocks, remapItems); - } - public void fireRemapEvent(Map remapBlocks, Map remapItems, boolean isFreezing) { if (modController!=null) diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/FieldRedirectTransformer.java b/src/main/java/net/minecraftforge/fml/common/asm/transformers/FieldRedirectTransformer.java new file mode 100644 index 0000000000..d51d0eefde --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/common/asm/transformers/FieldRedirectTransformer.java @@ -0,0 +1,119 @@ +/* + * Minecraft Forge + * Copyright (c) 2016. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.fml.common.asm.transformers; + +import java.util.ListIterator; + +import net.minecraft.launchwrapper.IClassTransformer; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldInsnNode; +import org.objectweb.asm.tree.FieldNode; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; + +public class FieldRedirectTransformer implements IClassTransformer +{ + private final String clsName; + private final String TYPE; + private final String DESC; + private final String bypass; + + protected FieldRedirectTransformer(String cls, String type, String bypass) + { + this.clsName = cls; + this.TYPE = type; + this.DESC = "()" + type; + this.bypass = bypass; + } + + @Override + public byte[] transform(String name, String transformedName, byte[] basicClass) + { + if (!this.clsName.equals(name)) + return basicClass; + + ClassNode classNode = new ClassNode(); + ClassReader classReader = new ClassReader(basicClass); + classReader.accept(classNode, 0); + + FieldNode fieldRef = null; + for (FieldNode f : classNode.fields) + { + if (this.TYPE.equals(f.desc) && fieldRef == null) + { + fieldRef = f; + } + else if (this.TYPE.equals(f.desc)) + { + throw new RuntimeException("Error processing " + clsName + " - found a duplicate holder field"); + } + } + if (fieldRef == null) + { + throw new RuntimeException("Error processing " + clsName + " - no holder field declared (is the code somehow obfuscated?)"); + } + + MethodNode getMethod = null; + for (MethodNode m: classNode.methods) + { + if (m.name.equals(this.bypass)) continue; + if (this.DESC.equals(m.desc) && getMethod == null) + { + getMethod = m; + } + else if (this.DESC.equals(m.desc)) + { + throw new RuntimeException("Error processing " + clsName + " - duplicate get method found"); + } + } + if (getMethod == null) + { + throw new RuntimeException("Error processing " + clsName + " - no get method found (is the code somehow obfuscated?)"); + } + + for (MethodNode m: classNode.methods) + { + if (m.name.equals(this.bypass)) continue; + for (ListIterator it = m.instructions.iterator(); it.hasNext(); ) + { + AbstractInsnNode insnNode = it.next(); + if (insnNode.getType() == AbstractInsnNode.FIELD_INSN) + { + FieldInsnNode fi = (FieldInsnNode)insnNode; + if (fieldRef.name.equals(fi.name) && fi.getOpcode() == Opcodes.GETFIELD) + { + it.remove(); + MethodInsnNode replace = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classNode.name, getMethod.name, getMethod.desc, false); + it.add(replace); + } + } + } + } + ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); + classNode.accept(writer); + return writer.toByteArray(); + } + +} diff --git a/src/main/java/net/minecraftforge/fml/common/registry/IncompatibleSubstitutionException.java b/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockSpecialTransformer.java similarity index 60% rename from src/main/java/net/minecraftforge/fml/common/registry/IncompatibleSubstitutionException.java rename to src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockSpecialTransformer.java index 671693d2d2..5350218778 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/IncompatibleSubstitutionException.java +++ b/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockSpecialTransformer.java @@ -17,16 +17,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.common.registry; +package net.minecraftforge.fml.common.asm.transformers; -import net.minecraft.util.ResourceLocation; - -public class IncompatibleSubstitutionException extends RuntimeException { - public IncompatibleSubstitutionException(ResourceLocation fromName, Object replacement, Object original) +public class ItemBlockSpecialTransformer extends FieldRedirectTransformer +{ + public ItemBlockSpecialTransformer() { - super(String.format("The substitute %s for %s (type %s) is type incompatible.", replacement.getClass().getName(), fromName, original.getClass().getName())); + super("net.minecraft.item.ItemBlockSpecial", "Lnet/minecraft/block/Block;", "getBlockRaw"); } - - private static final long serialVersionUID = 1L; - } diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockTransformer.java b/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockTransformer.java new file mode 100644 index 0000000000..9e71460ab8 --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemBlockTransformer.java @@ -0,0 +1,28 @@ +/* + * Minecraft Forge + * Copyright (c) 2016. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.fml.common.asm.transformers; + +public class ItemBlockTransformer extends FieldRedirectTransformer +{ + public ItemBlockTransformer() + { + super("net.minecraft.item.ItemBlock", "Lnet/minecraft/block/Block;", "getBlockRaw"); + } +} diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemStackTransformer.java b/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemStackTransformer.java index 80714896ad..ab6aa5299e 100644 --- a/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemStackTransformer.java +++ b/src/main/java/net/minecraftforge/fml/common/asm/transformers/ItemStackTransformer.java @@ -19,88 +19,10 @@ package net.minecraftforge.fml.common.asm.transformers; -import java.util.ListIterator; - -import net.minecraft.launchwrapper.IClassTransformer; - -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.tree.AbstractInsnNode; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.FieldInsnNode; -import org.objectweb.asm.tree.FieldNode; -import org.objectweb.asm.tree.MethodInsnNode; -import org.objectweb.asm.tree.MethodNode; - -public class ItemStackTransformer implements IClassTransformer { - private static final String ITEM_TYPE = "Lnet/minecraft/item/Item;"; - private static final String GETITEM_DESC = "()"+ ITEM_TYPE; - - @Override - public byte[] transform(String name, String transformedName, byte[] basicClass) { - if (!"net.minecraft.item.ItemStack".equals(name)) - return basicClass; - ClassNode classNode = new ClassNode(); - ClassReader classReader = new ClassReader(basicClass); - classReader.accept(classNode, 0); - - FieldNode itemField = null; - for (FieldNode f : classNode.fields) - { - if (ITEM_TYPE.equals(f.desc) && itemField == null) - { - itemField = f; - } - else if (ITEM_TYPE.equals(f.desc)) - { - throw new RuntimeException("Error processing ItemStack - found a duplicate Item field"); - } - } - if (itemField == null) - { - throw new RuntimeException("Error processing ItemStack - no Item field declared (is the code somehow obfuscated?)"); - } - - MethodNode getItemMethod = null; - for (MethodNode m: classNode.methods) - { - if (m.name.equals("getItemRaw")) continue; - if (GETITEM_DESC.equals(m.desc) && getItemMethod == null) - { - getItemMethod = m; - } - else if (GETITEM_DESC.equals(m.desc)) - { - throw new RuntimeException("Error processing ItemStack - duplicate getItem method found"); - } - } - if (getItemMethod == null) - { - throw new RuntimeException("Error processing ItemStack - no getItem method found (is the code somehow obfuscated?)"); - } - - for (MethodNode m: classNode.methods) - { - if (m.name.equals("getItemRaw")) continue; - for (ListIterator it = m.instructions.iterator(); it.hasNext(); ) - { - AbstractInsnNode insnNode = it.next(); - if (insnNode.getType() == AbstractInsnNode.FIELD_INSN) - { - FieldInsnNode fi = (FieldInsnNode)insnNode; - if (itemField.name.equals(fi.name) && fi.getOpcode() == Opcodes.GETFIELD) - { - it.remove(); - MethodInsnNode replace = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "net/minecraft/item/ItemStack",getItemMethod.name, getItemMethod.desc, false); - it.add(replace); - } - } - } - } - ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); - classNode.accept(writer); - return writer.toByteArray(); +public class ItemStackTransformer extends FieldRedirectTransformer +{ + public ItemStackTransformer() + { + super("net.minecraft.item.ItemStack", "Lnet/minecraft/item/Item;", "getItemRaw"); } - } diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLMissingMappingsEvent.java b/src/main/java/net/minecraftforge/fml/common/event/FMLMissingMappingsEvent.java deleted file mode 100644 index 6bdb9e31d3..0000000000 --- a/src/main/java/net/minecraftforge/fml/common/event/FMLMissingMappingsEvent.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.event; - -import java.util.List; - -import net.minecraft.block.Block; -import net.minecraft.item.Item; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.ModContainer; -import net.minecraftforge.fml.common.registry.GameData; -import net.minecraftforge.fml.common.registry.GameRegistry; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ListMultimap; - -/** - * This event is fired if a world is loaded that has block and item mappings referring the mod that are not - * in existence. - * These can be remapped to other existing objects, or simply discarded. - * Use get() and getAll() to process this event. - * - * @see net.minecraftforge.fml.common.Mod.EventHandler for how to subscribe to this event - * @author cpw - * @author Player - * - */ -public class FMLMissingMappingsEvent extends FMLEvent { - /** - * Actions you can take with this missing mapping. - *
    - *
  • {@link #IGNORE} means this missing mapping will be ignored. - *
  • {@link #WARN} means this missing mapping will generate a warning. - *
  • {@link #FAIL} means this missing mapping will prevent the world from loading. - *
- * @author cpw - * - */ - public enum Action { - /** - * Take the default action - */ - DEFAULT, - /** - * Ignore this missing mapping. This means the mapping will be abandoned - */ - IGNORE, - /** - * Generate a warning but allow loading to continue - */ - WARN, - /** - * Fail to load - */ - FAIL, - /** - * Remap this name to a new name (add a migration mapping) - */ - REMAP, - /** - * Allow a block to exist without itemblock anymore - */ - BLOCKONLY - } - public static class MissingMapping { - public final GameRegistry.Type type; - public final String name; - public final int id; - public final ResourceLocation resourceLocation; - private Action action = Action.DEFAULT; - private Object target; - - public MissingMapping(GameRegistry.Type type, ResourceLocation name, int id) - { - this.type = type; - this.name = name.toString(); - this.id = id; - this.resourceLocation = name; - } - - /** - * Ignore the missing item. - */ - public void ignore() - { - action = Action.IGNORE; - } - - /** - * Warn the user about the missing item. - */ - public void warn() - { - action = Action.WARN; - } - - /** - * Prevent the world from loading due to the missing item. - */ - public void fail() - { - action = Action.FAIL; - } - - /** - * Remap the missing item to the specified Block. - * - * Use this if you have renamed a Block, don't forget to handle the ItemBlock. - * Existing references using the old name will point to the new one. - * - * @param target Block to remap to. - */ - public void remap(Block target) - { - if (type != GameRegistry.Type.BLOCK) throw new IllegalArgumentException("Can't remap an item to a block."); - if (target == null) throw new NullPointerException("remap target is null"); - if (GameData.getBlockRegistry().getId(target) < 0) throw new IllegalArgumentException(String.format("The specified block %s hasn't been registered at startup.", target)); - - action = Action.REMAP; - this.target = target; - } - - /** - * Remap the missing item to the specified Item. - * - * Use this if you have renamed an Item. - * Existing references using the old name will point to the new one. - * - * @param target Item to remap to. - */ - public void remap(Item target) - { - if (type != GameRegistry.Type.ITEM) throw new IllegalArgumentException("Can't remap a block to an item."); - if (target == null) throw new NullPointerException("remap target is null"); - if (GameData.getItemRegistry().getId(target) < 0) throw new IllegalArgumentException(String.format("The specified item %s hasn't been registered at startup.", target)); - - action = Action.REMAP; - this.target = target; - } - - public void skipItemBlock() - { - if (type != GameRegistry.Type.ITEM) throw new IllegalArgumentException("Cannot skip an item that is a block"); - if (GameData.getBlockRegistry().getRaw(id) == null) throw new IllegalArgumentException("Cannot skip an ItemBlock that doesn't have a Block"); - action = Action.BLOCKONLY; - } - // internal - - public Action getAction() - { - return this.action; - } - - public Object getTarget() - { - return target; - } - } - private ListMultimap missing; - private ModContainer activeContainer; - - public FMLMissingMappingsEvent(ListMultimap missingMappings) - { - this.missing = missingMappings; - } - - @Override - public void applyModContainer(ModContainer activeContainer) - { - super.applyModContainer(activeContainer); - this.activeContainer = activeContainer; - } - - /** - * Get the list of missing mappings for the active mod. - * - * Process the list entries by calling ignore(), warn(), fail() or remap() on each entry. - * - * @return list of missing mappings - */ - public List get() - { - return ImmutableList.copyOf(missing.get(activeContainer.getModId())); - } - - /** - * Get the list of missing mappings for all mods. - * - * Only use this if you need to handle mod id changes, e.g. if you renamed your mod or - * split/merge into/from multiple mods. - * - * Process the list entries by calling ignore(), warn(), fail() or remap() on each entry you - * want to handle. - * - * @return list of missing mappings - */ - public List getAll() - { - return ImmutableList.copyOf(missing.values()); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java b/src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java index 1127b20d2a..d47f6843f2 100644 --- a/src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java +++ b/src/main/java/net/minecraftforge/fml/common/eventhandler/EventBus.java @@ -141,6 +141,7 @@ public class EventBus implements IEventExceptionHandler { ModContainer old = Loader.instance().activeModContainer(); Loader.instance().setActiveModContainer(owner); + ((IContextSetter)event).setModContainer(owner); asm.invoke(event); Loader.instance().setActiveModContainer(old); } diff --git a/src/main/java/net/minecraftforge/fml/common/eventhandler/IContextSetter.java b/src/main/java/net/minecraftforge/fml/common/eventhandler/IContextSetter.java index eab39993ed..debf478aa9 100644 --- a/src/main/java/net/minecraftforge/fml/common/eventhandler/IContextSetter.java +++ b/src/main/java/net/minecraftforge/fml/common/eventhandler/IContextSetter.java @@ -1,7 +1,12 @@ package net.minecraftforge.fml.common.eventhandler; +import net.minecraftforge.fml.common.ModContainer; + //Instructs event handlers to set the active mod container. //This has a major performance impact so use sparingly. //Note: The context IS NOT thread aware as this would be ungodly slow. //So This should ONLY be used for Forge mod lifecycle events. -public interface IContextSetter {} +public interface IContextSetter +{ + default void setModContainer(ModContainer mod){}; +} diff --git a/src/main/java/net/minecraftforge/fml/common/launcher/FMLDeobfTweaker.java b/src/main/java/net/minecraftforge/fml/common/launcher/FMLDeobfTweaker.java index fd13e19648..f81802f8b2 100644 --- a/src/main/java/net/minecraftforge/fml/common/launcher/FMLDeobfTweaker.java +++ b/src/main/java/net/minecraftforge/fml/common/launcher/FMLDeobfTweaker.java @@ -47,6 +47,8 @@ public class FMLDeobfTweaker implements ITweaker { } classLoader.registerTransformer("net.minecraftforge.fml.common.asm.transformers.ModAccessTransformer"); classLoader.registerTransformer("net.minecraftforge.fml.common.asm.transformers.ItemStackTransformer"); + classLoader.registerTransformer("net.minecraftforge.fml.common.asm.transformers.ItemBlockTransformer"); + classLoader.registerTransformer("net.minecraftforge.fml.common.asm.transformers.ItemBlockSpecialTransformer"); try { FMLLog.log.debug("Validating minecraft"); diff --git a/src/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java b/src/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java index 27d2e1badd..aadd9be14a 100644 --- a/src/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java +++ b/src/main/java/net/minecraftforge/fml/common/network/ByteBufUtils.java @@ -28,11 +28,12 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.registry.FMLControlledNamespacedRegistry; import net.minecraftforge.fml.common.registry.GameRegistry; -import net.minecraftforge.fml.common.registry.IForgeRegistry; -import net.minecraftforge.fml.common.registry.IForgeRegistryEntry; -import net.minecraftforge.fml.common.registry.PersistentRegistryManager; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.IForgeRegistryEntry; +import net.minecraftforge.registries.RegistryManager; + import org.apache.commons.lang3.Validate; import com.google.common.base.Charsets; @@ -228,7 +229,7 @@ public class ByteBufUtils { } catch (IOException e) { // Unpossible? - throw Throwables.propagate(e); + throw new RuntimeException(e); } } @@ -240,9 +241,9 @@ public class ByteBufUtils { */ public static > void writeRegistryEntry(@Nonnull ByteBuf out, @Nonnull T entry) { - FMLControlledNamespacedRegistry registry = (FMLControlledNamespacedRegistry)GameRegistry.findRegistry(entry.getRegistryType()); - writeUTF8String(out, PersistentRegistryManager.getRegistryRegistryName(registry).toString()); - writeVarInt(out, registry.getId(entry), 5); + ForgeRegistry registry = (ForgeRegistry)GameRegistry.findRegistry(entry.getRegistryType()); + writeUTF8String(out, RegistryManager.ACTIVE.getName(registry).toString()); + writeVarInt(out, registry.getID(entry), 5); } /** @@ -256,16 +257,15 @@ public class ByteBufUtils { { String registryName = readUTF8String(in); int id = readVarInt(in, 5); - ResourceLocation expectedRegistryName = PersistentRegistryManager.getRegistryRegistryName(registry); + ResourceLocation expectedRegistryName = RegistryManager.ACTIVE.getName(registry); + if (!expectedRegistryName.toString().equals(registryName)) - { throw new IllegalArgumentException("Registry mismatch: " + registryName + " != " + expectedRegistryName); - } - T thing = ((FMLControlledNamespacedRegistry)registry).getRaw(id); + + T thing = ((ForgeRegistry)registry).getRaw(id); if (thing == null) - { throw new IllegalArgumentException("Unknown ID " + id + " for registry " + expectedRegistryName + " received."); - } + return thing; } @@ -283,14 +283,15 @@ public class ByteBufUtils { if (it.hasNext()) { T first = it.next(); - FMLControlledNamespacedRegistry registry = (FMLControlledNamespacedRegistry)GameRegistry.findRegistry(first.getRegistryType()); - writeUTF8String(out, PersistentRegistryManager.getRegistryRegistryName(registry).toString()); - writeVarInt(out, registry.getId(first), 5); - while (it.hasNext()) { - int id = registry.getId(it.next()); - if (id == -1) { + ForgeRegistry registry = (ForgeRegistry)GameRegistry.findRegistry(first.getRegistryType()); + writeUTF8String(out, RegistryManager.ACTIVE.getName(registry).toString()); + writeVarInt(out, registry.getID(first), 5); + + while (it.hasNext()) + { + int id = registry.getID(it.next()); + if (id == -1) throw new IllegalArgumentException("Unregistered IForgeRegistryEntry in collection " + entries + "."); - } writeVarInt(out, id, 5); } } @@ -314,7 +315,7 @@ public class ByteBufUtils { else { String registryName = readUTF8String(in); - ResourceLocation expectedRegistryName = PersistentRegistryManager.getRegistryRegistryName(registry); + ResourceLocation expectedRegistryName = RegistryManager.ACTIVE.getName(registry); if (!expectedRegistryName.toString().equals(registryName)) { throw new IllegalArgumentException("Registry mismatch: " + registryName + " != " + expectedRegistryName); @@ -324,11 +325,10 @@ public class ByteBufUtils { for (int i = 0; i < size; i++) { int id = readVarInt(in, 5); - T thing = ((FMLControlledNamespacedRegistry)registry).getRaw(id); + T thing = ((ForgeRegistry)registry).getRaw(id); if (thing == null) - { throw new IllegalArgumentException("Unknown ID " + id + " for registry " + expectedRegistryName + " received."); - } + b.add(thing); } return b.build(); diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java b/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java index 9e1fade347..6512443876 100644 --- a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java +++ b/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeClientState.java @@ -23,15 +23,21 @@ import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import java.util.List; +import java.util.Map; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; + +import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.common.network.handshake.FMLHandshakeMessage.ServerHello; import net.minecraftforge.fml.common.network.internal.FMLMessage; import net.minecraftforge.fml.common.network.internal.FMLNetworkHandler; -import net.minecraftforge.fml.common.registry.PersistentRegistryManager; import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.GameData; /** * Packet handshake sequence manager- client side (responding to remote server) @@ -114,18 +120,17 @@ enum FMLHandshakeClientState implements IHandshakeState public FMLHandshakeClientState accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg) { FMLHandshakeMessage.RegistryData pkt = (FMLHandshakeMessage.RegistryData)msg; - PersistentRegistryManager.GameDataSnapshot snap = ctx.channel().attr(NetworkDispatcher.FML_GAMEDATA_SNAPSHOT).get(); + Map snap = ctx.channel().attr(NetworkDispatcher.FML_GAMEDATA_SNAPSHOT).get(); if (snap == null) { - snap = new PersistentRegistryManager.GameDataSnapshot(); + snap = Maps.newHashMap(); ctx.channel().attr(NetworkDispatcher.FML_GAMEDATA_SNAPSHOT).set(snap); } - PersistentRegistryManager.GameDataSnapshot.Entry entry = new PersistentRegistryManager.GameDataSnapshot.Entry(); + ForgeRegistry.Snapshot entry = new ForgeRegistry.Snapshot(); entry.ids.putAll(pkt.getIdMap()); - entry.substitutions.addAll(pkt.getSubstitutions()); entry.dummied.addAll(pkt.getDummied()); - snap.entries.put(pkt.getName(), entry); + snap.put(pkt.getName(), entry); if (pkt.hasMore()) { @@ -133,15 +138,15 @@ enum FMLHandshakeClientState implements IHandshakeState return WAITINGSERVERCOMPLETE; } - ctx.channel().attr(NetworkDispatcher.FML_GAMEDATA_SNAPSHOT).remove(); + ctx.channel().attr(NetworkDispatcher.FML_GAMEDATA_SNAPSHOT).set(null); - List locallyMissing = PersistentRegistryManager.injectSnapshot(snap, false, false); + Multimap locallyMissing = GameData.injectSnapshot(snap, false, false); if (!locallyMissing.isEmpty()) { NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); dispatcher.rejectHandshake("Fatally missing blocks and items"); FMLLog.log.fatal("Failed to connect to server: there are {} missing blocks and items", locallyMissing.size()); - FMLLog.log.debug("Missing list: {}", locallyMissing); + locallyMissing.asMap().forEach((key, value) -> FMLLog.log.debug("Missing %s Entries: {}", key, value)); return ERROR; } ctx.writeAndFlush(new FMLHandshakeMessage.HandshakeAck(ordinal())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); @@ -177,7 +182,7 @@ enum FMLHandshakeClientState implements IHandshakeState { if (msg instanceof FMLHandshakeMessage.HandshakeReset) { - PersistentRegistryManager.revertToFrozen(); + GameData.revertToFrozen(); return HELLO; } return this; diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java b/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java index 57adbaf612..efac5f2d04 100644 --- a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java +++ b/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeMessage.java @@ -35,7 +35,7 @@ import net.minecraftforge.fml.common.ModContainer; import net.minecraftforge.fml.common.network.ByteBufUtils; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; -import net.minecraftforge.fml.common.registry.PersistentRegistryManager; +import net.minecraftforge.registries.ForgeRegistry; import com.google.common.base.Charsets; import com.google.common.base.Joiner; @@ -178,19 +178,17 @@ public abstract class FMLHandshakeMessage { } - public RegistryData(boolean hasMore, ResourceLocation name, PersistentRegistryManager.GameDataSnapshot.Entry entry) + public RegistryData(boolean hasMore, ResourceLocation name, ForgeRegistry.Snapshot entry) { this.hasMore = hasMore; this.name = name; this.ids = entry.ids; - this.substitutions = entry.substitutions; this.dummied = entry.dummied; } private boolean hasMore; private ResourceLocation name; private Map ids; - private Set substitutions; private Set dummied; @Override @@ -208,22 +206,13 @@ public abstract class FMLHandshakeMessage { } length = ByteBufUtils.readVarInt(buffer, 3); - substitutions = Sets.newHashSet(); - for (int i = 0; i < length; i++) - { - substitutions.add(new ResourceLocation(ByteBufUtils.readUTF8String(buffer))); - } dummied = Sets.newHashSet(); - // if the dummied list isn't present - probably an older server - if (!buffer.isReadable()) return; - length = ByteBufUtils.readVarInt(buffer, 3); for (int i = 0; i < length; i++) { dummied.add(new ResourceLocation(ByteBufUtils.readUTF8String(buffer))); } - //if (!buffer.isReadable()) return; // In case we expand } @Override @@ -239,11 +228,6 @@ public abstract class FMLHandshakeMessage { ByteBufUtils.writeVarInt(buffer, entry.getValue(), 3); } - ByteBufUtils.writeVarInt(buffer, substitutions.size(), 3); - for (ResourceLocation entry: substitutions) - { - ByteBufUtils.writeUTF8String(buffer, entry.toString()); - } ByteBufUtils.writeVarInt(buffer, dummied.size(), 3); for (ResourceLocation entry: dummied) { @@ -251,19 +235,21 @@ public abstract class FMLHandshakeMessage { } } - public Map getIdMap() + public Map getIdMap() { return ids; } - public Set getSubstitutions() + + public Set getDummied() { - return substitutions; + return dummied; } - public Set getDummied() { return dummied; } + public ResourceLocation getName() { return this.name; } + public boolean hasMore() { return this.hasMore; diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java b/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java index fa6b538a1c..d8706ccc52 100644 --- a/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java +++ b/src/main/java/net/minecraftforge/fml/common/network/handshake/FMLHandshakeServerState.java @@ -32,8 +32,9 @@ import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.common.network.internal.FMLMessage; import net.minecraftforge.fml.common.network.internal.FMLNetworkHandler; -import net.minecraftforge.fml.common.registry.PersistentRegistryManager; import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.RegistryManager; enum FMLHandshakeServerState implements IHandshakeState { @@ -82,11 +83,11 @@ enum FMLHandshakeServerState implements IHandshakeState { if (!ctx.channel().attr(NetworkDispatcher.IS_LOCAL).get()) { - PersistentRegistryManager.GameDataSnapshot snapshot = PersistentRegistryManager.takeSnapshot(); - Iterator> itr = snapshot.entries.entrySet().iterator(); + Map snapshot = RegistryManager.ACTIVE.takeSnapshot(false); + Iterator> itr = snapshot.entrySet().iterator(); while (itr.hasNext()) { - Entry e = itr.next(); + Entry e = itr.next(); ctx.writeAndFlush(new FMLHandshakeMessage.RegistryData(itr.hasNext(), e.getKey(), e.getValue())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); } } diff --git a/src/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java b/src/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java index db02ba6b65..1b0baad47b 100644 --- a/src/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java +++ b/src/main/java/net/minecraftforge/fml/common/network/handshake/NetworkDispatcher.java @@ -22,7 +22,6 @@ package net.minecraftforge.fml.common.network.handshake; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandler; -import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.embedded.EmbeddedChannel; @@ -31,7 +30,6 @@ import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import java.io.IOException; -import java.lang.reflect.Field; import java.net.SocketAddress; import java.nio.channels.ClosedChannelException; import java.util.Collections; @@ -53,6 +51,7 @@ import net.minecraft.network.play.server.SPacketJoinGame; import net.minecraft.network.play.server.SPacketCustomPayload; import net.minecraft.network.play.server.SPacketDisconnect; import net.minecraft.server.management.PlayerList; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.TextComponentString; import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.MinecraftForge; @@ -66,8 +65,8 @@ import net.minecraftforge.fml.common.network.PacketLoggingHandler; import net.minecraftforge.fml.common.network.internal.FMLMessage; import net.minecraftforge.fml.common.network.internal.FMLNetworkHandler; import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; -import net.minecraftforge.fml.common.registry.PersistentRegistryManager; import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.registries.ForgeRegistry; import org.apache.logging.log4j.Level; @@ -103,7 +102,7 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler> im public static final AttributeKey FML_DISPATCHER = AttributeKey.valueOf("fml:dispatcher"); public static final AttributeKey IS_LOCAL = AttributeKey.valueOf("fml:isLocal"); - public static final AttributeKey FML_GAMEDATA_SNAPSHOT = AttributeKey.valueOf("fml:gameDataSnapshot"); + public static final AttributeKey> FML_GAMEDATA_SNAPSHOT = AttributeKey.valueOf("fml:gameDataSnapshot"); public final NetworkManager manager; private final PlayerList scm; private EntityPlayerMP player; @@ -599,11 +598,11 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler> im //they do not hold references to the world and causes it to leak. private void cleanAttributes(ChannelHandlerContext ctx) { - ctx.channel().attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).remove(); - ctx.channel().attr(NetworkRegistry.NET_HANDLER).remove(); - ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).remove(); - this.handshakeChannel.attr(FML_DISPATCHER).remove(); - this.manager.channel().attr(FML_DISPATCHER).remove(); + ctx.channel().attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(null); + ctx.channel().attr(NetworkRegistry.NET_HANDLER).set(null); + ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).set(null); + this.handshakeChannel.attr(FML_DISPATCHER).set(null); + this.manager.channel().attr(FML_DISPATCHER).set(null); } public void setOverrideDimension(int overrideDim) { diff --git a/src/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java b/src/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java index a454734e28..6eab2f6030 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java +++ b/src/main/java/net/minecraftforge/fml/common/registry/EntityEntry.java @@ -27,7 +27,7 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityList.EntityEggInfo; import net.minecraft.world.World; -import net.minecraftforge.fml.common.registry.IForgeRegistryEntry.Impl; +import net.minecraftforge.registries.IForgeRegistryEntry.Impl; public class EntityEntry extends Impl { diff --git a/src/main/java/net/minecraftforge/fml/common/registry/FMLControlledNamespacedRegistry.java b/src/main/java/net/minecraftforge/fml/common/registry/FMLControlledNamespacedRegistry.java deleted file mode 100644 index fa60b10623..0000000000 --- a/src/main/java/net/minecraftforge/fml/common/registry/FMLControlledNamespacedRegistry.java +++ /dev/null @@ -1,950 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.registry; - -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.google.common.base.Joiner; -import com.google.common.base.Preconditions; -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import com.google.common.collect.Iterators; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import net.minecraftforge.event.RegistryEvent; -import org.apache.commons.lang3.Validate; -import org.apache.logging.log4j.Level; - -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.registry.RegistryNamespacedDefaultedByKey; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.functions.GenericIterableFactory; -import net.minecraftforge.fml.common.registry.RegistryDelegate.Delegate; -import net.minecraftforge.fml.relauncher.ReflectionHelper; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public class FMLControlledNamespacedRegistry> extends RegistryNamespacedDefaultedByKey implements IForgeRegistry -{ - public static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("fml.debugRegistryEntries", "false")); - private final Class superType; - private final boolean isDelegated; - @Nullable - private ResourceLocation optionalDefaultKey; - @Nullable - private I optionalDefaultObject; - private int maxId; - private int minId; - /** - * Aliases are resource location to resource location pointers, allowing for alternative names to be supplied - * pointing at the same thing. They are used to allow programmatic migration of an ID. - */ - private final Map aliases = Maps.newHashMap(); - /** - * Persistent substitutions are the mechanism to allow mods to override specific behaviours with new behaviours. - */ - private final BiMap persistentSubstitutions = HashBiMap.create(); - /** - * Substitution originals - these are the originals that are being substituted - */ - private final BiMap substitutionOriginals = HashBiMap.create(); - /** - * This is the current active substitution set for a particular world. It will change as worlds come and go. - */ - private final BiMap activeSubstitutions = HashBiMap.create(); - /** - * The list of IDs blocked for this world. IDs will never be allocated in this set. - */ - private final Set blockedIds = Sets.newHashSet(); - - private final Set dummiedLocations = Sets.newHashSet(); - - private final BitSet availabilityMap; - - private final Map slaves = Maps.newHashMap(); - @Nullable - private final AddCallback addCallback; - @Nullable - private final ClearCallback clearCallback; - @Nullable - private final CreateCallback createCallback; - @Nullable - private final SubstitutionCallback substitutionCallback; - /** - * If true, this registry will persist in the save folder and be reloaded when the world is loaded. - * This should only be true if the save format includes this registry entries in ID format. - */ - private final boolean saveToDisc; - - FMLControlledNamespacedRegistry(@Nullable ResourceLocation defaultKey, int minIdValue, int maxIdValue, Class type, BiMap> registries, @Nullable AddCallback addCallback, @Nullable ClearCallback clearCallback, @Nullable CreateCallback createCallback, @Nullable SubstitutionCallback substitutionCallback, boolean saveToDisc) - { - super(defaultKey); - this.superType = type; - this.optionalDefaultKey = defaultKey; - this.minId = minIdValue; - this.maxId = maxIdValue; - this.availabilityMap = new BitSet(Math.min(maxIdValue + 1, 0xFFFF)); //No need to pre-allocate large sets, it will resize when we need it. - this.isDelegated = IForgeRegistryEntry.Impl.class.isAssignableFrom(type); - this.addCallback = addCallback; - this.clearCallback = clearCallback; - this.createCallback = createCallback; - this.substitutionCallback = substitutionCallback; - if (createCallback != null) - { - createCallback.onCreate(slaves, registries); - } - this.saveToDisc = saveToDisc; - } - - void validateContent(ResourceLocation registryName) - { - try - { - ReflectionHelper.findMethod(BitSet.class, "trimToSize", null).invoke(this.availabilityMap); - } - catch (Exception e) - { - //We don't care... Just a micro-optimization - } - - for (I obj : typeSafeIterable()) - { - int id = getId(obj); - ResourceLocation name = getNameForObject(obj); - boolean isSubstituted = activeSubstitutions.containsKey(name); - - // name lookup failed -> obj is not in the obj<->name map - if (name == null) - { - throw new IllegalStateException(String.format("Registry entry for %s %s, id %d, doesn't yield a name.", registryName, obj, id)); - } - // id lookup failed -> obj is not in the obj<->id map - if (!isSubstituted && id < 0) - { - throw new IllegalStateException(String.format("Registry entry for %s %s, name %s, doesn't yield an id.", registryName, obj, name)); - } - // id is too high - if (id > maxId) - { - throw new IllegalStateException(String.format("Registry entry for %s %s, name %s uses the too large id %d.", registryName, obj, name, id)); - } - // the rest of the tests don't really work for substituted items or blocks - if (isSubstituted) - { - continue; - } - // id -> obj lookup is inconsistent - if (getRaw(id) != obj) - { - throw new IllegalStateException(String.format("Registry entry for id %d, name %s, doesn't yield the expected %s %s.", id, name, registryName, obj)); - } - // name -> obj lookup is inconsistent - if (getRaw(name) != obj) - { - throw new IllegalStateException(String.format("Registry entry for name %s, id %d, doesn't yield the expected %s %s.", name, id, registryName, obj)); - } - // name -> id lookup is inconsistent - if (getId(name) != id) - { - throw new IllegalStateException(String.format("Registry entry for name %s doesn't yield the expected id %d.", name, id)); - } -/* - // entry is blocked, thus should be empty - if (blockedIds.contains(id)) - { - throw new IllegalStateException(String.format("Registry entry for %s %s, id %d, name %s, marked as dangling.", registryName, obj, id, name)); - } -*/ - } - - } - - void set(FMLControlledNamespacedRegistry otherRegistry) - { - if (this.superType != otherRegistry.superType) - { - throw new IllegalArgumentException("incompatible registry"); - } - final Map slaves = Maps.newHashMap(this.slaves); - slaves.put(PersistentRegistryManager.SUBSTITUTION_ORIGINALS, substitutionOriginals); - if (this.clearCallback!=null) this.clearCallback.onClear(this, slaves); - this.optionalDefaultKey = otherRegistry.optionalDefaultKey; - this.maxId = otherRegistry.maxId; - this.minId = otherRegistry.minId; - this.aliases.clear(); - this.aliases.putAll(otherRegistry.aliases); - this.persistentSubstitutions.clear(); - this.persistentSubstitutions.putAll(otherRegistry.getPersistentSubstitutions()); - this.activeSubstitutions.clear(); - this.dummiedLocations.clear(); - this.dummiedLocations.addAll(otherRegistry.dummiedLocations); - - underlyingIntegerMap.clear(); - registryObjects.clear(); - - for (I thing : otherRegistry.typeSafeIterable()) - { - addObjectRaw(otherRegistry.getId(thing), otherRegistry.getNameForObject(thing), thing); - } - for (ResourceLocation resloc : otherRegistry.activeSubstitutions.keySet()) - { - activateSubstitution(resloc); - } - this.substitutionOriginals.clear(); - this.substitutionOriginals.putAll(otherRegistry.substitutionOriginals); - } - - // public api - - /** - * Add an object to the registry, trying to use the specified id. - * This is required, to re-route vanilla block and item registration through to - * the {@link #add} method. - * - * @deprecated register through {@link GameRegistry} instead. - */ - @Override - @Deprecated - public void register(int id, @Nonnull ResourceLocation name, @Nonnull I thing) - { - add(id, name, thing); - } - - /** - * DANGEROUS! EVIL! DO NOT USE! - * - * @deprecated register through {@link GameRegistry} instead. - */ - @Override - @Deprecated - public void putObject(@Nonnull ResourceLocation name, @Nonnull I thing) - { - Preconditions.checkNotNull(name, "Can't use a null-name for the registry."); - Preconditions.checkNotNull(thing, "Can't add null-object to the registry."); - - ResourceLocation existingName = getNameForObject(thing); - - if (existingName == null) - { - FMLLog.bigWarning("Ignoring putObject({}, {}), not resolvable", name, thing); - } - else if (existingName.equals(name)) - { - FMLLog.bigWarning("Ignoring putObject({}, {}), already added", name, thing); - } - else - { - FMLLog.bigWarning("Ignoring putObject({}, {}), adding alias to {} instead", name, thing, existingName); - addAlias(name, existingName); - } - } - - /** - * Fetch the object identified by the specified name or the default object. - *

- * For blocks the default object is the air block, for items it's null. - * - * @param name Unique name identifying the object. - * @return Registered object of the default object if it wasn't found- - */ - @Nullable - @Override - public I getObject(ResourceLocation name) - { - I object = getRaw(name); - return object == null ? this.optionalDefaultObject : object; - } - - /** - * Fetch the object identified by the specified id or the default object. - *

- * For blocks the default object is the air block, for items it's null. - * - * @param id ID identifying the object. - * @return Registered object of the default object if it wasn't found- - */ - @Nullable - @Override - public I getObjectById(int id) - { - I object = getRaw(id); - return object == null ? this.optionalDefaultObject : object; - } - - /** - * Get the id for the specified object. - *

- * Don't hold onto the id across the world, it's being dynamically re-mapped as needed. - *

- * Usually the name should be used instead of the id, if using the Block/Item object itself is - * not suitable for the task. - * - * @param thing Block/Item object. - * @return Block/Item id or -1 if it wasn't found. - */ - public int getId(@Nullable I thing) - { - return getIDForObjectBypass(thing); - } - - /** - * Get the object identified by the specified id. - * - * @param id Block/Item id. - * @return Block/Item object or null if it wasn't found. - */ - @Nullable - public I getRaw(int id) - { - return super.getObjectById(id); - } - - /** - * Get the object identified by the specified name. - * - * @param name Block/Item name. - * @return Block/Item object or null if it wasn't found. - */ - @Nullable - private I getRaw(ResourceLocation name) - { - I ret = super.getObject(name); - - if (ret == null) // no match, try aliases recursively - { - name = aliases.get(name); - - if (name != null) - { - return getRaw(name); - } - } - - return ret; - } - - /** - * Determine if the registry has an entry for the specified name. - *

- * Aliased names will be resolved as well. - * - * @param name Object name to check. - * @return true if a matching entry was found. - */ - @Override - public boolean containsKey(@Nonnull ResourceLocation name) - { - boolean ret = super.containsKey(name); - - if (!ret) // no match, try aliases recursively - { - name = aliases.get(name); - - if (name != null) - { - return containsKey(name); - } - } - - return ret; - } - - /** - * Get the id for the specified object. - *

- * Don't hold onto the id across the world, it's being dynamically re-mapped as needed. - *

- * Usually the name should be used instead of the id, if using the Block/Item object itself is - * not suitable for the task. - * - * @param itemName Block/Item registry name. - * @return Block/Item id or -1 if it wasn't found. - */ - public int getId(ResourceLocation itemName) - { - I obj = getRaw(itemName); - if (obj == null) - { - return -1; - } - - return getId(obj); - } - - /* - * This iterator is used by FML to visit the actual block sets, it should use the super.iterator method instead - * Compare #iterator() - */ - public Iterable typeSafeIterable() - { - return GenericIterableFactory.newCastingIterable(super.iterator(), superType); - } - - // internal - - public void serializeIds(Map idMapping) // for saving - { - for (I thing : this.typeSafeIterable()) - { - idMapping.put(getNameForObject(thing), getId(thing)); - } - } - - public void serializeAliases(Map map) - { - map.putAll(this.aliases); - } - - public void serializeSubstitutions(Set set) - { - set.addAll(activeSubstitutions.keySet()); - } - - public void serializeDummied(Set set) { set.addAll(this.dummiedLocations); } - public boolean isDummied(ResourceLocation key){ return this.dummiedLocations.contains(key); } - - - /** - * Add the specified object to the registry. - * - * @param id ID to use if available, auto-assigned otherwise. - * @param name Name to use, prefixed by the mod id. - * @param thing Object to add. - * @return ID eventually allocated. - */ - int add(int id, @Nonnull ResourceLocation name, @Nonnull I thing) - { - Preconditions.checkNotNull(name, "Can't use a null-name for the registry, object %s.", thing); - Preconditions.checkNotNull(thing, "Can't add null-object to the registry, name %s.", name); - - if (optionalDefaultKey != null && optionalDefaultKey.equals(name) && this.optionalDefaultObject == null) - { - this.optionalDefaultObject = thing; - } - if (getPersistentSubstitutions().containsValue(thing)) - { - throw new IllegalArgumentException(String.format("The object %s (%s) cannot be added to the registry. It is already being used as a substitute for %s", thing.getClass(), name, getPersistentSubstitutions().inverse().get(thing))); - } - int idToUse = id; - if (idToUse < 0 || availabilityMap.get(idToUse)) - { - idToUse = availabilityMap.nextClearBit(minId); - } - if (idToUse > maxId) - { - throw new RuntimeException(String.format("Invalid id %d - maximum id range exceeded.", idToUse)); - } - - if (getRaw(name) == thing) // already registered, return prev registration's id - { - FMLLog.bigWarning("The object {} has been registered twice for the same name {}.", thing, name); - return getId(thing); - } - if (getRaw(name) != null) // duplicate name - { - throw new IllegalArgumentException(String.format("The name %s has been registered twice, for %s and %s.", name, getRaw(name), thing)); - } - if (getId(thing) >= 0) // duplicate object - but only if it's not being substituted - { - int foundId = getId(thing); - I otherThing = getRaw(foundId); - throw new IllegalArgumentException(String.format("The object %s{%x} has been registered twice, using the names %s and %s. (Other object at this id is %s{%x})", thing, System.identityHashCode(thing), getNameForObject(thing), name, otherThing, System.identityHashCode(otherThing))); - } - if (PersistentRegistryManager.isFrozen(this)) - { - FMLLog.bigWarning("The object {} (name {}) is being added too late.", thing, name); - } - - if (activeSubstitutions.containsKey(name)) - { - I oldThing = thing; - thing = activeSubstitutions.get(name); - if (DEBUG) - { - FMLLog.log.debug("Active substitution: {} {}@{} -> {}@{}", name, oldThing.getClass().getName(), System.identityHashCode(oldThing), thing.getClass().getName(), System.identityHashCode(thing)); - } - } - - - addObjectRaw(idToUse, name, thing); - if (isDelegated) - { - getExistingDelegate(thing).setName(name); - } - - if (this.dummiedLocations.remove(name) && DEBUG) - { - FMLLog.log.debug("Registry Dummy Remove: {}", name); - } - - if (DEBUG) - { - FMLLog.log.trace("Registry add: {} {} {} (req. id {})", name, idToUse, thing, id); - } - return idToUse; - } - - void markDummy(ResourceLocation rl, Integer id, I thing) - { - if (DEBUG) - { - FMLLog.log.trace("Registry Dummy Add: {} {} -> {}", rl, id, thing); - } - this.dummiedLocations.add(rl); - this.addObjectRaw(id, rl, thing); - } - - void addAlias(ResourceLocation from, ResourceLocation to) - { - aliases.put(from, to); - if (DEBUG) - { - FMLLog.log.trace("Registry alias: {} -> {}", from, to); - } - } - - Map getEntriesNotIn(FMLControlledNamespacedRegistry registry) - { - Map ret = new HashMap(); - - for (I thing : this.typeSafeIterable()) - { - if (!registry.inverseObjectRegistry.containsKey(thing)) - { - if (!registry.activeSubstitutions.containsKey(getNameForObject(thing))) - { - ret.put(getNameForObject(thing), getId(thing)); - } - } - } - - return ret; - } - - void dump(ResourceLocation registryName) - { - if (!DEBUG) - { - return; - } - - List ids = new ArrayList(); - - for (I thing : this.typeSafeIterable()) - { - ids.add(getId(thing)); - } - - // sort by id - Collections.sort(ids); - FMLLog.log.trace("Registry Name : {}", registryName); - for (int id : ids) - { - I thing = getRaw(id); - FMLLog.log.trace("Registry: {} {} {}", id, getNameForObject(thing), thing); - } - } - - /** - * Version of addObject not using the API restricting overrides. - */ - private void addObjectRaw(int id, ResourceLocation name, I thing) - { - Preconditions.checkNotNull(name, "The name to be added to the registry is null. This can only happen with a corrupted registry state. Reflection/ASM hackery? Registry bug?"); - Preconditions.checkNotNull(thing, "The object to be added to the registry is null. This can only happen with a corrupted registry state. Reflection/ASM hackery? Registry bug?"); - Preconditions.checkState(superType.isInstance(thing), "The object to be added to the registry is not of the right type. Reflection/ASM hackery? Registry bug?"); - - underlyingIntegerMap.put(thing, id); // obj <-> id - super.putObject(name, thing); // name <-> obj - availabilityMap.set(id); - if (addCallback != null) - { - addCallback.onAdd(thing, id, slaves); - } - } - - @Nullable - public I getDefaultValue() - { - return optionalDefaultObject; - } - - public RegistryDelegate getDelegate(I thing, Class clazz) - { - return new RegistryDelegate.Delegate(thing, clazz); - } - - @SuppressWarnings("unchecked") - @Nonnull - private Delegate getExistingDelegate(I thing) - { - if (isDelegated) - { - return (Delegate)((IForgeRegistryEntry.Impl)thing).delegate; - } - else - { - throw new IllegalStateException("Tried to get existing delegate from registry that is not delegated."); - } - } - - @Nullable - I activateSubstitution(ResourceLocation nameToReplace) - { - if (getPersistentSubstitutions().containsKey(nameToReplace)) - { - I original = getRaw(nameToReplace); - I sub = getPersistentSubstitutions().get(nameToReplace); - getExistingDelegate(original).changeReference(sub); - activeSubstitutions.put(nameToReplace, sub); - int id = getIDForObjectBypass(original); - // force the new object into the existing map - addObjectRaw(id, nameToReplace, sub); - // Track the original in the substitution originals collection - substitutionOriginals.put(nameToReplace, original); - if (substitutionCallback!=null) substitutionCallback.onSubstituteActivated(slaves, original, sub, nameToReplace); - return original; - } - return null; - } - - void addSubstitutionAlias(String modId, ResourceLocation nameToReplace, I replacement) throws ExistingSubstitutionException - { - if (getPersistentSubstitutions().containsKey(nameToReplace) || getPersistentSubstitutions().containsValue(replacement)) - { - FMLLog.log.fatal("The substitution of {} has already occurred. You cannot duplicate substitutions", nameToReplace); - throw new ExistingSubstitutionException(nameToReplace, replacement); - } - I original = getRaw(nameToReplace); - if (original == null) - { - throw new NullPointerException("The replacement target is not present. This won't work"); - } - if (!original.getClass().isAssignableFrom(replacement.getClass())) - { - FMLLog.log.fatal("The substitute {} for {} (type {}) is type incompatible. This won't work", replacement.getClass().getName(), nameToReplace, original.getClass().getName()); - throw new IncompatibleSubstitutionException(nameToReplace, replacement, original); - } - int existingId = getId(replacement); - if (existingId != -1) - { - FMLLog.log.fatal("The substitute {} for {} is registered into the game independently. This won't work", replacement.getClass().getName(), nameToReplace); - throw new IllegalArgumentException("The object substitution is already registered. This won't work"); - } - FMLLog.log.debug("Adding substitution {} with {} (name {})", original, replacement, nameToReplace); - getPersistentSubstitutions().put(nameToReplace, replacement); - } - - BiMap getPersistentSubstitutions() - { - return persistentSubstitutions; - } - - @Override - public void validateKey() - { - if (this.optionalDefaultKey != null) - { - Validate.notNull(this.optionalDefaultObject); - } - } - - /* - * This iterator is used by some regular MC methods to visit all blocks, we need to include substitutions - * Compare #typeSafeIterable() - */ - @Nonnull - @Override - public Iterator iterator() - { - return Iterators.concat(super.iterator(), getPersistentSubstitutions().values().iterator()); - } - - - FMLControlledNamespacedRegistry makeShallowCopy(BiMap> registries) - { - return new FMLControlledNamespacedRegistry(optionalDefaultKey, minId, maxId, superType, registries, addCallback, clearCallback, createCallback, substitutionCallback, saveToDisc); - } - - void resetSubstitutionDelegates() - { - if (!isDelegated) - { - return; - } - for (I obj : typeSafeIterable()) - { - Delegate delegate = getExistingDelegate(obj); - delegate.changeReference(obj); - } - } - - @SuppressWarnings("unchecked") - public > FMLControlledNamespacedRegistry asType(Class type) - { - return (FMLControlledNamespacedRegistry)this; - } - - public void serializeBlockList(Set blocked) - { - blocked.addAll(this.blockedIds); - } - - public Set getActiveSubstitutions() - { - return activeSubstitutions.keySet(); - } - - public void loadAliases(Map aliases) - { - for (Map.Entry alias : aliases.entrySet()) - { - addAlias(alias.getKey(), alias.getValue()); - } - } - - public void loadSubstitutions(Set substitutions) - { - for (ResourceLocation rl : substitutions) - { - activateSubstitution(rl); - } - } - - public void loadBlocked(Set blocked) - { - for (Integer id : blocked) - { - blockedIds.add(id); - availabilityMap.set(id); - } - } - - public void loadDummied(Set dummied) - { - if (DEBUG && dummied.size() > 0) - { - FMLLog.log.debug("Registry Dummy Load: [{}]", Joiner.on(", ").join(dummied)); - } - this.dummiedLocations.addAll(dummied); - } - - public void loadIds(Map ids, Map missingIds, Map remappedIds, FMLControlledNamespacedRegistry currentRegistry, ResourceLocation registryName) - { - for (Map.Entry entry : ids.entrySet()) - { - ResourceLocation itemName = entry.getKey(); - int newId = entry.getValue(); - int currId = currentRegistry.getId(itemName); - - if (currId == -1) - { - FMLLog.log.info("Found a missing id from the world {}", itemName); - missingIds.put(itemName, newId); - continue; // no block/item -> nothing to add - } - else if (currId != newId) - { - FMLLog.log.debug("Fixed {} id mismatch {}: {} (init) -> {} (map).", registryName, itemName, currId, newId); - remappedIds.put(itemName, new Integer[] {currId, newId}); - } - I obj = currentRegistry.getRaw(itemName); - Preconditions.checkState(obj != null, "objectKey has an ID but no object. Reflection/ASM hackery? Registry bug?"); - I sub = obj; - // If we have an object in the originals set, we use that for initial adding - substitute activation will re-add the substitute if necessary later - if (currentRegistry.substitutionOriginals.containsKey(itemName)) - { - obj = currentRegistry.substitutionOriginals.get(itemName); - } - add(newId, itemName, obj); - if (currentRegistry.substitutionOriginals.containsKey(itemName) && substitutionCallback != null) - { - substitutionCallback.onSubstituteActivated(slaves, sub, obj, itemName); - } - } - } - - public void blockId(int id) - { - blockedIds.add(id); - } - - public void notifyCallbacks() - { - if (addCallback == null) - return; - - for (I i : this.underlyingIntegerMap) - { - addCallback.onAdd(i, this.underlyingIntegerMap.add(i), slaves); - } - } - - @Override - @Nullable - public ResourceLocation getNameForObject(@Nonnull I p_177774_1_) - { - ResourceLocation rl = super.getNameForObjectBypass(p_177774_1_); - if (rl == null) - { - rl = activeSubstitutions.inverse().get(p_177774_1_); - } - return rl; - } - - @Override - public Class getRegistrySuperType() - { - return superType; - } - - - // IForgeRegistry: Modders should only interfaces with these methods - - @Override - public void register(@Nonnull I value) - { - ResourceLocation key = value.getRegistryName(); - if (key == null) - { - FMLLog.log.fatal("Attempted to register a entry with a null name: {}", value); - throw new NullPointerException(String.format("Attempted to register a entry with a null name: %s", value)); - } - add(-1, key, value); - } - - @Override - public void registerAll(I... values) - { - for (I value: values) - { - register(value); - } - } - @Override - public boolean containsValue(@Nonnull I value) - { - return getKey(value) != null; - } - - @Override - public I getValue(ResourceLocation key) - { - return getObject(key); - } - - @Override - @Nullable - public ResourceLocation getKey(I value) - { - return getNameForObject(value); - } - - @Nonnull - @Override //Bouncer for OBF, as the super class's function is NotchCode and gets obfed. This plus the SRG lines prevents a AbstractMethodException - public Set getKeys() - { - return super.getKeys(); - } - - @Override - @Nonnull - public List getValues() - { - return Lists.newArrayList(this.iterator()); - } - - @Override - @Nonnull - public Set> getEntries() - { - return Sets.newHashSet(new Iterator>() - { - Iterator itr = FMLControlledNamespacedRegistry.this.iterator(); - - @Override - public boolean hasNext() - { - return itr.hasNext(); - } - - @Override - public Entry next() - { - final I value = itr.next(); - final ResourceLocation key = FMLControlledNamespacedRegistry.this.getKey(value); - return new Entry() - { - @Override - public ResourceLocation getKey() - { - return key; - } - - @Override - public I getValue() - { - return value; - } - - @Override - public I setValue(I value) - { - throw new UnsupportedOperationException("Setting the value in an iterator is not allowed"); - } - }; - } - - @Override - public void remove() - { - throw new UnsupportedOperationException("This is a READ ONLY view of this registry."); - } - }); - } - - @SuppressWarnings("unchecked") - @Override - public T getSlaveMap(ResourceLocation slaveMapName, Class type) - { - return (T)slaves.get(slaveMapName); - } - - RegistryEvent.Register buildRegistryRegisterEvent(ResourceLocation location) - { - return new RegistryEvent.Register(location, this); - } - - public boolean shouldSaveToDisc() - { - return this.saveToDisc; - } - -} diff --git a/src/main/java/net/minecraftforge/fml/common/registry/FinalFieldHelper.java b/src/main/java/net/minecraftforge/fml/common/registry/FinalFieldHelper.java deleted file mode 100644 index dab7c2347f..0000000000 --- a/src/main/java/net/minecraftforge/fml/common/registry/FinalFieldHelper.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.registry; - -import com.google.common.base.Throwables; - -import javax.annotation.Nullable; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -/** - * Helper class for setting final fields. - */ -class FinalFieldHelper -{ - private static Field modifiersField; - private static Object reflectionFactory; - private static Method newFieldAccessor; - private static Method fieldAccessorSet; - static Field makeWritable(Field f) throws Exception - { - if (modifiersField == null) - { - Method getReflectionFactory = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("getReflectionFactory"); - reflectionFactory = getReflectionFactory.invoke(null); - newFieldAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newFieldAccessor", Field.class, boolean.class); - fieldAccessorSet = Class.forName("sun.reflect.FieldAccessor").getDeclaredMethod("set", Object.class, Object.class); - modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - } - modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL); - return f; - } - - - static void setField(Field field, @Nullable Object instance, Object thing) throws Exception - { - Object fieldAccessor = newFieldAccessor.invoke(reflectionFactory, field, false); - fieldAccessorSet.invoke(fieldAccessor, instance, thing); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java b/src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java index ac29177c65..6da0d4fcd8 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java +++ b/src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java @@ -29,6 +29,8 @@ import net.minecraft.potion.PotionType; import net.minecraft.util.SoundEvent; import net.minecraft.world.biome.Biome; import net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession; +import net.minecraftforge.registries.GameData; +import net.minecraftforge.registries.IForgeRegistry; /** * A class that exposes static references to all vanilla and Forge registries. @@ -56,7 +58,7 @@ public class ForgeRegistries */ private static void init() { - GameData.getMain(); + GameData.init(); VillagerRegistry.instance(); Bootstrap.register(); } diff --git a/src/main/java/net/minecraftforge/fml/common/registry/GameData.java b/src/main/java/net/minecraftforge/fml/common/registry/GameData.java deleted file mode 100644 index ff3210189b..0000000000 --- a/src/main/java/net/minecraftforge/fml/common/registry/GameData.java +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.registry; - -import java.lang.reflect.Field; -import java.util.Map; - -import com.google.common.base.Throwables; -import com.google.common.collect.HashBiMap; -import net.minecraft.block.Block; -import net.minecraft.block.state.IBlockState; -import net.minecraft.enchantment.Enchantment; -import net.minecraft.entity.EntityList; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.crafting.IRecipe; -import net.minecraft.potion.Potion; -import net.minecraft.potion.PotionType; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ObjectIntIdentityMap; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.SoundEvent; -import net.minecraft.world.biome.Biome; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.Loader; - -import com.google.common.collect.BiMap; -import net.minecraftforge.fml.relauncher.ReflectionHelper; -import org.apache.logging.log4j.Level; - -import static net.minecraftforge.fml.common.registry.PersistentRegistryManager.*; - -public class GameData -{ - private static final int MIN_BLOCK_ID = 0; - private static final int MAX_BLOCK_ID = 4095; - private static final int MIN_ITEM_ID = 4096; - private static final int MAX_ITEM_ID = 31999; - private static final int MIN_POTION_ID = 0; // 0-~31 are vanilla, forge start at 32 - private static final int MAX_POTION_ID = 255; // SPacketEntityEffect sends bytes, we can only use 255 - private static final int MIN_BIOME_ID = 0; - private static final int MAX_BIOME_ID = 255; // Maximum number in a byte in the chunk - private static final int MIN_SOUND_ID = 0; // Varint - private static final int MAX_SOUND_ID = Integer.MAX_VALUE >> 5; // Varint (SPacketSoundEffect) - private static final int MIN_POTIONTYPE_ID = 0; // Int - private static final int MAX_POTIONTYPE_ID = Integer.MAX_VALUE >> 5; // Int (SPacketEffect) - private static final int MIN_ENCHANTMENT_ID = 0; // Int - private static final int MAX_ENCHANTMENT_ID = Short.MAX_VALUE - 1; // Short - serialized as a short in ItemStack NBTs. - private static final int MIN_ENTITY_ID = 0; - private static final int MAX_ENTITY_ID = Integer.MAX_VALUE >> 5; // Varint (SPacketSpawnMob) - private static final int MIN_RECIPE_ID = 0; - private static final int MAX_RECIPE_ID = Integer.MAX_VALUE >> 5; // Varint CPacketRecipeInfo/SPacketRecipeBook - - private static final ResourceLocation BLOCK_TO_ITEM = new ResourceLocation("minecraft:blocktoitemmap"); - private static final ResourceLocation BLOCKSTATE_TO_ID = new ResourceLocation("minecraft:blockstatetoid"); - - private static final GameData mainData = new GameData(); - - private static Field blockField; - - public GameData() - { - iBlockRegistry = (FMLControlledNamespacedRegistry) makeRegistry(BLOCKS, Block.class, MIN_BLOCK_ID, MAX_BLOCK_ID).addCallback(BlockCallbacks.INSTANCE).enableDelegates().setDefaultKey(new ResourceLocation("air")).create(); - iItemRegistry = (FMLControlledNamespacedRegistry) makeRegistry(ITEMS, Item.class, MIN_ITEM_ID, MAX_ITEM_ID).addCallback(ItemCallbacks.INSTANCE).enableDelegates().create(); - iPotionRegistry = (FMLControlledNamespacedRegistry) makeRegistry(POTIONS, Potion.class, MIN_POTION_ID, MAX_POTION_ID).addCallback(PotionCallbacks.INSTANCE).create(); - iBiomeRegistry = (FMLControlledNamespacedRegistry) makeRegistry(BIOMES, Biome.class, MIN_BIOME_ID, MAX_BIOME_ID).addCallback(BiomeCallbacks.INSTANCE).create(); - iSoundEventRegistry = (FMLControlledNamespacedRegistry) makeRegistry(SOUNDEVENTS, SoundEvent.class, MIN_SOUND_ID, MAX_SOUND_ID).create(); - iPotionTypeRegistry = (FMLControlledNamespacedRegistry) makeRegistry(POTIONTYPES, PotionType.class, MIN_POTIONTYPE_ID, MAX_POTIONTYPE_ID).setDefaultKey(new ResourceLocation("water")).create(); - iEnchantmentRegistry = (FMLControlledNamespacedRegistry)makeRegistry(ENCHANTMENTS, Enchantment.class, MIN_ENCHANTMENT_ID, MAX_ENCHANTMENT_ID).create(); - iEntityRegistry = (FMLControlledNamespacedRegistry)makeRegistry(ENTITIES, EntityEntry.class, MIN_ENTITY_ID, MAX_ENTITY_ID).addCallback(EntityCallbacks.INSTANCE).create(); - iRecipeRegistry = (FMLControlledNamespacedRegistry) makeRegistry(RECIPES, IRecipe.class, MIN_RECIPE_ID, MAX_RECIPE_ID).disableSaving().create(); - - try - { - blockField = FinalFieldHelper.makeWritable(ReflectionHelper.findField(ItemBlock.class, "block", "field_150939" + "_a")); - } - catch (Exception e) - { - FMLLog.log.fatal("Cannot access the 'block' field from ItemBlock, this is fatal!", e); - throw Throwables.propagate(e); - } - - iTileEntityRegistry = new LegacyNamespacedRegistry>(); - } - - private > RegistryBuilder makeRegistry(ResourceLocation name, Class type, int min, int max) - { - return new RegistryBuilder().setName(name).setType(type).setIDRange(min, max); - } - // internal registry objects - private final FMLControlledNamespacedRegistry iBlockRegistry; - private final FMLControlledNamespacedRegistry iItemRegistry; - private final FMLControlledNamespacedRegistry iPotionRegistry; - private final FMLControlledNamespacedRegistry iBiomeRegistry; - private final FMLControlledNamespacedRegistry iSoundEventRegistry; - private final FMLControlledNamespacedRegistry iPotionTypeRegistry; - private final FMLControlledNamespacedRegistry iEnchantmentRegistry; - private final FMLControlledNamespacedRegistry iEntityRegistry; - - //TODO: ? These are never used by ID, so they don't need to be full registries/persisted. - //Need cpw to decide how we want to go about this as they are generic registries that - //don't follow the same patterns as the other ones. - private final LegacyNamespacedRegistry> iTileEntityRegistry; - - //TODO: This is not a recipe that is serilized to disc by ID, so we need to skip over any saving/loading from disc - private final FMLControlledNamespacedRegistry iRecipeRegistry; - - /** INTERNAL ONLY */ - @Deprecated - public static FMLControlledNamespacedRegistry getBlockRegistry() - { - return getMain().iBlockRegistry; - } - - /** INTERNAL ONLY */ - @Deprecated - public static FMLControlledNamespacedRegistry getItemRegistry() - { - return getMain().iItemRegistry; - } - - /** INTERNAL ONLY */ - @Deprecated - public static FMLControlledNamespacedRegistry getPotionRegistry() { - return getMain().iPotionRegistry; - } - - /** INTERNAL ONLY */ - @Deprecated - public static FMLControlledNamespacedRegistry getBiomeRegistry() { return getMain().iBiomeRegistry; } - - /** INTERNAL ONLY */ - @Deprecated - public static FMLControlledNamespacedRegistry getSoundEventRegistry() { return getMain().iSoundEventRegistry; } - - /** INTERNAL ONLY */ - @Deprecated - public static FMLControlledNamespacedRegistry getPotionTypesRegistry() { return getMain().iPotionTypeRegistry; } - - /** INTERNAL ONLY */ - @Deprecated - public static FMLControlledNamespacedRegistry getEnchantmentRegistry() { return getMain().iEnchantmentRegistry; } - - /** INTERNAL ONLY */ - @Deprecated - public static LegacyNamespacedRegistry> getTileEntityRegistry() { return getMain().iTileEntityRegistry; } - - /** INTERNAL ONLY */ - @Deprecated - public static FMLControlledNamespacedRegistry getEntityRegistry() { return getMain().iEntityRegistry; } - - /** INTERNAL ONLY */ - @Deprecated - public static FMLControlledNamespacedRegistry getRecipeRegistry() { return getMain().iRecipeRegistry; } - - protected static GameData getMain() - { - return mainData; - } - - void registerSubstitutionAlias(String name, GameRegistry.Type type, Object toReplace) throws ExistingSubstitutionException - { - ResourceLocation nameToSubstitute = new ResourceLocation(name); - final BiMap blockItemMap = getBlockItemMap(); - if (type == GameRegistry.Type.BLOCK) - { - iBlockRegistry.addSubstitutionAlias(Loader.instance().activeModContainer().getModId(), nameToSubstitute, (Block)toReplace); - iBlockRegistry.activateSubstitution(nameToSubstitute); - } - else if (type == GameRegistry.Type.ITEM) - { - iItemRegistry.addSubstitutionAlias(Loader.instance().activeModContainer().getModId(), nameToSubstitute, (Item)toReplace); - iItemRegistry.activateSubstitution(nameToSubstitute); - } - } - - @SuppressWarnings("unchecked") - public static BiMap getBlockItemMap() - { - return (BiMap)getMain().iItemRegistry.getSlaveMap(BLOCK_TO_ITEM, BiMap.class); - } - - @SuppressWarnings("unchecked") - static > K register_impl(Object object, ResourceLocation location) - { - if (object == null) - { - FMLLog.log.error("Attempt to register a null object"); - throw new NullPointerException("Attempt to register a null object"); - } - ((K)object).setRegistryName(location); - // explicit type is needed for some reason - return GameData.register_impl(object); - } - - // argument is Object due to incorrect inferrence of the type if source level = 6, probably related to https://bugs.openjdk.java.net/browse/JDK-8026527 - @SuppressWarnings("unchecked") - static > K register_impl(Object object) - { - K castedObj = (K)object; - if (object == null) - { - FMLLog.log.error("Attempt to register a null object"); - throw new NullPointerException("Attempt to register a null object"); - } - if (castedObj.getRegistryName() == null) - { - FMLLog.log.error("Attempt to register object without having set a registry name {} (type {})", object, object.getClass().getName()); - throw new IllegalArgumentException(String.format("No registry name set for object %s (%s)", object, object.getClass().getName())); - } - final IForgeRegistry registry = PersistentRegistryManager.findRegistry(castedObj); - registry.register(castedObj); - return castedObj; - } - - @SuppressWarnings("unchecked") - public static ObjectIntIdentityMap getBlockStateIDMap() - { - return (ObjectIntIdentityMap)getMain().iBlockRegistry.getSlaveMap(BLOCKSTATE_TO_ID, ObjectIntIdentityMap.class); - } - - public static void vanillaSnapshot() - { - PersistentRegistryManager.freezeVanilla(); - } - - //Lets us clear the map so we can rebuild it. - static class ClearableObjectIntIdentityMap extends ObjectIntIdentityMap - { - void clear() - { - this.identityMap.clear(); - this.objectList.clear(); - } - } - - public > RegistryDelegate makeDelegate(T obj, Class rootClass) - { - return PersistentRegistryManager.makeDelegate(obj, rootClass); - } - - private static class BlockCallbacks implements IForgeRegistry.AddCallback,IForgeRegistry.ClearCallback,IForgeRegistry.CreateCallback, IForgeRegistry.SubstitutionCallback - { - static final BlockCallbacks INSTANCE = new BlockCallbacks(); - - @SuppressWarnings("unchecked") - @Override - public void onAdd(Block block, int blockId, Map slaves) - { - ClearableObjectIntIdentityMap blockstateMap = (ClearableObjectIntIdentityMap)slaves.get(BLOCKSTATE_TO_ID); - - //So, due to blocks having more in-world states then metadata allows, we have to turn the map into a semi-milti-bimap. - //We can do this however because the implementation of the map is last set wins. So we can add all states, then fix the meta bimap. - //Multiple states -> meta. But meta to CORRECT state. - - final boolean[] usedMeta = new boolean[16]; //Hold a list of known meta from all states. - for (IBlockState state : block.getBlockState().getValidStates()) - { - final int meta = block.getMetaFromState(state); - blockstateMap.put(state, blockId << 4 | meta); //Add ALL the things! - usedMeta[meta] = true; - } - - for (int meta = 0; meta < 16; meta++) - { - if (usedMeta[meta]) - blockstateMap.put(block.getStateFromMeta(meta), blockId << 4 | meta); // Put the CORRECT thing! - } - } - - @SuppressWarnings("unchecked") - @Override - public void onClear(IForgeRegistry registry, Map slaveset) - { - ClearableObjectIntIdentityMap blockstateMap = (ClearableObjectIntIdentityMap)slaveset.get(BLOCKSTATE_TO_ID); - blockstateMap.clear(); - final Map originals = (Map)slaveset.get(PersistentRegistryManager.SUBSTITUTION_ORIGINALS); - final BiMap blockItemMap = (BiMap)slaveset.get(BLOCK_TO_ITEM); - for (Item it : blockItemMap.values()) - { - if (it instanceof ItemBlock) { - ItemBlock itemBlock = (ItemBlock)it; - final ResourceLocation registryKey = registry.getKey(itemBlock.block); - if (!originals.containsKey(registryKey)) continue; - try - { - FinalFieldHelper.setField(blockField, itemBlock, originals.get(registryKey)); - } - catch (Exception e) - { - throw Throwables.propagate(e); - } - } - } - } - - @SuppressWarnings("unchecked") - @Override - public void onCreate(Map slaveset, BiMap> registries) - { - final ClearableObjectIntIdentityMap idMap = new ClearableObjectIntIdentityMap() - { - @SuppressWarnings("deprecation") - @Override - public int get(IBlockState key) - { - Integer integer = (Integer)this.identityMap.get(key); - // There are some cases where this map is queried to serialize a state that is valid, - //but somehow not in this list, so attempt to get real metadata. Doing this hear saves us 7 patches - if (integer == null && key != null) - integer = this.identityMap.get(key.getBlock().getStateFromMeta(key.getBlock().getMetaFromState(key))); - return integer == null ? -1 : integer.intValue(); - } - }; - ((Map)slaveset).put(BLOCKSTATE_TO_ID, idMap); - final HashBiMap map = HashBiMap.create(); - ((Map)slaveset).put(BLOCK_TO_ITEM, map); - } - - @Override - public void onSubstituteActivated(Map slaveset, Block original, Block replacement, ResourceLocation name) - { - final BiMap blockItemMap = (BiMap)slaveset.get(BLOCK_TO_ITEM); - if (blockItemMap.containsKey(original)) - { - Item i = blockItemMap.get(original); - if (i instanceof ItemBlock) - { - try - { - FinalFieldHelper.setField(blockField, i, replacement); - } - catch (Exception e) - { - throw Throwables.propagate(e); - } - } - blockItemMap.forcePut(replacement,i); - } - } - } - - private static class ItemCallbacks implements IForgeRegistry.AddCallback,IForgeRegistry.ClearCallback,IForgeRegistry.CreateCallback, IForgeRegistry.SubstitutionCallback - { - static final ItemCallbacks INSTANCE = new ItemCallbacks(); - - @Override - public void onAdd(Item item, int blockId, Map slaves) - { - if (item instanceof ItemBlock) - { - ItemBlock itemBlock = (ItemBlock)item; - @SuppressWarnings("unchecked") BiMap blockToItem = (BiMap)slaves.get(BLOCK_TO_ITEM); - final Block block = itemBlock.getBlock().delegate.get(); - blockToItem.forcePut(block, item); - } - } - - @SuppressWarnings("unchecked") - @Override - public void onClear(IForgeRegistry registry, Map slaveset) - { - Map map = (Map)slaveset.get(BLOCK_TO_ITEM); - map.clear(); - } - - @SuppressWarnings("unchecked") - @Override - public void onCreate(Map slaveset, BiMap> registries) - { - // We share the blockItem map between items and blocks registries - final BiMap blockItemMap = (BiMap)registries.get(PersistentRegistryManager.BLOCKS).getSlaveMap(BLOCK_TO_ITEM, BiMap.class); - ((Map)slaveset).put(BLOCK_TO_ITEM, blockItemMap); - } - - @Override - public void onSubstituteActivated(Map slaveset, Item original, Item replacement, ResourceLocation name) - { - final BiMap blockItemMap = (BiMap)slaveset.get(BLOCK_TO_ITEM); - } - } - - private static class PotionCallbacks implements IForgeRegistry.AddCallback,IForgeRegistry.ClearCallback,IForgeRegistry.CreateCallback - { - static final PotionCallbacks INSTANCE = new PotionCallbacks(); - - @Override - public void onAdd(Potion potion, int id, Map slaves) { - // no op for the minute? - } - - @Override - public void onClear(IForgeRegistry registry, Map slaveset) - { - // no op for the minute? - } - - @Override - public void onCreate(Map slaveset, BiMap> registries) - { - // no op for the minute? - } - } - private static class BiomeCallbacks implements IForgeRegistry.AddCallback,IForgeRegistry.ClearCallback,IForgeRegistry.CreateCallback - { - static final BiomeCallbacks INSTANCE = new BiomeCallbacks(); - - @Override - public void onAdd(Biome biome, int id, Map slaves) { - // no op for the minute? - } - - @Override - public void onClear(IForgeRegistry registry, Map slaveset) - { - // no op for the minute? - } - - @Override - public void onCreate(Map slaveset, BiMap> registries) - { - // no op for the minute? - } - } - private static class EntityCallbacks implements IForgeRegistry.AddCallback,IForgeRegistry.ClearCallback,IForgeRegistry.CreateCallback - { - static final EntityCallbacks INSTANCE = new EntityCallbacks(); - - @Override - public void onAdd(EntityEntry entry, int id, Map slaves) - { - if (entry.getEgg() != null) - EntityList.ENTITY_EGGS.put(entry.getRegistryName(), entry.getEgg()); - } - - @Override - public void onClear(IForgeRegistry registry, Map slaveset) - { - // no op for the minute? - } - - @Override - public void onCreate(Map slaveset, BiMap> registries) - { - // no op for the minute? - } - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java b/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java index 799e52716c..35c57403f6 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java +++ b/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java @@ -23,7 +23,6 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -40,27 +39,30 @@ import net.minecraft.entity.Entity; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; 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.Ingredient; +import net.minecraft.item.crafting.ShapedRecipes; +import net.minecraft.item.crafting.ShapelessRecipes; import net.minecraft.nbt.JsonToNBT; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTException; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.gen.IChunkGenerator; +import net.minecraftforge.common.crafting.CraftingHelper; +import net.minecraftforge.common.crafting.CraftingHelper.ShapedPrimer; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.IFuelHandler; import net.minecraftforge.fml.common.IWorldGenerator; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.common.LoaderException; -import net.minecraftforge.fml.common.LoaderState; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; +import net.minecraftforge.registries.GameData; +import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.IForgeRegistryEntry; +import net.minecraftforge.registries.RegistryManager; import net.minecraftforge.fml.common.IEntitySelectorFactory; import org.apache.logging.log4j.Level; @@ -70,13 +72,11 @@ import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.common.collect.ObjectArrays; import com.google.common.collect.Sets; import com.google.common.primitives.Ints; import javax.annotation.Nonnull; -@SuppressWarnings({"WeakerAccess", "unused"}) public class GameRegistry { private static Set worldGenerators = Sets.newHashSet(); @@ -189,61 +189,14 @@ public class GameRegistry } /** - * Register the previously named {@link IForgeRegistry} object with the registry system. - * Always ensure the object is already named using {@link IForgeRegistryEntry#setRegistryName(ResourceLocation)} - * or another mechanism. - * - * Note: That DOES NOT create the ItemBlock for you if this is a Block, you should register that item separately. - * - * @param object The object to register with a registry - * @param The registry supertype - * @throws IllegalArgumentException if the object is not yet named (use {@link #register(IForgeRegistryEntry, ResourceLocation)} instead) - * @return The object + * This is now private, you should use either ForgeRegistries constants. + * Or the registry passed in during the RegistryEvent.Register event. */ - @SuppressWarnings("unchecked") - public static > K register(K object) + private static > K register(K object) { return (K)GameData.register_impl(object); } - /** - * Register the unnamed {@link IForgeRegistry} object with the registry system. - * Always make sure you have not previously named the object. - * - * It is advised that you set the object's registry name and use {@link #register(IForgeRegistryEntry)} instead. - * - * Note: That DOES NOT create the ItemBlock for you if this is a Block, you should register that item separately. - * - * @param object The object to register - * @param name The name to register it with - * @param The registry supertype - * @throws IllegalStateException if the object already has an existing name (use {@link #register(IForgeRegistryEntry)} instead) - * @return The object - */ - @SuppressWarnings("unchecked") - public static > K register(K object, ResourceLocation name) - { - return (K)GameData.register_impl(object, name); - } - - - /** - * Registers a named block with the Block registry. This WILL create a new ItemBlock for you with the - * same name and register it with the ItemRegistry. This method is created as a convince method for - * modder and SHOULD NOT be used. Modders should create and register their ItemBlocks like normal items. - * - * @param block The block to register with a registry - * @throws IllegalArgumentException if the object is not yet named - * @return The block - */ - @Deprecated //Modders SHOULD NOT use this, so it'll stay deprecated. Purely added to make lazy modders happy -.- - public static Block registerWithItem(Block block) - { - register(block); - register(new ItemBlock(block).setRegistryName(block.getRegistryName())); - return block; - } - /** * Retrieves the registry associated with this super class type. * If the return is non-null it is HIGHLY recommended that modders cache this @@ -254,44 +207,21 @@ public class GameRegistry */ public static > IForgeRegistry findRegistry(Class registryType) { - return PersistentRegistryManager.findRegistryByType(registryType); + return RegistryManager.ACTIVE.getRegistry(registryType); } - /** - * Add a forced persistent substitution alias for the block or item to another block or item. This will have - * the effect of using the substituted block or item instead of the original, where ever it is - * referenced. - * - * @param nameToSubstitute The name to link to (this is the NEW block or item) - * @param type The type (Block or Item) - * @param object a NEW instance that is type compatible with the existing instance - * @throws ExistingSubstitutionException if someone else has already registered an alias either from or to one of the names - * @throws IncompatibleSubstitutionException if the substitution is incompatible - */ - public static void addSubstitutionAlias(String nameToSubstitute, GameRegistry.Type type, Object object) throws ExistingSubstitutionException + public static void addShapedRecipe(ResourceLocation name, ResourceLocation group, @Nonnull ItemStack output, Object... params) { - GameData.getMain().registerSubstitutionAlias(nameToSubstitute, type, object); + ShapedPrimer primer = CraftingHelper.parseShaped(params); + register(new ShapedRecipes(group == null ? "" : group.toString(), primer.width, primer.height, primer.input, output).setRegistryName(name)); } - @Deprecated //TODO Make IRecipe a registry - public static IRecipe addShapedRecipe(ResourceLocation name, @Nonnull ItemStack output, Object... params) + public static void addShapelessRecipe(ResourceLocation name, ResourceLocation group, @Nonnull ItemStack output, Ingredient... params) { - throw new RuntimeException("TODO: Forge implement IRecipe registry"); - //return CraftingManager.addRecipe(output, params); - } - - @Deprecated //TODO Make IRecipe a registry - public static void addShapelessRecipe(ResourceLocation name, @Nonnull ItemStack output, Ingredient... params) - { - throw new RuntimeException("TODO: Forge implement IRecipe registry"); - //CraftingManager.getInstance().addShapelessRecipe(output, params); - } - - @Deprecated //TODO Make IRecipe a registry - public static void addRecipe(ResourceLocation name, IRecipe recipe) - { - throw new RuntimeException("TODO: Forge implement IRecipe registry"); - //CraftingManager.getInstance().getRecipeList().add(recipe); + NonNullList lst = NonNullList.create(); + for (Ingredient i : params) + lst.add(i); + register(new ShapelessRecipes(group == null ? "" : group.toString(), output, lst).setRegistryName(name)); } public static void addSmelting(Block input, @Nonnull ItemStack output, float xp) @@ -309,26 +239,10 @@ public class GameRegistry FurnaceRecipes.instance().addSmeltingRecipe(input, output, xp); } - public static void registerTileEntity(Class tileEntityClass, String id) + public static void registerTileEntity(Class tileEntityClass, String key) { - GameData.getTileEntityRegistry().putObject(new ResourceLocation(id), tileEntityClass); - } - - /** - * Register a tile entity, with alternative TileEntity identifiers. Use with caution! - * This method allows for you to "rename" the 'id' of the tile entity. - * - * @param tileEntityClass The tileEntity class to register - * @param id The primary ID, this will be the ID that the tileentity saves as - * @param alternatives A list of alternative IDs that will also map to this class. These will never save, but they will load - */ - public static void registerTileEntityWithAlternatives(Class tileEntityClass, String id, String... alternatives) - { - GameRegistry.registerTileEntity(tileEntityClass, id); - for (String s : alternatives) - { - GameData.getTileEntityRegistry().addLegacyName(new ResourceLocation(s), new ResourceLocation(id)); - } + throw new RuntimeException("TODO: TileEntity registration"); + //TileEntity.register(key, tileEntityClass); } public static void registerFuelHandler(IFuelHandler handler) @@ -346,12 +260,6 @@ public class GameRegistry return fuelValue; } - public enum Type - { - BLOCK, - ITEM; - } - /** * ObjectHolder can be used to automatically populate public static final fields with entries * from the registry. These values can then be referred within mod code directly. @@ -423,7 +331,7 @@ public class GameRegistry { throw new IllegalArgumentException("The itemName cannot be null"); } - Item item = GameData.getItemRegistry().getObject(new ResourceLocation(itemName)); + Item item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(itemName)); if (item == null) { FMLLog.log.trace("Unable to find item with name {}", itemName); @@ -439,7 +347,8 @@ public class GameRegistry } catch (NBTException e) { FMLLog.log.warn("Encountered an exception parsing ItemStack NBT string {}", nbtString, e); - throw Throwables.propagate(e); + Throwables.throwIfUnchecked(e); + throw new RuntimeException(e); } if (!(nbttag instanceof NBTTagCompound)) { diff --git a/src/main/java/net/minecraftforge/fml/common/registry/LegacyNamespacedRegistry.java b/src/main/java/net/minecraftforge/fml/common/registry/LegacyNamespacedRegistry.java deleted file mode 100644 index 5f41591f32..0000000000 --- a/src/main/java/net/minecraftforge/fml/common/registry/LegacyNamespacedRegistry.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.registry; - -import java.util.Map; - -import javax.annotation.Nullable; - -import com.google.common.collect.Maps; - -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.registry.RegistryNamespaced; - -public class LegacyNamespacedRegistry extends RegistryNamespaced -{ - private Map legacy_names = Maps.newHashMap(); - - @Override - @Nullable - public V getObject(@Nullable ResourceLocation name) - { - V ret = super.getObject(name); - - if (ret == null) - { - ResourceLocation new_name = legacy_names.get(name); - if (new_name != null) - ret = super.getObject(new_name); - } - - return ret; - } - - public void addLegacyName(ResourceLocation old_name, ResourceLocation new_name) - { - legacy_names.put(old_name, new_name); - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/registry/PersistentRegistryManager.java b/src/main/java/net/minecraftforge/fml/common/registry/PersistentRegistryManager.java deleted file mode 100644 index 3c7f3e054f..0000000000 --- a/src/main/java/net/minecraftforge/fml/common/registry/PersistentRegistryManager.java +++ /dev/null @@ -1,857 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.common.registry; - -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockAir; -import net.minecraft.item.Item; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.EnhancedRuntimeException; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.common.StartupQuery; -import net.minecraftforge.fml.common.ZipperUtil; -import net.minecraftforge.fml.common.event.FMLMissingMappingsEvent; - -import org.apache.logging.log4j.Level; - -import com.google.common.base.Function; -import com.google.common.base.Throwables; -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.common.collect.Sets.SetView; - -import javax.annotation.Nullable; - -/** - * Persistent registry manager. Manages the registries loading from disk, and from network. Handles staging - * registry data before loading uniformly into the active registry, and keeps a frozen registry instance - * for reversion after connection. - * - * @author cpw - */ -@SuppressWarnings("WeakerAccess") -public class PersistentRegistryManager -{ - public static void fireCreateRegistryEvents() { - MinecraftForge.EVENT_BUS.post(new RegistryEvent.NewRegistry()); - } - - public static void fireRegistryEvents() - { - List registryKeys = Lists.newArrayList(PersistentRegistry.ACTIVE.registries.keySet()); - Collections.sort(registryKeys, new Comparator() - { - @Override - public int compare(ResourceLocation o1, ResourceLocation o2) - { - return o1.toString().compareToIgnoreCase(o2.toString()); - } - }); - fireRegistryEvent(PersistentRegistry.ACTIVE.registries, BLOCKS); - ObjectHolderRegistry.INSTANCE.applyObjectHolders(); // inject any blocks - fireRegistryEvent(PersistentRegistry.ACTIVE.registries, ITEMS); - ObjectHolderRegistry.INSTANCE.applyObjectHolders(); // inject any items - for (ResourceLocation rl : registryKeys) { - if (rl == BLOCKS || rl == ITEMS) continue; - if (rl == RECIPES) continue; //For now disable, we should fire this event in ServerInit or something... - fireRegistryEvent(PersistentRegistry.ACTIVE.registries, rl); - } - ObjectHolderRegistry.INSTANCE.applyObjectHolders(); // inject everything else - } - private static void fireRegistryEvent(BiMap> registries, ResourceLocation name) - { - final RegistryEvent.Register event = registries.get(name).buildRegistryRegisterEvent(name); - MinecraftForge.EVENT_BUS.post(event); - } - - enum PersistentRegistry - { - ACTIVE, VANILLA, FROZEN, STAGING; - - private final BiMap> registries = HashBiMap.create(); - private final BiMap>, ResourceLocation> registrySuperTypes = HashBiMap.create(); - - @SuppressWarnings("unchecked") - private > Class getRegistrySuperType(ResourceLocation key) - { - return (Class)registrySuperTypes.inverse().get(key); - } - - @SuppressWarnings("unchecked") - private > FMLControlledNamespacedRegistry getRegistry(ResourceLocation key, @SuppressWarnings("UnusedParameters") @Nullable Class regType) - { - return (FMLControlledNamespacedRegistry)registries.get(key); - } - - private > FMLControlledNamespacedRegistry getOrShallowCopyRegistry(ResourceLocation key, Class regType, FMLControlledNamespacedRegistry other) - { - if (!registries.containsKey(key)) - { - registries.put(key, other.makeShallowCopy(registries)); - registrySuperTypes.put(regType, key); - } - return getRegistry(key, regType); - } - - private > FMLControlledNamespacedRegistry createRegistry(ResourceLocation registryName, Class type, ResourceLocation defaultObjectKey, int minId, int maxId, @Nullable IForgeRegistry.AddCallback addCallback, @Nullable IForgeRegistry.ClearCallback clearCallback, @Nullable IForgeRegistry.CreateCallback createCallback, @Nullable IForgeRegistry.SubstitutionCallback substitutionCallback, boolean saveToDisc) - { - Set> parents = Sets.newHashSet(); - findSuperTypes(type, parents); - SetView> overlappedTypes = Sets.intersection(parents, registrySuperTypes.keySet()); - if (!overlappedTypes.isEmpty()) - { - Class foundType = overlappedTypes.iterator().next(); - FMLLog.log.fatal("Found existing registry of type {} named {}, you cannot create a new registry ({}) with type {}, as {} has a parent of that type", foundType, registrySuperTypes.get(foundType), registryName, type, type); - throw new IllegalArgumentException("Duplicate registry parent type found - you can only have one registry for a particular super type"); - } - FMLControlledNamespacedRegistry fmlControlledNamespacedRegistry = new FMLControlledNamespacedRegistry(defaultObjectKey, minId, maxId, type, registries, addCallback, clearCallback, createCallback, substitutionCallback, saveToDisc); - registries.put(registryName, fmlControlledNamespacedRegistry); - registrySuperTypes.put(type, registryName); - return getRegistry(registryName, type); - } - - private void findSuperTypes(Class type, Set> types) - { - if (type == null || type == Object.class) - { - return; - } - types.add(type); - for (Class interfac : type.getInterfaces()) - { - findSuperTypes(interfac, types); - } - findSuperTypes(type.getSuperclass(), types); - } - - - void clean() - { - registries.clear(); - registrySuperTypes.clear(); - } - - boolean isPopulated() - { - return !registries.isEmpty(); - } - - boolean containsRegistry(FMLControlledNamespacedRegistry registry) - { - return registries.containsValue(registry); - } - - public > FMLControlledNamespacedRegistry getRegistry(Class rootClass) - { - ResourceLocation rl = registrySuperTypes.get(rootClass); - return getRegistry(rl, rootClass); - } - } - - public static final ResourceLocation BLOCKS = new ResourceLocation("minecraft:blocks"); - public static final ResourceLocation ITEMS = new ResourceLocation("minecraft:items"); - public static final ResourceLocation POTIONS = new ResourceLocation("minecraft:potions"); - public static final ResourceLocation BIOMES = new ResourceLocation("minecraft:biomes"); - public static final ResourceLocation SOUNDEVENTS = new ResourceLocation("minecraft:soundevents"); - public static final ResourceLocation POTIONTYPES = new ResourceLocation("minecraft:potiontypes"); - public static final ResourceLocation ENCHANTMENTS = new ResourceLocation("minecraft:enchantments"); - public static final ResourceLocation ENTITIES = new ResourceLocation("minecraft:entities"); - public static final ResourceLocation RECIPES = new ResourceLocation("minecraft:recipes"); - static final ResourceLocation SUBSTITUTION_ORIGINALS = new ResourceLocation("fml:suboriginals"); - - @Deprecated //Use RegistryBuilder TODO: Remove in 1.11 {Make package private so only builder can use it} - static > FMLControlledNamespacedRegistry createRegistry( - ResourceLocation registryName, Class registryType, @Nullable ResourceLocation optionalDefaultKey, - int minId, int maxId, boolean hasDelegates, - @Nullable IForgeRegistry.AddCallback addCallback, - @Nullable IForgeRegistry.ClearCallback clearCallback, - @Nullable IForgeRegistry.CreateCallback createCallback, - @Nullable IForgeRegistry.SubstitutionCallback substitutionCallback, - boolean saveToDisc) - { - return PersistentRegistry.ACTIVE.createRegistry(registryName, registryType, optionalDefaultKey, minId, maxId, - addCallback, clearCallback, createCallback, substitutionCallback, saveToDisc); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - static > IForgeRegistry findRegistry(IForgeRegistryEntry entry) - { - final Class registryType = (Class)(Class)entry.getRegistryType(); - final FMLControlledNamespacedRegistry registry = PersistentRegistry.ACTIVE.getRegistry(registryType); - if (registry == null) - { - FMLLog.log.error("Unable to locate registry for registered object of type {}", entry.getClass().getName()); - throw new IllegalArgumentException("Unable to locate registry for registered object"); - } - return registry; - } - - static > IForgeRegistry findRegistryByType(Class registryType) - { - return PersistentRegistry.ACTIVE.getRegistry(registryType); - } - - public static ResourceLocation getRegistryRegistryName(IForgeRegistry registry) { - return PersistentRegistry.ACTIVE.registries.inverse().get(registry); - } - - public static List injectSnapshot(GameDataSnapshot snapshot, boolean injectFrozenData, boolean isLocalWorld) - { - FMLLog.log.info("Injecting existing block and item data into this {} instance", FMLCommonHandler.instance().getEffectiveSide().isServer() ? "server" : "client"); - final Map> remaps = Maps.newHashMap(); - final LinkedHashMap> missing = Maps.newLinkedHashMap(); - - forAllRegistries(PersistentRegistry.ACTIVE, ValidateRegistryFunction.OPERATION); - forAllRegistries(PersistentRegistry.ACTIVE, DumpRegistryFunction.OPERATION); - forAllRegistries(PersistentRegistry.ACTIVE, ResetDelegatesFunction.OPERATION); - - List missingRegs = Lists.newArrayList(); - for (ResourceLocation name : snapshot.entries.keySet()) - { - name = getFixedName(name); - if (PersistentRegistry.ACTIVE.getRegistry(name, null) == null) - { - missingRegs.add(name); - } - } - - if (missingRegs.size() > 0) - { - String text = "Forge Mod Loader detected missing/unknown registrie(s).\n\n" + - "There are " + missingRegs.size() + " missing registries in this save.\n" + - "If you continue the missing registries will get removed.\n" + - "This may cause issues, it is advised that you create a world backup before continuing.\n\n" + - "Missing Registries:\n"; - - for (ResourceLocation s : missingRegs) - text += s.toString() + "\n"; - - boolean confirmed = StartupQuery.confirm(text); - if (!confirmed) - { - StartupQuery.abort(); - ; - } - } - - // Load the snapshot into the "STAGING" registry - for (Map.Entry snapshotEntry : snapshot.entries.entrySet()) - { - final Class registrySuperType = PersistentRegistry.ACTIVE.getRegistrySuperType(snapshotEntry.getKey()); - loadPersistentDataToStagingRegistry(injectFrozenData, remaps, missing, snapshotEntry, registrySuperType); - } - - // Handle dummied blocks - for (ResourceLocation dummy : snapshot.entries.get(BLOCKS).dummied) - { - // Currently missing locally, we just inject and carry on - if (missing.get(BLOCKS).containsKey(dummy)) - { - Integer id = missing.get(BLOCKS).remove(dummy); - // Mark this entry as a dummy - PersistentRegistry.STAGING.getRegistry(BLOCKS, Block.class).markDummy(dummy, id, new BlockDummyAir()); - } - else if (isLocalWorld) - { - // Carry on, we resuscitated the block - if (FMLControlledNamespacedRegistry.DEBUG) - { - FMLLog.log.debug("Registry: Resuscitating dummy block {}", dummy); - } - } - else - { - Integer id = PersistentRegistry.STAGING.getRegistry(BLOCKS, Block.class).getId(dummy); - // The server believes this is a dummy block identity, but we seem to have one locally. This is likely a conflict - // in mod setup - Mark this entry as a dummy - FMLLog.log.warn("The ID {} is currently locally mapped - it will be replaced with air for this session", id); - PersistentRegistry.STAGING.getRegistry(BLOCKS, Block.class).markDummy(dummy, id, new BlockDummyAir()); - } - } - - // If we have missed data, fire the missing mapping event - List missedMappings = Loader.instance().fireMissingMappingEvent(missing.get(BLOCKS), missing.get(ITEMS), isLocalWorld, remaps.get(BLOCKS), remaps.get(ITEMS)); - // If there's still missed mappings, we return, because that's an error - if (!missedMappings.isEmpty()) - { - return missedMappings; - } - - // If we're loading from disk, we can actually substitute air in the block map for anything that is otherwise "missing". This keeps the reference in the map, in case - // the block comes back later - if (injectFrozenData) - { - for (Map.Entry missingBlock: missing.get(BLOCKS).entrySet()) - { - ResourceLocation rl = missingBlock.getKey(); - Integer id = missingBlock.getValue(); - FMLLog.log.debug("Replacing id {} named as {} with air block. If the mod becomes available again later, it can reload here", id, rl); - // Mark this entry as a dummy - PersistentRegistry.STAGING.getRegistry(BLOCKS, Block.class).markDummy(rl, id, new BlockDummyAir()); - } - } - // If we're loading up the world from disk, we want to add in the new data that might have been provisioned by mods - if (injectFrozenData) - { - // So we load it from the frozen persistent registry - for (Map.Entry> r : PersistentRegistry.ACTIVE.registries.entrySet()) - { - final Class registrySuperType = PersistentRegistry.ACTIVE.getRegistrySuperType(r.getKey()); - loadFrozenDataToStagingRegistry(remaps, r.getKey(), registrySuperType); - } - } - - // Validate that all the STAGING data is good - forAllRegistries(PersistentRegistry.STAGING, ValidateRegistryFunction.OPERATION); - - // Load the STAGING registry into the ACTIVE registry - for (Map.Entry> r : PersistentRegistry.ACTIVE.registries.entrySet()) - { - final Class registrySuperType = PersistentRegistry.ACTIVE.getRegistrySuperType(r.getKey()); - loadRegistry(r.getKey(), PersistentRegistry.STAGING, PersistentRegistry.ACTIVE, registrySuperType); - } - - // Dump the active registry - forAllRegistries(PersistentRegistry.ACTIVE, DumpRegistryFunction.OPERATION); - - // Tell mods that the ids have changed - Loader.instance().fireRemapEvent(remaps.get(BLOCKS), remaps.get(ITEMS), false); - - // The id map changed, ensure we apply object holders - ObjectHolderRegistry.INSTANCE.applyObjectHolders(); - - // Clean out the staging registry now, we're done with it - PersistentRegistry.STAGING.clean(); - - // Return an empty list, because we're good - return ImmutableList.of(); - } - private static class BlockDummyAir extends BlockAir { - private BlockDummyAir() { - setUnlocalizedName("air"); - } - } - private static void forAllRegistries(PersistentRegistry registrySet, Function>, Void> operation) - { - for (Map.Entry> r : registrySet.registries.entrySet()) - { - operation.apply(r); - } - } - - private static > void loadRegistry(final ResourceLocation registryName, final PersistentRegistry from, final PersistentRegistry to, final Class regType) - { - FMLControlledNamespacedRegistry fromRegistry = from.getRegistry(registryName, regType); - if (fromRegistry == null) - { - FMLControlledNamespacedRegistry toRegistry = to.getRegistry(registryName, regType); - if (toRegistry == null) - { - throw new EnhancedRuntimeException("Could not find registry to load: " + registryName){ - private static final long serialVersionUID = 1L; - @Override - protected void printStackTrace(WrappedPrintStream stream) - { - stream.println("Looking For: " + registryName); - stream.println("Found From:"); - for (ResourceLocation name : from.registries.keySet()) - stream.println(" " + name); - stream.println("Found To:"); - for (ResourceLocation name : to.registries.keySet()) - stream.println(" " + name); - } - }; - } - // We found it in to, so lets trust to's state... - // This happens when connecting to a server that doesn't have this registry. - // Such as a 1.8.0 Forge server with 1.8.8+ Forge. - // We must however, re-fire the callbacks as some internal data may be corrupted {potions} - toRegistry.notifyCallbacks(); - } - else - { - FMLControlledNamespacedRegistry toRegistry = to.getOrShallowCopyRegistry(registryName, regType, fromRegistry); - toRegistry.set(fromRegistry); - } - } - - private static > void loadFrozenDataToStagingRegistry(Map> remaps, ResourceLocation registryName, Class regType) - { - FMLControlledNamespacedRegistry frozenRegistry = PersistentRegistry.FROZEN.getRegistry(registryName, regType); - FMLControlledNamespacedRegistry newRegistry = PersistentRegistry.STAGING.getOrShallowCopyRegistry(registryName, regType, frozenRegistry); - newRegistry.loadIds(frozenRegistry.getEntriesNotIn(newRegistry), Maps.newLinkedHashMap(), remaps.get(registryName), frozenRegistry, registryName); - } - - // TODO: Remove in 1.11 when we don't care about loading 1.8 worlds and below - private static ResourceLocation getFixedName(ResourceLocation registryName) - { - //Translate old names - if ("fml:blocks".equals(registryName.toString())) registryName = PersistentRegistryManager.BLOCKS; - else if ("fml:items".equals(registryName.toString())) registryName = PersistentRegistryManager.ITEMS; - else if ("fmlgr:villagerprofessions".equals(registryName.toString())) registryName = VillagerRegistry.PROFESSIONS; - - return registryName; - } - - private static > void loadPersistentDataToStagingRegistry(boolean injectFrozenData, Map> remaps, LinkedHashMap> missing, Map.Entry snapEntry, Class regType) - { - ResourceLocation registryName = getFixedName(snapEntry.getKey()); - - FMLControlledNamespacedRegistry currentRegistry = PersistentRegistry.ACTIVE.getRegistry(registryName, regType); - if (currentRegistry == null) - { - return; // We've already asked the user if they wish to continue. So if the reg isnt found just assume the user knows and accepted it. - } - FMLControlledNamespacedRegistry newRegistry = PersistentRegistry.STAGING.getOrShallowCopyRegistry(registryName, regType, currentRegistry); - // Copy the persistent substitution set from the currently active one into the new registry - newRegistry.getPersistentSubstitutions().putAll(currentRegistry.getPersistentSubstitutions()); - GameDataSnapshot.Entry snapshotEntry = snapEntry.getValue(); - Set substitutions = snapshotEntry.substitutions; - if (injectFrozenData) - { - substitutions = Sets.union(snapshotEntry.substitutions, currentRegistry.getActiveSubstitutions()); - } - newRegistry.loadAliases(snapshotEntry.aliases); - newRegistry.loadBlocked(snapshotEntry.blocked); - missing.put(registryName, Maps.newLinkedHashMap()); - remaps.put(registryName, Maps.newHashMap()); - // Load current dummies BEFORE the snapshot is loaded so that add() will remove from the list. - // Potentially causes issues from cpw's previous comment. Must keep eye on. - newRegistry.loadDummied(snapshotEntry.dummied); - newRegistry.loadIds(snapshotEntry.ids, missing.get(registryName), remaps.get(registryName), currentRegistry, registryName); - newRegistry.loadSubstitutions(substitutions); - } - - public static boolean isFrozen(FMLControlledNamespacedRegistry registry) - { - return PersistentRegistry.FROZEN.containsRegistry(registry); - } - - public static void revertToFrozen() - { - if (!PersistentRegistry.FROZEN.isPopulated()) - { - FMLLog.log.warn("Can't revert to frozen GameData state without freezing first."); - return; - } - else - { - FMLLog.log.debug("Reverting to frozen data state."); - } - for (Map.Entry> r : PersistentRegistry.ACTIVE.registries.entrySet()) - { - final Class registrySuperType = PersistentRegistry.ACTIVE.getRegistrySuperType(r.getKey()); - loadRegistry(r.getKey(), PersistentRegistry.FROZEN, PersistentRegistry.ACTIVE, registrySuperType); - } - // the id mapping has reverted, fire remap events for those that care about id changes - Loader.instance().fireRemapEvent(ImmutableMap.of(), ImmutableMap.of(), true); - - // the id mapping has reverted, ensure we sync up the object holders - ObjectHolderRegistry.INSTANCE.applyObjectHolders(); - FMLLog.log.debug("Frozen state restored."); - } - - public static void freezeData() - { - FMLLog.log.debug("Freezing block and item id maps"); - for (Map.Entry> r : PersistentRegistry.ACTIVE.registries.entrySet()) - { - // This has to be performed prior to invoking the method so the compiler can precompute the type bounds for the method - final Class registrySuperType = PersistentRegistry.ACTIVE.getRegistrySuperType(r.getKey()); - loadRegistry(r.getKey(), PersistentRegistry.ACTIVE, PersistentRegistry.FROZEN, registrySuperType); - } - forAllRegistries(PersistentRegistry.FROZEN, ValidateRegistryFunction.OPERATION); - } - - public static void freezeVanilla() - { - FMLLog.log.debug("Creating vanilla freeze snapshot"); - for (Map.Entry> r : PersistentRegistry.ACTIVE.registries.entrySet()) - { - // This has to be performed prior to invoking the method so the compiler can precompute the type bounds for the method - final Class registrySuperType = PersistentRegistry.ACTIVE.getRegistrySuperType(r.getKey()); - loadRegistry(r.getKey(), PersistentRegistry.ACTIVE, PersistentRegistry.VANILLA, registrySuperType); - } - forAllRegistries(PersistentRegistry.VANILLA, ValidateRegistryFunction.OPERATION); - FMLLog.log.debug("Vanilla freeze snapshot created"); - } - - public static List processIdRematches(Iterable missedMappings, boolean isLocalWorld, Map missingBlocks, Map missingItems, Map remapBlocks, Map remapItems) - { - List failed = Lists.newArrayList(); - List ignored = Lists.newArrayList(); - List warned = Lists.newArrayList(); - List defaulted = Lists.newArrayList(); - - final PersistentRegistry staging = PersistentRegistry.STAGING; - final PersistentRegistry active = PersistentRegistry.ACTIVE; - for (FMLMissingMappingsEvent.MissingMapping remap : missedMappings) - { - FMLMissingMappingsEvent.Action action = remap.getAction(); - - if (action == FMLMissingMappingsEvent.Action.REMAP) - { - // block/item re-mapped, finish the registration with the new name/object, but the old id - int currId = -1, newId = -1; - ResourceLocation newName; - - if (remap.type == GameRegistry.Type.BLOCK) - { - currId = staging.getRegistry(BLOCKS, Block.class).getId((Block)remap.getTarget()); - newName = active.getRegistry(BLOCKS, Block.class).getNameForObject((Block)remap.getTarget()); - FMLLog.log.debug("The Block {} is being remapped to {}.", remap.name, newName); - - missingBlocks.remove(new ResourceLocation(remap.name)); - newId = staging.getRegistry(BLOCKS, Block.class).add(remap.id, newName, (Block)remap.getTarget()); - staging.getRegistry(BLOCKS, Block.class).addAlias(remap.resourceLocation, newName); - } - else if (remap.type == GameRegistry.Type.ITEM) - { - currId = staging.getRegistry(ITEMS, Item.class).getId((Item)remap.getTarget()); - newName = active.getRegistry(ITEMS, Item.class).getNameForObject((Item)remap.getTarget()); - FMLLog.log.debug("The Item {} is being remapped to {}.", remap.name, newName); - - missingItems.remove(new ResourceLocation(remap.name)); - newId = staging.getRegistry(ITEMS, Item.class).add(remap.id, newName, (Item)remap.getTarget()); - staging.getRegistry(ITEMS, Item.class).addAlias(remap.resourceLocation, newName); - } - else - { - // currently not remapping non-blocks and items - continue; - } - - if (newId != remap.id) - { - throw new IllegalStateException(); - } - - if (currId != newId) - { - FMLLog.log.info("Fixed {} id mismatch {}: {} (init) -> {} (map).", remap.type == GameRegistry.Type.BLOCK ? "block" : "item", newName, currId, newId); - (remap.type == GameRegistry.Type.BLOCK ? remapBlocks : remapItems).put(newName, new Integer[] {currId, newId}); - } - } - else if (action == FMLMissingMappingsEvent.Action.BLOCKONLY) - { - // Pulled out specifically so the block doesn't get reassigned a new ID just because it's - // Item block has gone away - FMLLog.log.debug("The ItemBlock {} is no longer present in the game. The residual block will remain", remap.name); - } - else - { - // block item missing, warn as requested and block the id - if (action == FMLMissingMappingsEvent.Action.DEFAULT) - { - defaulted.add(remap.name); - } - else if (action == FMLMissingMappingsEvent.Action.IGNORE) - { - ignored.add(remap.name); - } - else if (action == FMLMissingMappingsEvent.Action.FAIL) - { - failed.add(remap.name); - } - else if (action == FMLMissingMappingsEvent.Action.WARN) - { - warned.add(remap.name); - } - // prevent the id from being reused later - if (remap.type == GameRegistry.Type.BLOCK) - { - staging.getRegistry(BLOCKS, Block.class).blockId(remap.id); - } - else if (remap.type == GameRegistry.Type.ITEM) - { - staging.getRegistry(ITEMS, Item.class).blockId(remap.id); - } - } - } - - if (!defaulted.isEmpty()) - { - String text = "Forge Mod Loader detected missing blocks/items.\n\n" + - "There are " + defaulted.size() + " missing blocks and items in this save.\n" + - "If you continue the missing blocks/items will get removed.\n" + - "A world backup will be automatically created in your saves directory.\n\n" + - "Missing Blocks/Items:\n"; - - for (String s : defaulted) text += s + "\n"; - - boolean confirmed = StartupQuery.confirm(text); - if (!confirmed) - { - StartupQuery.abort(); - } - - try - { - String skip = System.getProperty("fml.doNotBackup"); - if (skip == null || !"true".equals(skip)) - { - ZipperUtil.backupWorld(); - } - else - { - for (int x = 0; x < 10; x++) - FMLLog.log.fatal("!!!!!!!!!! UPDATING WORLD WITHOUT DOING BACKUP !!!!!!!!!!!!!!!!"); - } - } catch (IOException e) - { - StartupQuery.notify("The world backup couldn't be created.\n\n" + e); - StartupQuery.abort(); - } - - warned.addAll(defaulted); - } - if (!failed.isEmpty()) - { - FMLLog.log.fatal("This world contains blocks and items that refuse to be remapped. The world will not be loaded"); - return failed; - } - if (!warned.isEmpty()) - { - FMLLog.log.warn("This world contains block and item mappings that may cause world breakage"); - return failed; - } - else if (!ignored.isEmpty()) - { - FMLLog.log.debug("There were {} missing mappings that have been ignored", ignored.size()); - } - return failed; - } - - - public static GameDataSnapshot takeSnapshot() - { - final GameDataSnapshot snap = new GameDataSnapshot(); - forAllRegistries(PersistentRegistry.ACTIVE, new Function>, Void>() - { - @Override - public Void apply(Map.Entry> input) - { - snap.entries.put(input.getKey(), new GameDataSnapshot.Entry(input.getValue())); - return null; - } - }); - return snap; - } - - - public static class GameDataSnapshot - { - public static class Entry - { - public final Map ids; - public final Set substitutions; - public final Map aliases; - public final Set blocked; - public final Set dummied; - public final boolean saveToDisc; - - public Entry() - { - this(new HashMap(), new HashSet(), new HashMap(), new HashSet(), new HashSet()); - } - - public Entry(Map ids, Set substitutions, Map aliases, Set blocked, Set dummies) - { - this.ids = ids; - this.substitutions = substitutions; - this.aliases = aliases; - this.blocked = blocked; - this.dummied = dummies; - saveToDisc = false; - } - - public Entry(FMLControlledNamespacedRegistry registry) - { - this.ids = Maps.newHashMap(); - this.substitutions = Sets.newHashSet(); - this.aliases = Maps.newHashMap(); - this.blocked = Sets.newHashSet(); - this.dummied = Sets.newHashSet(); - - registry.serializeIds(this.ids); - registry.serializeSubstitutions(this.substitutions); - registry.serializeAliases(this.aliases); - registry.serializeBlockList(this.blocked); - registry.serializeDummied(this.dummied); - this.saveToDisc = registry.shouldSaveToDisc(); - } - } - - public final Map entries = Maps.newHashMap(); - } - - public static > RegistryDelegate makeDelegate(T obj, Class rootClass) - { - return PersistentRegistry.ACTIVE.getRegistry(rootClass).getDelegate(obj, rootClass); - } - - - private static class DumpRegistryFunction implements Function>, Void> - { - static final DumpRegistryFunction OPERATION = new DumpRegistryFunction(); - - @Override - public Void apply(Map.Entry> input) - { - input.getValue().dump(input.getKey()); - return null; - } - } - - private static class ValidateRegistryFunction implements Function>, Void> - { - static final ValidateRegistryFunction OPERATION = new ValidateRegistryFunction(); - - @Override - public Void apply(Map.Entry> input) - { - input.getValue().validateContent(input.getKey()); - return null; - } - } - - private static class ResetDelegatesFunction implements Function>, Void> - { - static final ResetDelegatesFunction OPERATION = new ResetDelegatesFunction(); - - @Override - public Void apply(Map.Entry> input) - { - input.getValue().resetSubstitutionDelegates(); - return null; - } - } - - - //TODO: Remove in 1.11, creates wrappers for API breakage cpw did in registry re-work. - @Nullable - private static > IForgeRegistry.ClearCallback getLegacyClear(@Nullable final IForgeRegistry.ClearCallback cb) - { - if (cb == null) - return null; - try { - final Method mtd = cb.getClass().getMethod("onClear", Map.class); - return new IForgeRegistry.ClearCallback() - { - @Override - public void onClear(IForgeRegistry is, Map slaveset) - { - try { - mtd.invoke(cb, slaveset); - } catch (Exception e) { - e.printStackTrace( ); - Throwables.propagate(e); - } - } - }; - } catch (NoSuchMethodException e) { - e.printStackTrace(); - return cb; //Assume they are ussing modern API - } catch (SecurityException e) { - e.printStackTrace(); - throw Throwables.propagate(e); - } - } - - //TODO: Remove in 1.11, creates wrappers for API breakage cpw did in registry re-work. - @Nullable - private static > IForgeRegistry.CreateCallback getLegacyCreate(@Nullable final IForgeRegistry.CreateCallback cb) - { - if (cb == null) - return null; - try { - final Method mtd = cb.getClass().getMethod("onCreate", Map.class); - return new IForgeRegistry.CreateCallback() - { - @Override - public void onCreate(Map slaveset, BiMap> registries) - { - try { - mtd.invoke(cb, slaveset); - } catch (Exception e) { - e.printStackTrace( ); - Throwables.propagate(e); - } - } - }; - } catch (NoSuchMethodException e) { - e.printStackTrace(); - return cb; //Assume they are ussing modern API - } catch (SecurityException e) { - e.printStackTrace(); - throw Throwables.propagate(e); - } - } - - //TODO: Remove in 1.11, creates wrappers for API breakage cpw did in registry re-work. - @Nullable - private static > IForgeRegistry.AddCallback getLegacyAdd(@Nullable final IForgeRegistry.AddCallback cb) - { - if (cb == null) - return null; - try { - final Method mtd = cb.getClass().getMethod("onAdd", Object.class, int.class, Map.class); - return new IForgeRegistry.AddCallback() - { - @Override - public void onAdd(T obj, int id, Map slaveset) - { - try { - mtd.invoke(cb, obj, id, slaveset); - } catch (Exception e) { - e.printStackTrace( ); - Throwables.propagate(e); - } - } - }; - } catch (NoSuchMethodException e) { - e.printStackTrace(); - return cb; //Assume they are ussing modern API - } catch (SecurityException e) { - e.printStackTrace(); - throw Throwables.propagate(e); - } - } -} diff --git a/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java b/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java index 5e4231ec61..bf69ea3f23 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java +++ b/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java @@ -28,17 +28,18 @@ import com.google.common.collect.Maps; import net.minecraft.entity.monster.EntityZombieVillager; import org.apache.commons.lang3.Validate; -import net.minecraft.entity.monster.EntityZombie; import net.minecraft.entity.passive.EntityVillager; import net.minecraft.entity.passive.EntityVillager.ITradeList; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.registry.RegistryNamespaced; import net.minecraft.world.gen.structure.StructureComponent; import net.minecraft.world.gen.structure.StructureVillagePieces; import net.minecraft.world.gen.structure.StructureVillagePieces.PieceWeight; import net.minecraft.world.gen.structure.StructureVillagePieces.Village; import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; -import net.minecraftforge.fml.common.registry.RegistryBuilder; +import net.minecraftforge.registries.GameData; +import net.minecraftforge.registries.IForgeRegistryEntry; import javax.annotation.Nullable; @@ -47,7 +48,6 @@ import javax.annotation.Nullable; */ public class VillagerRegistry { - public static final ResourceLocation PROFESSIONS = new ResourceLocation("minecraft:villagerprofessions"); @ObjectHolder("minecraft:farmer") public static final VillagerProfession FARMER = null; private static final VillagerRegistry INSTANCE = new VillagerRegistry(); @@ -128,21 +128,14 @@ public class VillagerRegistry return instance().villageCreationHandlers.get(villagePiece.villagePieceClass).buildComponent(villagePiece, startPiece, pieces, random, p1, p2, p3, facing, p5); } - public void register(VillagerProfession prof) - { - register(prof, -1); - } + RegistryNamespaced REGISTRY = GameData.getWrapper(VillagerProfession.class); private void register(VillagerProfession prof, int id) { - professions.register(id, prof.name, prof); + REGISTRY.register(id, prof.name, prof); } private boolean hasInit = false; - private FMLControlledNamespacedRegistry professions = (FMLControlledNamespacedRegistry)new RegistryBuilder().setName(PROFESSIONS).setType(VillagerProfession.class).setIDRange(0, 1024).enableDelegates().create(); - public IForgeRegistry getRegistry() { return this.professions; } - - private void init() { if (hasInit) @@ -208,11 +201,6 @@ public class VillagerRegistry private ResourceLocation zombie; private List careers = Lists.newArrayList(); - @Deprecated //Use Zombie texture - public VillagerProfession(String name, String texture) - { - this (name, texture, "minecraft:textures/entity/zombie_villager/zombie_villager.png"); - } public VillagerProfession(String name, String texture, String zombie) { this.name = new ResourceLocation(name); @@ -327,8 +315,7 @@ public class VillagerRegistry */ public static void setRandomProfession(EntityVillager entity, Random rand) { - List entries = INSTANCE.professions.getValues(); - entity.setProfession(entries.get(rand.nextInt(entries.size()))); + entity.setProfession(INSTANCE.REGISTRY.getRandomObject(rand)); } @@ -341,8 +328,8 @@ public class VillagerRegistry //Below this is INTERNAL USE ONLY DO NOT USE MODDERS public static void onSetProfession(EntityVillager entity, int network) { - VillagerProfession prof = INSTANCE.professions.getObjectById(network); - if (prof == null || INSTANCE.professions.getId(prof) != network) + VillagerProfession prof = INSTANCE.REGISTRY.getObjectById(network); + if (prof == null || INSTANCE.REGISTRY.getIDForObject(prof) != network) { throw new RuntimeException("Attempted to set villager profession to unregistered profession: " + network + " " + prof); } @@ -353,8 +340,8 @@ public class VillagerRegistry public static void onSetProfession(EntityZombieVillager entity, int network) { - VillagerProfession prof = INSTANCE.professions.getObjectById(network); - if (prof == null && network != -1 || INSTANCE.professions.getId(prof) != network) + VillagerProfession prof = INSTANCE.REGISTRY.getObjectById(network); + if (prof == null && network != -1 || INSTANCE.REGISTRY.getIDForObject(prof) != network) { throw new RuntimeException("Attempted to set villager profession to unregistered profession: " + network + " " + prof); } @@ -363,8 +350,8 @@ public class VillagerRegistry entity.setForgeProfession(prof); } - @Deprecated public static VillagerProfession getById(int network){ return INSTANCE.professions.getObjectById(network); } - @Deprecated public static int getId(@Nullable VillagerProfession prof){ return INSTANCE.professions.getId(prof); } + @Deprecated public static VillagerProfession getById(int network){ return INSTANCE.REGISTRY.getObjectById(network); } + @Deprecated public static int getId(@Nullable VillagerProfession prof){ return INSTANCE.REGISTRY.getIDForObject(prof); } //TODO: Figure out a good generic system for this. Put on hold for Patches. diff --git a/src/main/java/net/minecraftforge/oredict/OreDictionary.java b/src/main/java/net/minecraftforge/oredict/OreDictionary.java index 4e90d3034d..5dd95ec141 100644 --- a/src/main/java/net/minecraftforge/oredict/OreDictionary.java +++ b/src/main/java/net/minecraftforge/oredict/OreDictionary.java @@ -53,7 +53,8 @@ import com.google.common.collect.Maps; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.eventhandler.Event; -import net.minecraftforge.fml.common.registry.GameData; +import net.minecraftforge.fml.common.registry.ForgeRegistries; +import net.minecraftforge.registries.GameData; import javax.annotation.Nonnull; @@ -470,7 +471,7 @@ public class OreDictionary } else { - id = GameData.getItemRegistry().getId(registryName); + id = Item.REGISTRY.getIDForObject(stack.getItem().delegate.get()); } List ids = stackToId.get(id); if (ids != null) set.addAll(ids); @@ -636,7 +637,7 @@ public class OreDictionary } else { - hash = GameData.getItemRegistry().getId(registryName); + hash = Item.REGISTRY.getIDForObject(ore.getItem().delegate.get()); } if (ore.getItemDamage() != WILDCARD_VALUE) { @@ -702,7 +703,7 @@ public class OreDictionary } else { - hash = GameData.getItemRegistry().getId(name); + hash = Item.REGISTRY.getIDForObject(ore.getItem().delegate.get()); } if (ore.getItemDamage() != WILDCARD_VALUE) { diff --git a/src/main/java/net/minecraftforge/oredict/ShapedOreRecipe.java b/src/main/java/net/minecraftforge/oredict/ShapedOreRecipe.java index 8659d976a7..5834f759db 100644 --- a/src/main/java/net/minecraftforge/oredict/ShapedOreRecipe.java +++ b/src/main/java/net/minecraftforge/oredict/ShapedOreRecipe.java @@ -32,8 +32,8 @@ import net.minecraft.world.World; import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.crafting.CraftingHelper; import net.minecraftforge.common.crafting.CraftingHelper.ShapedPrimer; +import net.minecraftforge.registries.IForgeRegistryEntry; import net.minecraftforge.common.crafting.JsonContext; -import net.minecraftforge.fml.common.registry.IForgeRegistryEntry; import java.util.Map; import java.util.Set; diff --git a/src/main/java/net/minecraftforge/oredict/ShapelessOreRecipe.java b/src/main/java/net/minecraftforge/oredict/ShapelessOreRecipe.java index 7dc1906ffd..66da171aec 100644 --- a/src/main/java/net/minecraftforge/oredict/ShapelessOreRecipe.java +++ b/src/main/java/net/minecraftforge/oredict/ShapelessOreRecipe.java @@ -34,7 +34,7 @@ import net.minecraft.world.World; import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.crafting.CraftingHelper; import net.minecraftforge.common.crafting.JsonContext; -import net.minecraftforge.fml.common.registry.IForgeRegistryEntry; +import net.minecraftforge.registries.IForgeRegistryEntry; import javax.annotation.Nonnull; diff --git a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java new file mode 100644 index 0000000000..758e202da4 --- /dev/null +++ b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java @@ -0,0 +1,657 @@ +package net.minecraftforge.registries; + +import java.lang.ref.WeakReference; +import java.util.BitSet; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.annotation.Nullable; + +import org.apache.commons.lang3.Validate; + +import java.util.Set; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; +import com.google.common.collect.Sets; + +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.event.RegistryEvent.MissingMappings; +import net.minecraftforge.fml.common.FMLLog; +import net.minecraftforge.fml.relauncher.ReflectionHelper; + +public class ForgeRegistry> implements IForgeRegistryInternal, IForgeRegistryModifiable +{ + public static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("forge.debugRegistryEntries", "false")); + private final RegistryManager stage; + private final BiMap ids = HashBiMap.create(); + private final BiMap names = HashBiMap.create(); + private final Class superType; + private final Map aliases = Maps.newHashMap(); + private final Map slaves = Maps.newHashMap(); + private final ResourceLocation defaultKey; + private final CreateCallback create; + private final AddCallback add; + private final ClearCallback clear; + private final BitSet availabilityMap; + private final Set dummies = Sets.newHashSet(); + private final Set blocked = Sets.newHashSet(); + private final Multimap> overrides = ArrayListMultimap.create(); + private final DummyFactory dummyFactory; + private final boolean isDelegated; + private final int min; + private final int max; + private final boolean allowOverrides; + private final boolean isModifiable; + + private V defaultValue = null; + boolean isFrozen = false; + + ForgeRegistry(Class superType, ResourceLocation defaultKey, int min, int max, @Nullable CreateCallback create, @Nullable AddCallback add, @Nullable ClearCallback clear, RegistryManager stage, boolean allowOverrides, boolean isModifiable, @Nullable DummyFactory dummyFactory) + { + this.stage = stage; + this.superType = superType; + this.defaultKey = defaultKey; + this.min = min; + this.max = max; + this.availabilityMap = new BitSet(Math.min(max + 1, 0x0FFF)); + this.create = create; + this.add = add; + this.clear = clear; + this.isDelegated = IForgeRegistryEntry.Impl.class.isAssignableFrom(superType); //TODO: Make this IDelegatedRegistryEntry? + this.allowOverrides = allowOverrides; + this.isModifiable = isModifiable; + this.dummyFactory = dummyFactory; + if (this.create != null) + this.create.onCreate(this, stage); + } + + + @Override + public void register(V value) + { + add(-1, value); + } + + @Override + public Iterator iterator() { + return new Iterator() + { + Iterator itr = names.values().iterator(); + @Override + public boolean hasNext() + { + return itr.hasNext(); + } + + @Override + public V next() + { + return itr.next(); + } + //TODO add remove support? + }; + } + + @Override + public Class getRegistrySuperType() + { + return superType; + } + + @Override + public void registerAll(@SuppressWarnings("unchecked") V... values) + { + for (V value : values) + register(value); + } + + @Override + public boolean containsKey(ResourceLocation key) + { + while (key != null) + { + if (this.names.containsKey(key)) + return true; + key = this.aliases.get(key); + } + return false; + } + + @Override + public boolean containsValue(V value) + { + return this.names.containsValue(value); + } + + @Override + public V getValue(ResourceLocation key) + { + V ret = this.names.get(key); + key = this.aliases.get(key); + while (ret == null && key != null) + { + ret = this.names.get(key); + key = this.aliases.get(key); + } + return ret == null ? this.defaultValue : ret; + } + + @Override + public ResourceLocation getKey(V value) + { + return this.names.inverse().get(value); + } + + @Override + public Set getKeys() + { + return ImmutableSet.copyOf(this.names.keySet()); + } + + @Override + public List getValues() + { + return ImmutableList.copyOf(this.names.values()); + } + + @Override + public Set> getEntries() + { + return ImmutableSet.copyOf(this.names.entrySet()); + } + + @SuppressWarnings("unchecked") + @Override + public T getSlaveMap(ResourceLocation name, Class type) + { + return (T)this.slaves.get(name); + } + + @SuppressWarnings("unchecked") + @Override + public void setSlaveMap(ResourceLocation name, Object obj) + { + ((Map)this.slaves).put(name, obj); + } + + public int getID(V value) + { + Integer ret = this.ids.inverse().get(value); + if (ret == null && this.defaultValue != null) + ret = this.ids.inverse().get(this.defaultValue); + return ret == null ? -1 : ret.intValue(); + } + + public int getID(ResourceLocation name) + { + return getID(this.names.get(name)); + } + + public V getValue(int id) + { + V ret = this.ids.get(id); + return ret == null ? this.defaultValue : ret; + } + + void validateKey() + { + if (this.defaultKey != null) + Validate.notNull(this.defaultValue, "Missing default of ForgeRegistry: " + this.defaultKey + " Type: " + this.superType); + } + + ForgeRegistry copy(RegistryManager stage) + { + return new ForgeRegistry(superType, defaultKey, min, max, create, add, clear, stage, allowOverrides, isModifiable, dummyFactory); + } + + int add(int id, V value) + { + ResourceLocation key = value == null ? null : value.getRegistryName(); + Preconditions.checkNotNull(key, "Can't use a null-name for the registry, object %s.", value); + Preconditions.checkNotNull(value, "Can't add null-object to the registry, name %s.", key); + + int idToUse = id; + if (idToUse < 0 || availabilityMap.get(idToUse)) + idToUse = availabilityMap.nextClearBit(min); + + if (idToUse > max) + throw new RuntimeException(String.format("Invalid id %d - maximum id range exceeded.", idToUse)); + + V oldEntry = getRaw(key); + if (oldEntry == value) // already registered, return prev registration's id + { + FMLLog.bigWarning("The object %s has been registered twice for the same name %s.", value, key); + return this.getID(value); + } + if (oldEntry != null) // duplicate name + { + if (!this.allowOverrides) + throw new IllegalArgumentException(String.format("The name %s has been registered twice, for %s and %s.", key, getRaw(key), value)); + idToUse = this.getID(oldEntry); + } + + Integer foundId = this.ids.inverse().get(value); //Is this ever possible to trigger with otherThing being different? + if (foundId != null) + { + V otherThing = this.ids.get(foundId); + throw new IllegalArgumentException(String.format("The object %s{%x} has been registered twice, using the names %s and %s. (Other object at this id is %s{%x})", value, System.identityHashCode(value), getKey(value), key, otherThing, System.identityHashCode(otherThing))); + } + + if (isLocked()) + throw new IllegalStateException(String.format("The object %s (name %s) is being added too late.", value, key)); + + if (defaultKey != null && defaultKey.equals(key)) + { + if (this.defaultValue != null) + throw new IllegalStateException(String.format("Attemped to override already set default value. This is not allowed: The object %s (name %s)", value, key)); + this.defaultValue = value; + } + + this.names.put(key, value); + this.ids.put(idToUse, value); + this.availabilityMap.set(idToUse); + + if (isDelegated) + { + getDelegate(value).setName(key); + if (oldEntry != null) + { + this.overrides.put(key, new WeakReference(oldEntry)); + if (this.stage == RegistryManager.ACTIVE) + getDelegate(oldEntry).changeReference(value); + } + } + + if (this.add != null) + this.add.onAdd(this, this.stage, idToUse, value); + + if (this.dummies.remove(key) && DEBUG) + FMLLog.fine("Registry Dummy Remove: %s", key); + + if (DEBUG) + FMLLog.finer("Registry add: %s %d %s (req. id %d)", key, idToUse, value, id); + + return idToUse; + } + + private V getRaw(ResourceLocation key) + { + V ret = this.names.get(key); + key = this.aliases.get(key); + while (ret == null && key != null) + { + ret = this.names.get(key); + key = this.aliases.get(key); + } + return ret; + } + + @Deprecated //Public for ByteByfUtils only! + public V getRaw(int id) + { + return this.ids.get(id); + } + + void addAlias(ResourceLocation from, ResourceLocation to) + { + if (this.isLocked()) + throw new IllegalStateException(String.format("Attempted to register the alias %s -> %s to late", from, to)); + this.aliases.put(from, to); + if (DEBUG) + FMLLog.finer("Registry alias: %s -> %s", from, to); + } + + void addDummy(ResourceLocation key) + { + if (this.isLocked()) + throw new IllegalStateException(String.format("Attempted to register the dummy %s to late", key)); + this.dummies.add(key); + if (DEBUG) + FMLLog.finer("Registry dummy: %s -> %s", key); + } + + private RegistryDelegate getDelegate(V thing) + { + if (isDelegated) + return (RegistryDelegate)((IForgeRegistryEntry.Impl)thing).delegate; + else + throw new IllegalStateException("Tried to get existing delegate from registry that is not delegated."); + } + + void resetDelegates() + { + if (!this.isDelegated) + return; + + for (V value : this) + getDelegate(value).changeReference(value); + + Iterator>> itr = this.overrides.entries().iterator(); + while (itr.hasNext()) + { + Entry> next = itr.next(); + V value = next.getValue().get(); + if (value == null) + itr.remove(); + else + getDelegate(value).changeReference(value); + } + } + + V getDefault() + { + return this.defaultValue; + } + + boolean isDummied(ResourceLocation key) + { + return this.dummies.contains(key); + } + + + void validateContent(ResourceLocation registryName) + { + try + { + ReflectionHelper.findMethod(BitSet.class, "trimToSize", null).invoke(this.availabilityMap); + } + catch (Exception e) + { + //We don't care... Just a micro-optimization + } + + for (V obj : this) + { + int id = getID(obj); + ResourceLocation name = getKey(obj); + + // name lookup failed -> obj is not in the obj<->name map + if (name == null) + throw new IllegalStateException(String.format("Registry entry for %s %s, id %d, doesn't yield a name.", registryName, obj, id)); + + // id is too high + if (id > max) + throw new IllegalStateException(String.format("Registry entry for %s %s, name %s uses the too large id %d.", registryName, obj, name, id)); + + // id -> obj lookup is inconsistent + if (getValue(id) != obj) + throw new IllegalStateException(String.format("Registry entry for id %d, name %s, doesn't yield the expected %s %s.", id, name, registryName, obj)); + + // name -> obj lookup is inconsistent + if (getValue(name) != obj) + throw new IllegalStateException(String.format("Registry entry for name %s, id %d, doesn't yield the expected %s %s.", name, id, registryName, obj)); + + // name -> id lookup is inconsistent + if (getID(name) != id) + throw new IllegalStateException(String.format("Registry entry for name %s doesn't yield the expected id %d.", name, id)); + + /* + // entry is blocked, thus should be empty + if (blockedIds.contains(id)) + throw new IllegalStateException(String.format("Registry entry for %s %s, id %d, name %s, marked as dangling.", registryName, obj, id, name)); + */ + } + } + + void sync(ResourceLocation name, ForgeRegistry from) + { + if (from.superType != this.superType) + throw new IllegalArgumentException("Attempted to copy to incompatible registry: " + name + " " + from.superType + " -> " + this.superType); + + if (this.clear != null) + this.clear.onClear(this, stage); + + /* -- Should never need to be copied + this.defaultKey = from.defaultKey; + this.max = from.max; + this.min = from.min; + */ + this.aliases.clear(); + from.aliases.forEach((f, t) -> this.addAlias(f, t)); + this.dummies.clear(); + from.dummies.forEach(dummy -> this.addDummy(dummy)); + + this.ids.clear(); + this.names.clear(); + this.availabilityMap.clear(0, this.availabilityMap.length()); + this.isFrozen = false; + + boolean errored = false; + + for (Entry entry : from.names.entrySet()) + { + int id = from.ids.inverse().get(entry.getKey()); + int realId = add(id, entry.getValue()); + if (id != realId && id != -1) + { + FMLLog.warning("Registered object did not get ID it asked for. Name: {} Type: {} Expected: {} Got: {}", entry.getKey(), this.getRegistrySuperType().getName(), id, realId); + errored = true; + } + } + + if (errored) + throw new RuntimeException("One of more entry values did not copy to the correct id. Check log for details!"); + } + + + + @Override + public void clear() + { + if (!this.isModifiable) + throw new UnsupportedOperationException("Attempted to clear a non-modifiable Forge Registry"); + + if (this.isLocked()) + throw new IllegalStateException("Attempted to clear the registry to late."); + + if (this.clear != null) + this.clear.onClear(this, stage); + + + this.aliases.clear(); + this.dummies.clear(); + + this.ids.clear(); + this.names.clear(); + this.availabilityMap.clear(0, this.availabilityMap.length()); + } + + @Override + public V remove(ResourceLocation key) + { + if (!this.isModifiable) + throw new UnsupportedOperationException("Attempted to remove from a non-modifiable Forge Registry"); + + if (this.isLocked()) + throw new IllegalStateException("Attempted to remove from the registry to late."); + + V value = this.names.remove(key); + if (value != null) + { + Integer id = this.ids.inverse().remove(value); + if (id == null) + throw new IllegalStateException("Removed a entry that did not have an associated id: " + key + " " + value.toString() + " This should never happen unless hackery!"); + } + + return value; + } + + void block(int id) + { + this.blocked.add(id); + this.availabilityMap.set(id); + } + + @Override + public boolean isLocked() + { + return this.isFrozen; + } + + public void freeze() + { + this.isFrozen = true; + } + + RegistryEvent.Register getRegisterEvent(ResourceLocation name) + { + return new RegistryEvent.Register(name, this); + } + + void dump(ResourceLocation name) + { + List ids = Lists.newArrayList(); + getKeys().forEach(n -> ids.add(getID(n))); + + Collections.sort(ids); + + FMLLog.finer("Registry Name : {}", name); + ids.forEach(id -> FMLLog.finer("Registry: %d %s %s", id, getKey(getValue(id)), getValue(id))); + } + + public void loadIds(Map ids, Map missing, Map remapped, ForgeRegistry old, ResourceLocation name) + { + for (Map.Entry entry : ids.entrySet()) + { + ResourceLocation itemName = entry.getKey(); + int newId = entry.getValue(); + int currId = old.getID(itemName); + + if (currId == -1) + { + FMLLog.info("Found a missing id from the world %s", itemName); + missing.put(itemName, newId); + continue; // no block/item -> nothing to add + } + else if (currId != newId) + { + FMLLog.fine("Fixed %s id mismatch %s: %d (init) -> %d (map).", name, itemName, currId, newId); + remapped.put(itemName, new Integer[] {currId, newId}); + } + V obj = old.getRaw(itemName); + Preconditions.checkState(obj != null, "objectKey has an ID but no object. Reflection/ASM hackery? Registry bug?"); + + // Register all overrides so new registry has the full list so we can update delegates later + old.overrides.get(obj.getRegistryName()).stream() + .filter(e -> e.get() != null) + .forEach(e -> add(newId, e.get())); + + add(newId, obj); + } + } + + boolean markDummy(ResourceLocation key, int id) + { + if (this.dummyFactory == null) + return false; + + V dummy = this.dummyFactory.createDummy(key); + if (DEBUG) + FMLLog.finer("Registry Dummy Add: %s %d -> %s", key, id, dummy); + + int realId = this.add(id, dummy); + if (realId != id) + FMLLog.warning("Registered object did not get ID it asked for. Name: {} Type: {} Expected: {} Got: {}", key, dummy.getRegistryType().getName(), id, realId); + this.dummies.add(key); + + return true; + } + + //Public for tests + public Snapshot makeSnapshot() + { + Snapshot ret = new Snapshot(); + this.ids.forEach((id, value) -> ret.ids.put(getKey(value), id)); + this.aliases.forEach((from, to) -> ret.aliases.put(from, to)); + this.blocked.forEach(id -> ret.blocked.add(id)); + this.dummies.forEach(name -> ret.dummied.add(name)); + return ret; + } + + public static class Snapshot + { + public final Map ids = Maps.newHashMap(); + public final Map aliases = Maps.newHashMap(); + public final Set blocked = Sets.newHashSet(); + public final Set dummied = Sets.newHashSet(); + } + + public MissingMappings getMissingEvent(ResourceLocation name, Map map) + { + List> lst = Lists.newArrayList(); + map.forEach((rl, id) -> lst.add(new MissingMappings.Mapping(this, rl, id))); + return new MissingMappings(name, this, lst); + } + + void processMissingEvent(ResourceLocation name, ForgeRegistry pool, List> mappings, Map missing, Map remaps, Collection defaulted, Collection failed) + { + FMLLog.fine("Processing missing event for %s:", name); + int ignored = 0; + + for (MissingMappings.Mapping remap : mappings) + { + MissingMappings.Action action = remap.getAction(); + + if (action == MissingMappings.Action.REMAP) + { + // entry re-mapped, finish the registration with the new name/object, but the old id + int currId = getID(remap.getTarget()); + ResourceLocation newName = pool.getKey(remap.getTarget()); + FMLLog.fine(" Remapping %s -> %s.", remap.key, newName); + + missing.remove(remap.key); + //I don't think this will work, but I dont think it ever worked.. the item is already in the map with a different id... we want to fix that.. + int realId = this.add(remap.id, remap.getTarget()); + if (realId != remap.id) + FMLLog.warning("Registered object did not get ID it asked for. Name: {} Type: {} Expected: {} Got: {}", newName, this.getRegistrySuperType(), remap.id, realId); + this.addAlias(remap.key, newName); + + + if (currId != realId) + { + FMLLog.info(" Fixed id mismatch %s: %d (init) -> %d (map).", newName, currId, realId); + remaps.put(newName, new Integer[] {currId, realId}); + } + } + else + { + // block item missing, warn as requested and block the id + if (action == MissingMappings.Action.DEFAULT) + { + defaulted.add(remap.key); + } + else if (action == MissingMappings.Action.IGNORE) + { + FMLLog.fine(" Ignoring %s", remap.key); + ignored++; + } + else if (action == MissingMappings.Action.FAIL) + { + FMLLog.fine(" Failing %s!", remap.key); + failed.add(remap.key); + } + else if (action == MissingMappings.Action.WARN) + { + FMLLog.warning(" %s may cause world breakage!", remap.key); + } + this.block(remap.id); + } + } + + if (failed.isEmpty() && ignored > 0) + FMLLog.fine("There were %d missing mappings that have been ignored", ignored); + } +} diff --git a/src/main/java/net/minecraftforge/registries/GameData.java b/src/main/java/net/minecraftforge/registries/GameData.java new file mode 100644 index 0000000000..90fbc424fe --- /dev/null +++ b/src/main/java/net/minecraftforge/registries/GameData.java @@ -0,0 +1,670 @@ +/* + * Minecraft Forge + * Copyright (c) 2016. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.registries; + +import com.google.common.collect.HashBiMap; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionType; +import net.minecraft.util.ObjectIntIdentityMap; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.registry.RegistryNamespaced; +import net.minecraft.util.registry.RegistryNamespacedDefaultedByKey; +import net.minecraft.world.biome.Biome; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.event.RegistryEvent.MissingMappings; +import net.minecraftforge.fml.common.EnhancedRuntimeException; +import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.fml.common.FMLLog; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.StartupQuery; +import net.minecraftforge.fml.common.ZipperUtil; +import net.minecraftforge.fml.common.registry.EntityEntry; +import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.BiMap; + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.Validate; +import org.apache.logging.log4j.Level; + +/** + * INTERNAL ONLY + * MODDERS SHOULD HAVE NO REASON TO USE THIS CLASS + */ +public class GameData +{ + public static final ResourceLocation BLOCKS = new ResourceLocation("minecraft:blocks"); + public static final ResourceLocation ITEMS = new ResourceLocation("minecraft:items"); + public static final ResourceLocation POTIONS = new ResourceLocation("minecraft:potions"); + public static final ResourceLocation BIOMES = new ResourceLocation("minecraft:biomes"); + public static final ResourceLocation SOUNDEVENTS = new ResourceLocation("minecraft:soundevents"); + public static final ResourceLocation POTIONTYPES = new ResourceLocation("minecraft:potiontypes"); + public static final ResourceLocation ENCHANTMENTS = new ResourceLocation("minecraft:enchantments"); + public static final ResourceLocation ENTITIES = new ResourceLocation("minecraft:entities"); + public static final ResourceLocation RECIPES = new ResourceLocation("minecraft:recipes"); + public static final ResourceLocation PROFESSIONS = new ResourceLocation("minecraft:villagerprofessions"); + private static final int MAX_BLOCK_ID = 4095; + private static final int MIN_ITEM_ID = MAX_BLOCK_ID + 1; + private static final int MAX_ITEM_ID = 31999; + private static final int MAX_POTION_ID = 255; // SPacketEntityEffect sends bytes, we can only use 255 + private static final int MAX_BIOME_ID = 255; // Maximum number in a byte in the chunk + private static final int MAX_SOUND_ID = Integer.MAX_VALUE >> 5; // Varint (SPacketSoundEffect) + private static final int MAX_POTIONTYPE_ID = Integer.MAX_VALUE >> 5; // Int (SPacketEffect) + private static final int MAX_ENCHANTMENT_ID = Short.MAX_VALUE - 1; // Short - serialized as a short in ItemStack NBTs. + private static final int MAX_ENTITY_ID = Integer.MAX_VALUE >> 5; // Varint (SPacketSpawnMob) + private static final int MAX_RECIPE_ID = Integer.MAX_VALUE >> 5; // Varint CPacketRecipeInfo/SPacketRecipeBook + private static final int MAX_PROFESSION_ID = 1024; //TODO: Is this serialized anywhere anymore? + + private static final ResourceLocation BLOCK_TO_ITEM = new ResourceLocation("minecraft:blocktoitemmap"); + private static final ResourceLocation BLOCKSTATE_TO_ID = new ResourceLocation("minecraft:blockstatetoid"); + private static boolean hasInit = false; + private static final boolean DISABLE_VANILLA_REGISTRIES = Boolean.parseBoolean(System.getProperty("forge.disableVanillaGameData", "false")); // Use for unit tests/debugging + + static { + init(); + } + + public static void init() + { + if ( DISABLE_VANILLA_REGISTRIES) + { + FMLLog.bigWarning("DISABELING VANILLA REGISTRY CREATION AS PER SYSTEM VARIABLE SETTING! forge.disableVanillaGameData"); + return; + } + if (hasInit) + return; + hasInit = true; + makeRegistry(BLOCKS, Block.class, MAX_BLOCK_ID, new ResourceLocation("air")).addCallback(BlockCallbacks.INSTANCE).create(); + makeRegistry(ITEMS, Item.class, MIN_ITEM_ID, MAX_ITEM_ID).addCallback(ItemCallbacks.INSTANCE).create(); + makeRegistry(POTIONS, Potion.class, MAX_POTION_ID).create(); + makeRegistry(BIOMES, Biome.class, MAX_BIOME_ID).create(); + makeRegistry(SOUNDEVENTS, SoundEvent.class, MAX_SOUND_ID).create(); + makeRegistry(POTIONTYPES, PotionType.class, MAX_POTIONTYPE_ID, new ResourceLocation("water")).create(); + makeRegistry(ENCHANTMENTS, Enchantment.class, MAX_ENCHANTMENT_ID).create(); + makeRegistry(RECIPES, IRecipe.class, MAX_RECIPE_ID).disableSaving().create(); + makeRegistry(PROFESSIONS, VillagerProfession.class, MAX_PROFESSION_ID).create(); + entityRegistry = (ForgeRegistry)makeRegistry(ENTITIES, EntityEntry.class, MAX_ENTITY_ID).addCallback(EntityCallbacks.INSTANCE).create(); + } + + private static > RegistryBuilder makeRegistry(ResourceLocation name, Class type, int min, int max) + { + return new RegistryBuilder().setName(name).setType(type).setIDRange(min, max).addCallback(new NamespacedWrapper.Factory()); + } + private static > RegistryBuilder makeRegistry(ResourceLocation name, Class type, int max) + { + return new RegistryBuilder().setName(name).setType(type).setMaxID(max).addCallback(new NamespacedWrapper.Factory()); + } + private static > RegistryBuilder makeRegistry(ResourceLocation name, Class type, int max, ResourceLocation _default) + { + return new RegistryBuilder().setName(name).setType(type).setMaxID(max).addCallback(new NamespacedDefaultedWrapper.Factory()).setDefaultKey(_default); + } + + public static > RegistryNamespacedDefaultedByKey getWrapperDefaulted(Class cls) + { + IForgeRegistry reg = GameRegistry.findRegistry(cls); + Validate.notNull(reg, "Attempted to get vanilla wrapper for unknown registry: " + cls.toString()); + @SuppressWarnings("unchecked") + RegistryNamespacedDefaultedByKey ret = reg.getSlaveMap(NamespacedDefaultedWrapper.Factory.ID, NamespacedDefaultedWrapper.class); + Validate.notNull(reg, "Attempted to get vanilla wrapper for registry created incorrectly: " + cls.toString()); + return ret; + } + + public static > RegistryNamespaced getWrapper(Class cls) + { + IForgeRegistry reg = GameRegistry.findRegistry(cls); + Validate.notNull(reg, "Attempted to get vanilla wrapper for unknown registry: " + cls.toString()); + @SuppressWarnings("unchecked") + RegistryNamespaced ret = reg.getSlaveMap(NamespacedWrapper.Factory.ID, NamespacedWrapper.class); + Validate.notNull(reg, "Attempted to get vanilla wrapper for registry created incorrectly: " + cls.toString()); + return ret; + } + + @SuppressWarnings("unchecked") + public static BiMap getBlockItemMap() + { + return GameRegistry.findRegistry(Item.class).getSlaveMap(BLOCK_TO_ITEM, BiMap.class); + } + + @SuppressWarnings("unchecked") + public static ObjectIntIdentityMap getBlockStateIDMap() + { + return GameRegistry.findRegistry(Block.class).getSlaveMap(BLOCKSTATE_TO_ID, ObjectIntIdentityMap.class); + } + + public static > K register_impl(K value) + { + Validate.notNull(value, "Attempted to register a null object"); + Validate.notNull(value.getRegistryName(), String.format("Attempt to register object without having set a registry name %s (type %s)", value, value.getClass().getName())); + final IForgeRegistry registry = GameRegistry.findRegistry(value.getRegistryType()); + Validate.notNull(registry, "Attempted to registry object without creating registry first: " + value.getRegistryType().getName()); + registry.register(value); + return value; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static void vanillaSnapshot() + { + FMLLog.fine("Creating vanilla freeze snapshot"); + for (Map.Entry>> r : RegistryManager.ACTIVE.registries.entrySet()) + { + final Class clazz = RegistryManager.ACTIVE.getSuperType(r.getKey()); + loadRegistry(r.getKey(), RegistryManager.ACTIVE, RegistryManager.VANILLA, clazz, true); + } + RegistryManager.VANILLA.registries.forEach((name, reg) -> reg.validateContent(name)); + RegistryManager.ACTIVE.registries.forEach((name, reg) -> reg.freeze()); + FMLLog.fine("Vanilla freeze snapshot created"); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static void freezeData() + { + FMLLog.fine("Freezing registries"); + for (Map.Entry>> r : RegistryManager.ACTIVE.registries.entrySet()) + { + final Class clazz = RegistryManager.ACTIVE.getSuperType(r.getKey()); + loadRegistry(r.getKey(), RegistryManager.ACTIVE, RegistryManager.FROZEN, clazz, true); + } + RegistryManager.FROZEN.registries.forEach((name, reg) -> reg.validateContent(name)); + RegistryManager.ACTIVE.registries.forEach((name, reg) -> reg.freeze()); + FMLLog.fine("All registries frozen"); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static void revertToFrozen() + { + if (RegistryManager.FROZEN.registries.isEmpty()) + { + FMLLog.warning("Can't revert to frozen GameData state without freezing first."); + return; + } + + FMLLog.fine("Reverting to frozen data state."); + for (Map.Entry>> r : RegistryManager.ACTIVE.registries.entrySet()) + { + final Class clazz = RegistryManager.ACTIVE.getSuperType(r.getKey()); + loadRegistry(r.getKey(), RegistryManager.FROZEN, RegistryManager.ACTIVE, clazz, true); + } + // the id mapping has reverted, fire remap events for those that care about id changes + Loader.instance().fireRemapEvent(ImmutableMap.of(), ImmutableMap.of(), true); + + // the id mapping has reverted, ensure we sync up the object holders + ObjectHolderRegistry.INSTANCE.applyObjectHolders(); + FMLLog.fine("Frozen state restored."); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static void revert(RegistryManager state, ResourceLocation registry, boolean lock) + { + FMLLog.fine("Reverting {} to {}", registry, state.getName()); + final Class clazz = RegistryManager.ACTIVE.getSuperType(registry); + loadRegistry(registry, RegistryManager.FROZEN, RegistryManager.ACTIVE, clazz, lock); + FMLLog.fine("Reverting complete"); + } + + //Lets us clear the map so we can rebuild it. + static class ClearableObjectIntIdentityMap extends ObjectIntIdentityMap + { + void clear() + { + this.identityMap.clear(); + this.objectList.clear(); + } + } + + + private static class BlockCallbacks implements IForgeRegistry.AddCallback, IForgeRegistry.ClearCallback, IForgeRegistry.CreateCallback, IForgeRegistry.DummyFactory + { + static final BlockCallbacks INSTANCE = new BlockCallbacks(); + + @SuppressWarnings("deprecation") + @Override + public void onAdd(IForgeRegistryInternal owner, RegistryManager stage, int id, Block block) + { + @SuppressWarnings("unchecked") + ClearableObjectIntIdentityMap blockstateMap = owner.getSlaveMap(BLOCKSTATE_TO_ID, ClearableObjectIntIdentityMap.class); + + //So, due to blocks having more in-world states then metadata allows, we have to turn the map into a semi-milti-bimap. + //We can do this however because the implementation of the map is last set wins. So we can add all states, then fix the meta bimap. + //Multiple states -> meta. But meta to CORRECT state. + + final boolean[] usedMeta = new boolean[16]; //Hold a list of known meta from all states. + for (IBlockState state : block.getBlockState().getValidStates()) + { + final int meta = block.getMetaFromState(state); + blockstateMap.put(state, id << 4 | meta); //Add ALL the things! + usedMeta[meta] = true; + } + + for (int meta = 0; meta < 16; meta++) + { + if (usedMeta[meta]) + blockstateMap.put(block.getStateFromMeta(meta), id << 4 | meta); // Put the CORRECT thing! + } + } + + @Override + public void onClear(IForgeRegistryInternal owner, RegistryManager stage) + { + owner.getSlaveMap(BLOCKSTATE_TO_ID, ClearableObjectIntIdentityMap.class).clear(); + } + + @Override + public void onCreate(IForgeRegistryInternal owner, RegistryManager stage) + { + final ClearableObjectIntIdentityMap idMap = new ClearableObjectIntIdentityMap() + { + @SuppressWarnings("deprecation") + @Override + public int get(IBlockState key) + { + Integer integer = (Integer)this.identityMap.get(key); + // There are some cases where this map is queried to serialize a state that is valid, + //but somehow not in this list, so attempt to get real metadata. Doing this hear saves us 7 patches + if (integer == null && key != null) + integer = this.identityMap.get(key.getBlock().getStateFromMeta(key.getBlock().getMetaFromState(key))); + return integer == null ? -1 : integer.intValue(); + } + }; + owner.setSlaveMap(BLOCKSTATE_TO_ID, idMap); + owner.setSlaveMap(BLOCK_TO_ITEM, HashBiMap.create()); + } + + @Override + public Block createDummy(ResourceLocation key) + { + return new Block(Material.AIR).setUnlocalizedName("air").setRegistryName(key); + } + } + + private static class ItemCallbacks implements IForgeRegistry.AddCallback, IForgeRegistry.ClearCallback, IForgeRegistry.CreateCallback + { + static final ItemCallbacks INSTANCE = new ItemCallbacks(); + + @Override + public void onAdd(IForgeRegistryInternal owner, RegistryManager stage, int id, Item item) + { + if (item instanceof ItemBlock) + { + @SuppressWarnings("unchecked") + BiMap blockToItem = owner.getSlaveMap(BLOCK_TO_ITEM, BiMap.class); + blockToItem.forcePut(((ItemBlock)item).getBlock(), item); + } + } + + @Override + public void onClear(IForgeRegistryInternal owner, RegistryManager stage) + { + owner.getSlaveMap(BLOCK_TO_ITEM, BiMap.class).clear(); + } + + @Override + public void onCreate(IForgeRegistryInternal owner, RegistryManager stage) + { + // We share the blockItem map between items and blocks registries + BiMap map = stage.getRegistry(BLOCKS).getSlaveMap(BLOCK_TO_ITEM, BiMap.class); + owner.setSlaveMap(BLOCK_TO_ITEM, map); + } + } + + + private static ForgeRegistry entityRegistry; + public static ForgeRegistry getEntityRegistry() { return entityRegistry; } + public static void registerEntity(int id, ResourceLocation key, Class clazz, String oldName) + { + RegistryNamespaced reg = getWrapper(EntityEntry.class); + reg.register(id, key, new EntityEntry(clazz, oldName)); + } + + private static class EntityCallbacks implements IForgeRegistry.AddCallback + { + static final EntityCallbacks INSTANCE = new EntityCallbacks(); + + @Override + public void onAdd(IForgeRegistryInternal owner, RegistryManager stage, int id, EntityEntry entry) + { + if (entry.getEgg() != null) + EntityList.ENTITY_EGGS.put(entry.getRegistryName(), entry.getEgg()); + } + } + + private static > void loadRegistry(final ResourceLocation registryName, final RegistryManager from, final RegistryManager to, final Class regType, boolean freeze) + { + ForgeRegistry fromRegistry = from.getRegistry(registryName); + if (fromRegistry == null) + { + ForgeRegistry toRegistry = to.getRegistry(registryName); + if (toRegistry == null) + { + throw new EnhancedRuntimeException("Could not find registry to load: " + registryName){ + private static final long serialVersionUID = 1L; + @Override + protected void printStackTrace(WrappedPrintStream stream) + { + stream.println("Looking For: " + registryName); + stream.println("Found From:"); + for (ResourceLocation name : from.registries.keySet()) + stream.println(" " + name); + stream.println("Found To:"); + for (ResourceLocation name : to.registries.keySet()) + stream.println(" " + name); + } + }; + } + // We found it in to, so lets trust to's state... + // This happens when connecting to a server that doesn't have this registry. + // Such as a 1.8.0 Forge server with 1.8.8+ Forge. + // We must however, re-fire the callbacks as some internal data may be corrupted {potions} + //TODO: With my rework of how registries add callbacks are done.. I don't think this is necessary. + //fire addCallback for each entry + } + else + { + ForgeRegistry toRegistry = to.getRegistry(registryName, from); + toRegistry.sync(registryName, fromRegistry); + if (freeze) + toRegistry.isFrozen = true; + } + } + + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static Multimap injectSnapshot(Map snapshot, boolean injectFrozenData, boolean isLocalWorld) + { + FMLLog.info("Injecting existing registry data into this %s instance", FMLCommonHandler.instance().getEffectiveSide().isServer() ? "server" : "client"); + RegistryManager.ACTIVE.registries.forEach((name, reg) -> reg.validateContent(name)); + RegistryManager.ACTIVE.registries.forEach((name, reg) -> reg.dump(name)); + RegistryManager.ACTIVE.registries.forEach((name, reg) -> reg.resetDelegates()); + + List missingRegs = snapshot.keySet().stream().filter(name -> !RegistryManager.ACTIVE.registries.containsKey(name)).collect(Collectors.toList()); + if (missingRegs.size() > 0) + { + String text = "Forge Mod Loader detected missing/unknown registrie(s).\n\n" + + "There are " + missingRegs.size() + " missing registries in this save.\n" + + "If you continue the missing registries will get removed.\n" + + "This may cause issues, it is advised that you create a world backup before continuing.\n\n" + + "Missing Registries:\n"; + + for (ResourceLocation s : missingRegs) + text += s.toString() + "\n"; + + if (!StartupQuery.confirm(text)) + StartupQuery.abort(); + } + + RegistryManager STAGING = new RegistryManager("STAGING"); + + final Map> remaps = Maps.newHashMap(); + final LinkedHashMap> missing = Maps.newLinkedHashMap(); + // Load the snapshot into the "STAGING" registry + snapshot.entrySet().forEach(e -> + { + final Class clazz = RegistryManager.ACTIVE.getSuperType(e.getKey()); + remaps.put(e.getKey(), Maps.newLinkedHashMap()); + missing.put(e.getKey(), Maps.newHashMap()); + loadPersistentDataToStagingRegistry(RegistryManager.ACTIVE, STAGING, remaps.get(e.getKey()), missing.get(e.getKey()), e.getKey(), e.getValue(), clazz); + }); + + snapshot.entrySet().forEach(e -> + { + snapshot.get(e.getKey()).dummied.forEach(dummy -> + { + Map m = missing.get(e.getKey()); + ForgeRegistry reg = STAGING.getRegistry(e.getKey()); + + // Currently missing locally, we just inject and carry on + if (m.containsKey(dummy)) + { + if (reg.markDummy(dummy, m.get(dummy))) + m.remove(dummy); + } + else if (isLocalWorld) + { + if (ForgeRegistry.DEBUG) + FMLLog.log(Level.DEBUG, "Registry %s: Resuscitating dummy entry %s", e.getKey(), dummy); + } + else + { + // The server believes this is a dummy block identity, but we seem to have one locally. This is likely a conflict + // in mod setup - Mark this entry as a dummy + int id = reg.getID(dummy); + FMLLog.log(Level.WARN, "Registry $s: The ID %d is currently locally mapped - it will be replaced with a dummy for this session", e.getKey(), id); + reg.markDummy(dummy, id); + } + }); + }); + + int count = missing.values().stream().mapToInt(e -> e.size()).sum(); + if (count > 0) + { + FMLLog.fine("There are %d mappings missing - attempting a mod remap", count); + Multimap defaulted = ArrayListMultimap.create(); + Multimap failed = ArrayListMultimap.create(); + + missing.entrySet().stream().filter(e -> e.getValue().size() > 0).forEach(m -> + { + ResourceLocation name = m.getKey(); + ForgeRegistry reg = STAGING.getRegistry(name); + RegistryEvent.MissingMappings event = reg.getMissingEvent(name, m.getValue()); + MinecraftForge.EVENT_BUS.post(event); + + List> lst = event.getAllMappings().stream().filter(e -> e.getAction() == MissingMappings.Action.DEFAULT).collect(Collectors.toList()); + if (!lst.isEmpty()) + { + FMLLog.severe("Unidentified mapping from registry %s", name); + lst.forEach(map -> { + FMLLog.severe(" %s: %d", map.key, map.id); + if (!isLocalWorld) + defaulted.put(name, map.key); + }); + } + event.getAllMappings().stream().filter(e -> e.getAction() == MissingMappings.Action.FAIL).forEach(fail -> failed.put(name, fail.key)); + + final Class clazz = RegistryManager.ACTIVE.getSuperType(name); + processMissing(clazz, name, STAGING, event, m.getValue(), remaps.get(name), defaulted.get(name), failed.get(name)); + }); + + if (!defaulted.isEmpty() && !isLocalWorld) + return defaulted; + + if (!defaulted.isEmpty()) + { + StringBuilder buf = new StringBuilder(); + buf.append("Forge Mod Loader detected missing registry entries.\n\n") + .append("There are ").append(defaulted.size()).append(" missing entries in this save.\n") + .append("If you continue the missing entries will get removed.\n") + .append("A world backup will be automatically created in your saves directory.\n\n"); + + defaulted.asMap().forEach((name, entries) -> + { + buf.append("Missing ").append(name).append(":\n"); + entries.forEach(rl -> buf.append(" ").append(rl).append("\n")); + }); + + boolean confirmed = StartupQuery.confirm(buf.toString()); + if (!confirmed) + StartupQuery.abort(); + + try + { + String skip = System.getProperty("fml.doNotBackup"); + if (skip == null || !"true".equals(skip)) + { + ZipperUtil.backupWorld(); + } + else + { + for (int x = 0; x < 10; x++) + FMLLog.severe("!!!!!!!!!! UPDATING WORLD WITHOUT DOING BACKUP !!!!!!!!!!!!!!!!"); + } + } + catch (IOException e) + { + StartupQuery.notify("The world backup couldn't be created.\n\n" + e); + StartupQuery.abort(); + } + } + + if (!defaulted.isEmpty()) + { + if (isLocalWorld) + FMLLog.severe("There are unidentified mappings in this world - we are going to attempt to process anyway"); + } + + } + + if (injectFrozenData) + { + // If we're loading from disk, we can actually substitute air in the block map for anything that is otherwise "missing". This keeps the reference in the map, in case + // the block comes back later + missing.forEach((name, m) -> + { + ForgeRegistry reg = STAGING.getRegistry(name); + m.forEach((rl, id) -> reg.markDummy(rl, id)); + }); + + + // If we're loading up the world from disk, we want to add in the new data that might have been provisioned by mods + // So we load it from the frozen persistent registry + RegistryManager.ACTIVE.registries.forEach((name, reg) -> + { + final Class clazz = RegistryManager.ACTIVE.getSuperType(name); + loadFrozenDataToStagingRegistry(STAGING, name, remaps.get(name), clazz); + }); + } + + /* + // Validate that all the STAGING data is good + forAllRegistries(PersistentRegistry.STAGING, ValidateRegistryFunction.OPERATION); + + // Load the STAGING registry into the ACTIVE registry + for (Map.Entry> r : PersistentRegistry.ACTIVE.registries.entrySet()) + { + final Class registrySuperType = PersistentRegistry.ACTIVE.getRegistrySuperType(r.getKey()); + loadRegistry(r.getKey(), PersistentRegistry.STAGING, PersistentRegistry.ACTIVE, registrySuperType); + } + + // Dump the active registry + forAllRegistries(PersistentRegistry.ACTIVE, DumpRegistryFunction.OPERATION); + + // Tell mods that the ids have changed + Loader.instance().fireRemapEvent(remaps.get(BLOCKS), remaps.get(ITEMS), false); + + // The id map changed, ensure we apply object holders + ObjectHolderRegistry.INSTANCE.applyObjectHolders(); + + // Clean out the staging registry now, we're done with it + PersistentRegistry.STAGING.clean(); + */ + + // Return an empty list, because we're good + return ArrayListMultimap.create(); + } + + //Has to be split because of generics, Yay! + private static > void loadPersistentDataToStagingRegistry(RegistryManager pool, RegistryManager to, Map remaps, Map missing, ResourceLocation name, ForgeRegistry.Snapshot snap, Class regType) + { + ForgeRegistry active = pool.getRegistry(name); + if (active == null) + return; // We've already asked the user if they wish to continue. So if the reg isnt found just assume the user knows and accepted it. + ForgeRegistry _new = to.getRegistry(name, RegistryManager.ACTIVE); + snap.aliases.forEach((f, t) -> _new.addAlias(f, t)); + snap.blocked.forEach(id -> _new.block(id)); + // Load current dummies BEFORE the snapshot is loaded so that add() will remove from the list. + snap.dummied.forEach(key -> _new.addDummy(key)); + _new.loadIds(snap.ids, missing, remaps, active, name); + } + + //Another bouncer for generic reasons + @SuppressWarnings("unchecked") + private static > void processMissing(Class clazz, ResourceLocation name, RegistryManager STAGING, MissingMappings e, Map missing, Map remaps, Collection defaulted, Collection failed) + { + List> mappings = ((MissingMappings)e).getAllMappings(); + ForgeRegistry active = RegistryManager.ACTIVE.getRegistry(name); + ForgeRegistry staging = STAGING.getRegistry(name); + staging.processMissingEvent(name, active, mappings, missing, remaps, defaulted, failed); + } + + private static > void loadFrozenDataToStagingRegistry(RegistryManager STAGING, ResourceLocation name, Map remaps, Class clazz) + { + ForgeRegistry frozen = RegistryManager.FROZEN.getRegistry(name); + ForgeRegistry newRegistry = STAGING.getRegistry(name, RegistryManager.FROZEN); + Map _new = Maps.newHashMap(); + frozen.getKeys().stream().filter(key -> !newRegistry.containsKey(key)).forEach(key -> _new.put(key, frozen.getID(key))); + newRegistry.loadIds(_new, Maps.newLinkedHashMap(), remaps, frozen, name); + } + + public static void fireCreateRegistryEvents() + { + MinecraftForge.EVENT_BUS.post(new RegistryEvent.NewRegistry()); + } + + public static void fireRegistryEvents() + { + fireRegistryEvents(rl -> true); + } + public static void fireRegistryEvents(Predicate filter) + { + List keys = Lists.newArrayList(RegistryManager.ACTIVE.registries.keySet()); + Collections.sort(keys, (o1, o2) -> o1.toString().compareToIgnoreCase(o2.toString())); + + if (filter.test(BLOCKS)) + { + MinecraftForge.EVENT_BUS.post(RegistryManager.ACTIVE.getRegistry(BLOCKS).getRegisterEvent(BLOCKS)); + ObjectHolderRegistry.INSTANCE.applyObjectHolders(); // inject any blocks + } + if (filter.test(ITEMS)) + { + MinecraftForge.EVENT_BUS.post(RegistryManager.ACTIVE.getRegistry(ITEMS).getRegisterEvent(ITEMS)); + ObjectHolderRegistry.INSTANCE.applyObjectHolders(); // inject any items + } + for (ResourceLocation rl : keys) + { + if (!filter.test(rl)) continue; + if (rl == BLOCKS || rl == ITEMS) continue; + MinecraftForge.EVENT_BUS.post(RegistryManager.ACTIVE.getRegistry(rl).getRegisterEvent(rl)); + } + ObjectHolderRegistry.INSTANCE.applyObjectHolders(); // inject everything else + } +} diff --git a/src/main/java/net/minecraftforge/fml/common/registry/IForgeRegistry.java b/src/main/java/net/minecraftforge/registries/IForgeRegistry.java similarity index 80% rename from src/main/java/net/minecraftforge/fml/common/registry/IForgeRegistry.java rename to src/main/java/net/minecraftforge/registries/IForgeRegistry.java index e37e05fcb9..16f164454f 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/IForgeRegistry.java +++ b/src/main/java/net/minecraftforge/registries/IForgeRegistry.java @@ -17,14 +17,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.common.registry; +package net.minecraftforge.registries; import java.util.List; -import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import com.google.common.collect.BiMap; import net.minecraft.util.ResourceLocation; import javax.annotation.Nonnull; @@ -35,14 +33,13 @@ import javax.annotation.Nullable; * * @param The top level type for the registry */ -@SuppressWarnings({"WeakerAccess", "unused"}) public interface IForgeRegistry> extends Iterable { public Class getRegistrySuperType(); void register(V value); - void registerAll(V... values); + void registerAll(@SuppressWarnings("unchecked") V... values); boolean containsKey(ResourceLocation key); boolean containsValue(V value); @@ -70,7 +67,7 @@ public interface IForgeRegistry> extends Iterab */ interface AddCallback> { - void onAdd(V obj, int id, Map slaveset); + void onAdd(IForgeRegistryInternal owner, RegistryManager stage, int id, V obj); } /** @@ -79,7 +76,7 @@ public interface IForgeRegistry> extends Iterab */ interface ClearCallback> { - void onClear(IForgeRegistry is, Map slaveset); + void onClear(IForgeRegistryInternal owner, RegistryManager stage); } /** @@ -87,11 +84,14 @@ public interface IForgeRegistry> extends Iterab */ interface CreateCallback> { - void onCreate(Map slaveset, BiMap> registries); + void onCreate(IForgeRegistryInternal owner, RegistryManager stage); } - interface SubstitutionCallback> + /** + * Factory for creating dummy entries, allowing worlds to be loaded and keep the missing block references. + */ + interface DummyFactory> { - void onSubstituteActivated(Map slaveset, V original, V replacement, ResourceLocation name); + V createDummy(ResourceLocation key); } } diff --git a/src/main/java/net/minecraftforge/fml/common/registry/IForgeRegistryEntry.java b/src/main/java/net/minecraftforge/registries/IForgeRegistryEntry.java similarity index 96% rename from src/main/java/net/minecraftforge/fml/common/registry/IForgeRegistryEntry.java rename to src/main/java/net/minecraftforge/registries/IForgeRegistryEntry.java index 615bc9b5cc..374b3aafd3 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/IForgeRegistryEntry.java +++ b/src/main/java/net/minecraftforge/registries/IForgeRegistryEntry.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.common.registry; +package net.minecraftforge.registries; import com.google.common.reflect.TypeToken; @@ -67,7 +67,7 @@ public interface IForgeRegistryEntry public static class Impl> implements IForgeRegistryEntry { private TypeToken token = new TypeToken(getClass()){}; - public final RegistryDelegate delegate = PersistentRegistryManager.makeDelegate((T)this, (Class)token.getRawType()); + public final IRegistryDelegate delegate = new RegistryDelegate((T)this, (Class)token.getRawType()); private ResourceLocation registryName = null; public final T setRegistryName(String name) diff --git a/src/main/java/net/minecraftforge/registries/IForgeRegistryInternal.java b/src/main/java/net/minecraftforge/registries/IForgeRegistryInternal.java new file mode 100644 index 0000000000..fdd6c2cc34 --- /dev/null +++ b/src/main/java/net/minecraftforge/registries/IForgeRegistryInternal.java @@ -0,0 +1,8 @@ +package net.minecraftforge.registries; + +import net.minecraft.util.ResourceLocation; + +public interface IForgeRegistryInternal> extends IForgeRegistry +{ + void setSlaveMap(ResourceLocation name, Object obj); +} diff --git a/src/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java b/src/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java new file mode 100644 index 0000000000..1a64e10477 --- /dev/null +++ b/src/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java @@ -0,0 +1,10 @@ +package net.minecraftforge.registries; + +import net.minecraft.util.ResourceLocation; + +public interface IForgeRegistryModifiable> extends IForgeRegistry +{ + void clear(); + V remove(ResourceLocation key); + boolean isLocked(); +} diff --git a/src/main/java/net/minecraftforge/registries/ILockableRegistry.java b/src/main/java/net/minecraftforge/registries/ILockableRegistry.java new file mode 100644 index 0000000000..2640728ad7 --- /dev/null +++ b/src/main/java/net/minecraftforge/registries/ILockableRegistry.java @@ -0,0 +1,8 @@ +package net.minecraftforge.registries; + +public interface ILockableRegistry { + + //Lock a registry to disable any direct Register calls. + // All future calls must be done via Forge registry methods not vanilla + void lock(); +} diff --git a/src/main/java/net/minecraftforge/fml/common/registry/RegistryDelegate.java b/src/main/java/net/minecraftforge/registries/IRegistryDelegate.java similarity index 57% rename from src/main/java/net/minecraftforge/fml/common/registry/RegistryDelegate.java rename to src/main/java/net/minecraftforge/registries/IRegistryDelegate.java index 70af23a4c5..db0916d4ae 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/RegistryDelegate.java +++ b/src/main/java/net/minecraftforge/registries/IRegistryDelegate.java @@ -17,9 +17,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.common.registry; +package net.minecraftforge.registries; -import com.google.common.base.Objects; import net.minecraft.util.ResourceLocation; @@ -32,7 +31,7 @@ import net.minecraft.util.ResourceLocation; * * @param the type of thing we're holding onto */ -public interface RegistryDelegate { +public interface IRegistryDelegate { /** * Get the referent pointed at by this delegate. This will be the currently active item or block, and will change * as world saves come and go. Note that item.delegate.get() may NOT be the same object as item, due to item and @@ -54,57 +53,4 @@ public interface RegistryDelegate { * @return The type of delegate */ Class type(); - - /* - * This is the internal implementation class of the delegate. - */ - final class Delegate implements RegistryDelegate - { - private T referent; - private ResourceLocation name; - private final Class type; - - public Delegate(T referent, Class type) { - this.referent = referent; - this.type = type; - } - - @Override - public T get() { - return referent; - } - - @Override - public ResourceLocation name() { return name; } - - @Override - public Class type() - { - return this.type; - } - - void changeReference(T newTarget) - { - this.referent = newTarget; - } - - void setName(ResourceLocation name) { this.name = name; } - - @Override - public boolean equals(Object obj) - { - if (obj instanceof Delegate) - { - Delegate other = (Delegate) obj; - return Objects.equal(other.name, name); - } - return false; - } - - @Override - public int hashCode() - { - return Objects.hashCode(name); - } - } } diff --git a/src/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java b/src/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java new file mode 100644 index 0000000000..b241f62bf0 --- /dev/null +++ b/src/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java @@ -0,0 +1,126 @@ +package net.minecraftforge.registries; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; + +import javax.annotation.Nullable; + +import org.apache.commons.lang3.Validate; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.registry.RegistryNamespacedDefaultedByKey; +import net.minecraftforge.fml.common.FMLLog; + +class NamespacedDefaultedWrapper> extends RegistryNamespacedDefaultedByKey implements ILockableRegistry +{ + private boolean locked = false; + private ForgeRegistry delegate; + + private NamespacedDefaultedWrapper(ForgeRegistry owner) + { + super(null); + this.delegate = owner; + } + + @Override + public void register(int id, ResourceLocation key, V value) + { + if (locked) + throw new IllegalStateException("Can not register to a locked registry. Modder should use Forge Register methods."); + Validate.notNull(value); + + if (value.getRegistryName() == null) + value.setRegistryName(key); + + int realId = this.delegate.add(id, value); + if (realId != id && id != -1) + FMLLog.warning("Registered object did not get ID it asked for. Name: {} Type: {} Expected: {} Got: {}", key, value.getRegistryType().getName(), id, realId); + } + + @Override + public void putObject(ResourceLocation key, V value) + { + register(-1, key, value); + } + + public void validateKey() + { + this.delegate.validateKey(); + } + + // Reading Functions + @Override + @Nullable + public V getObject(@Nullable ResourceLocation name) + { + return this.delegate.getValue(name); + } + + @Override + @Nullable + public ResourceLocation getNameForObject(V value) + { + return this.delegate.getKey(value); + } + + @Override + public boolean containsKey(ResourceLocation key) + { + return this.delegate.containsKey(key); + } + + @Override + public int getIDForObject(@Nullable V value) + { + return this.delegate.getID(value); + } + + @Override + @Nullable + public V getObjectById(int id) + { + return this.delegate.getValue(id); + } + + @Override + public Iterator iterator() + { + return this.delegate.iterator(); + } + + @Override + public Set getKeys() + { + return this.delegate.getKeys(); + } + + @Override + @Nullable + public V getRandomObject(Random random) + { + List lst = this.delegate.getValues(); + if (lst.isEmpty()) + return null; + return lst.get(random.nextInt(lst.size())); + } + + //internal + @Override //We override all public methods, this should be fine as null. + protected Map createUnderlyingMap(){ return null; } + + @Override + public void lock(){ this.locked = true; } + + public static class Factory> implements IForgeRegistry.CreateCallback + { + public static final ResourceLocation ID = new ResourceLocation("forge", "registry_defaulted_wrapper"); + @Override + public void onCreate(IForgeRegistryInternal owner, RegistryManager stage) + { + owner.setSlaveMap(ID, new NamespacedDefaultedWrapper((ForgeRegistry)owner)); + } + } +} diff --git a/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java b/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java new file mode 100644 index 0000000000..be6d8924d5 --- /dev/null +++ b/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java @@ -0,0 +1,122 @@ +package net.minecraftforge.registries; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; + +import javax.annotation.Nullable; + +import org.apache.commons.lang3.Validate; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.registry.RegistryNamespaced; +import net.minecraftforge.fml.common.FMLLog; + +class NamespacedWrapper> extends RegistryNamespaced implements ILockableRegistry +{ + private boolean locked = false; + private ForgeRegistry delegate; + + public NamespacedWrapper(ForgeRegistry owner) + { + this.delegate = owner; + } + + @Override + public void register(int id, ResourceLocation key, V value) + { + if (locked) + throw new IllegalStateException("Can not register to a locked registry. Modder should use Forge Register methods."); + + Validate.notNull(value); + + if (value.getRegistryName() == null) + value.setRegistryName(key); + + int realId = this.delegate.add(id, value); + if (realId != id && id != -1) + FMLLog.warning("Registered object did not get ID it asked for. Name: {} Type: {} Expected: {} Got: {}", key, value.getRegistryType().getName(), id, realId); + } + + @Override + public void putObject(ResourceLocation key, V value) + { + register(-1, key, value); + } + + + // Reading Functions + @Override + @Nullable + public V getObject(@Nullable ResourceLocation name) + { + return this.delegate.getValue(name); + } + + @Override + @Nullable + public ResourceLocation getNameForObject(V value) + { + return this.delegate.getKey(value); + } + + @Override + public boolean containsKey(ResourceLocation key) + { + return this.delegate.containsKey(key); + } + + @Override + public int getIDForObject(@Nullable V value) + { + return this.delegate.getID(value); + } + + @Override + @Nullable + public V getObjectById(int id) + { + return this.delegate.getValue(id); + } + + @Override + public Iterator iterator() + { + return this.delegate.iterator(); + } + + @Override + public Set getKeys() + { + return this.delegate.getKeys(); + } + + @Override + @Nullable + public V getRandomObject(Random random) + { + List lst = this.delegate.getValues(); + if (lst.isEmpty()) + return null; + return lst.get(random.nextInt(lst.size())); + } + + //internal + @Override //We override all public methods, this should be fine as null. + protected Map createUnderlyingMap(){ return null; } + + @Override + public void lock(){ this.locked = true; } + + public static class Factory> implements IForgeRegistry.CreateCallback + { + public static final ResourceLocation ID = new ResourceLocation("forge", "registry_defaulted_wrapper"); + @Override + public void onCreate(IForgeRegistryInternal owner, RegistryManager stage) + { + owner.setSlaveMap(ID, new NamespacedWrapper((ForgeRegistry)owner)); + } + } +} diff --git a/src/main/java/net/minecraftforge/fml/common/registry/ObjectHolderRef.java b/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java similarity index 64% rename from src/main/java/net/minecraftforge/fml/common/registry/ObjectHolderRef.java rename to src/main/java/net/minecraftforge/registries/ObjectHolderRef.java index f89ecfb346..cd650f69da 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/ObjectHolderRef.java +++ b/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java @@ -17,9 +17,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.common.registry; +package net.minecraftforge.registries; import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.Collections; import java.util.LinkedList; import java.util.Queue; @@ -30,27 +32,24 @@ import org.apache.logging.log4j.Level; import com.google.common.base.Throwables; import net.minecraftforge.fml.common.FMLLog; +import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; -import net.minecraftforge.fml.common.registry.PersistentRegistryManager.PersistentRegistry; import javax.annotation.Nullable; - /** * Internal class used in tracking {@link ObjectHolder} references - * - * @author cpw - * */ @SuppressWarnings("rawtypes") -class ObjectHolderRef { +class ObjectHolderRef +{ private Field field; private ResourceLocation injectedObject; private boolean isValid; - private FMLControlledNamespacedRegistry registry; + private ForgeRegistry registry; @SuppressWarnings("unchecked") - ObjectHolderRef(Field field, ResourceLocation injectedObject, boolean extractFromExistingValues) + ObjectHolderRef(Field field, ResourceLocation injectedObject, boolean extractFromExistingValues) { registry = getRegistryForType(field); @@ -62,7 +61,7 @@ class ObjectHolderRef { { Object existing = field.get(null); // nothing is ever allowed to replace AIR - if (existing == null || existing == registry.getDefaultValue()) + if (existing == null || existing == registry.getDefault()) { this.injectedObject = null; this.field = null; @@ -71,15 +70,13 @@ class ObjectHolderRef { } else { - ResourceLocation tmp = null; - if (registry != null) { - tmp = registry.getKey((IForgeRegistryEntry) existing); - } - this.injectedObject = tmp; + this.injectedObject = ((IForgeRegistryEntry)existing).getRegistryName(); } - } catch (Exception e) + } + catch (Exception e) { - throw Throwables.propagate(e); + Throwables.throwIfUnchecked(e); + throw new RuntimeException(e); } } else @@ -97,24 +94,26 @@ class ObjectHolderRef { } catch (Exception e) { - throw Throwables.propagate(e); + Throwables.throwIfUnchecked(e); + throw new RuntimeException(e); } } - @SuppressWarnings("unchecked") - @Nullable - private FMLControlledNamespacedRegistry getRegistryForType(Field field) + @SuppressWarnings("unchecked") + @Nullable + private ForgeRegistry getRegistryForType(Field field) { Queue> typesToExamine = new LinkedList>(); typesToExamine.add(field.getType()); - FMLControlledNamespacedRegistry registry = null; + + ForgeRegistry registry = null; while (!typesToExamine.isEmpty() && registry == null) { Class type = typesToExamine.remove(); Collections.addAll(typesToExamine, type.getInterfaces()); if (IForgeRegistryEntry.class.isAssignableFrom(type)) { - registry = PersistentRegistry.ACTIVE.getRegistry((Class) type); + registry = (ForgeRegistry)GameRegistry.findRegistry((Class)type); final Class parentType = type.getSuperclass(); if (parentType != null) { @@ -129,6 +128,7 @@ class ObjectHolderRef { { return isValid; } + public void apply() { Object thing; @@ -155,4 +155,33 @@ class ObjectHolderRef { FMLLog.log.warn("Unable to set {} with value {} ({})", this.field, thing, this.injectedObject, e); } } + + private static class FinalFieldHelper + { + private static Field modifiersField; + private static Object reflectionFactory; + private static Method newFieldAccessor; + private static Method fieldAccessorSet; + static Field makeWritable(Field f) throws Exception + { + if (modifiersField == null) + { + Method getReflectionFactory = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("getReflectionFactory"); + reflectionFactory = getReflectionFactory.invoke(null); + newFieldAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newFieldAccessor", Field.class, boolean.class); + fieldAccessorSet = Class.forName("sun.reflect.FieldAccessor").getDeclaredMethod("set", Object.class, Object.class); + modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + } + modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL); + return f; + } + + + static void setField(Field field, @Nullable Object instance, Object thing) throws Exception + { + Object fieldAccessor = newFieldAccessor.invoke(reflectionFactory, field, false); + fieldAccessorSet.invoke(fieldAccessor, instance, thing); + } + } } diff --git a/src/main/java/net/minecraftforge/fml/common/registry/ObjectHolderRegistry.java b/src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java similarity index 94% rename from src/main/java/net/minecraftforge/fml/common/registry/ObjectHolderRegistry.java rename to src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java index 238e56e188..f0ca8d248d 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/ObjectHolderRegistry.java +++ b/src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.common.registry; +package net.minecraftforge.registries; import java.lang.reflect.Field; import java.lang.reflect.Modifier; @@ -29,6 +29,7 @@ import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.discovery.ASMDataTable; import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData; +import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; import com.google.common.base.Throwables; @@ -39,10 +40,9 @@ import javax.annotation.Nullable; /** * Internal registry for tracking {@link ObjectHolder} references - * @author cpw - * */ -public enum ObjectHolderRegistry { +public enum ObjectHolderRegistry +{ INSTANCE; private List objectHolders = Lists.newArrayList(); @@ -97,7 +97,8 @@ public enum ObjectHolderRegistry { catch (Exception ex) { // unpossible? - throw Throwables.propagate(ex); + Throwables.throwIfUnchecked(ex); + throw new RuntimeException(ex); } } if (isClass) @@ -124,7 +125,8 @@ public enum ObjectHolderRegistry { catch (Exception ex) { // unpossible? - throw Throwables.propagate(ex); + Throwables.throwIfUnchecked(ex); + throw new RuntimeException(ex); } } } diff --git a/src/main/java/net/minecraftforge/fml/common/registry/RegistryBuilder.java b/src/main/java/net/minecraftforge/registries/RegistryBuilder.java similarity index 52% rename from src/main/java/net/minecraftforge/fml/common/registry/RegistryBuilder.java rename to src/main/java/net/minecraftforge/registries/RegistryBuilder.java index dbb5287ce2..70671ae199 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/RegistryBuilder.java +++ b/src/main/java/net/minecraftforge/registries/RegistryBuilder.java @@ -17,16 +17,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.common.registry; +package net.minecraftforge.registries; import java.util.List; -import java.util.Map; -import com.google.common.collect.BiMap; import com.google.common.collect.Lists; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.registry.IForgeRegistry.*; +import net.minecraftforge.registries.IForgeRegistry.*; import javax.annotation.Nullable; @@ -35,14 +33,15 @@ public class RegistryBuilder> private ResourceLocation registryName; private Class registryType; private ResourceLocation optionalDefaultKey; - private int minId; - private int maxId; - private boolean hasDelegates = false; + private int minId = 0; + private int maxId = Integer.MAX_VALUE; private List> addCallback = Lists.newArrayList(); private List> clearCallback = Lists.newArrayList(); private List> createCallback = Lists.newArrayList(); - private List> substitutionCallback = Lists.newArrayList(); private boolean saveToDisc = true; + private boolean allowOverrides = true; + private boolean allowModifications = false; + private DummyFactory dummyFactory; public RegistryBuilder setName(ResourceLocation name) { @@ -63,6 +62,11 @@ public class RegistryBuilder> return this; } + public RegistryBuilder setMaxID(int max) + { + return this.setIDRange(0, max); + } + public RegistryBuilder setDefaultKey(ResourceLocation key) { this.optionalDefaultKey = key; @@ -78,8 +82,8 @@ public class RegistryBuilder> this.add((ClearCallback)inst); if (inst instanceof CreateCallback) this.add((CreateCallback)inst); - if (inst instanceof SubstitutionCallback) - this.add((SubstitutionCallback)inst); + if (inst instanceof DummyFactory) + this.set((DummyFactory)inst); return this; } @@ -101,15 +105,9 @@ public class RegistryBuilder> return this; } - public RegistryBuilder add(SubstitutionCallback sub) + public RegistryBuilder set(DummyFactory factory) { - this.substitutionCallback.add(sub); - return this; - } - - public RegistryBuilder enableDelegates() - { - this.hasDelegates = true; + this.dummyFactory = factory; return this; } @@ -119,86 +117,66 @@ public class RegistryBuilder> return this; } - @SuppressWarnings("deprecation") + public RegistryBuilder disableOverrides() + { + this.allowOverrides = false; + return this; + } + + public RegistryBuilder allowModification() + { + this.allowModifications = true; + return this; + } + public IForgeRegistry create() { - return PersistentRegistryManager.createRegistry(registryName, registryType, optionalDefaultKey, minId, maxId, hasDelegates, - getAdd(), getClear(), getCreate(), getSubstitution(), saveToDisc); + return RegistryManager.ACTIVE.createRegistry(registryName, registryType, optionalDefaultKey, minId, maxId, + getAdd(), getClear(), getCreate(), saveToDisc, allowOverrides, allowModifications, dummyFactory); } @Nullable private AddCallback getAdd() { - if (this.addCallback.isEmpty()) + if (addCallback.isEmpty()) return null; - if (this.addCallback.size() == 1) - return this.addCallback.get(0); + if (addCallback.size() == 1) + return addCallback.get(0); - return new AddCallback() + return (owner, stage, id, obj) -> { - @Override - public void onAdd(T obj, int id, Map slaveset) - { - for (AddCallback cb : RegistryBuilder.this.addCallback) - cb.onAdd(obj, id, slaveset); - } + for (AddCallback cb : this.addCallback) + cb.onAdd(owner, stage, id, obj); }; } @Nullable private ClearCallback getClear() { - if (this.clearCallback.isEmpty()) + if (clearCallback.isEmpty()) return null; - if (this.clearCallback.size() == 1) - return this.clearCallback.get(0); + if (clearCallback.size() == 1) + return clearCallback.get(0); - return new ClearCallback() + return (owner, stage) -> { - @Override - public void onClear(IForgeRegistry is, Map slaveset) - { - for (ClearCallback cb : RegistryBuilder.this.clearCallback) - cb.onClear(is, slaveset); - } + for (ClearCallback cb : this.clearCallback) + cb.onClear(owner, stage); }; } @Nullable private CreateCallback getCreate() { - if (this.createCallback.isEmpty()) + if (createCallback.isEmpty()) return null; - if (this.createCallback.size() == 1) - return this.createCallback.get(0); + if (createCallback.size() == 1) + return createCallback.get(0); - return new CreateCallback() + return (owner, stage) -> { - @Override - public void onCreate(Map slaveset, BiMap> registries) - { - for (CreateCallback cb : RegistryBuilder.this.createCallback) - cb.onCreate(slaveset, registries); - } - }; - } - - @Nullable - private SubstitutionCallback getSubstitution() - { - if (this.substitutionCallback.isEmpty()) - return null; - if (this.substitutionCallback.size() == 1) - return this.substitutionCallback.get(0); - - return new SubstitutionCallback() - { - @Override - public void onSubstituteActivated(Map slaveset, T original, T replacement, ResourceLocation name) - { - for (SubstitutionCallback cb : RegistryBuilder.this.substitutionCallback) - cb.onSubstituteActivated(slaveset, original, replacement, name); - } + for (CreateCallback cb : this.createCallback) + cb.onCreate(owner, stage); }; } } diff --git a/src/main/java/net/minecraftforge/registries/RegistryDelegate.java b/src/main/java/net/minecraftforge/registries/RegistryDelegate.java new file mode 100644 index 0000000000..0dc7944622 --- /dev/null +++ b/src/main/java/net/minecraftforge/registries/RegistryDelegate.java @@ -0,0 +1,48 @@ +package net.minecraftforge.registries; + +import com.google.common.base.Objects; + +import net.minecraft.util.ResourceLocation; + +/* + * This is the internal implementation class of the delegate. + */ +final class RegistryDelegate implements IRegistryDelegate +{ + private T referent; + private ResourceLocation name; + private final Class type; + + public RegistryDelegate(T referent, Class type) + { + this.referent = referent; + this.type = type; + } + + @Override + public T get() { return referent; } + @Override + public ResourceLocation name() { return name; } + @Override + public Class type() { return this.type; } + + void changeReference(T newTarget){ this.referent = newTarget; } + public void setName(ResourceLocation name) { this.name = name; } + + @Override + public boolean equals(Object obj) + { + if (obj instanceof RegistryDelegate) + { + RegistryDelegate other = (RegistryDelegate) obj; + return Objects.equal(other.name, name); + } + return false; + } + + @Override + public int hashCode() + { + return Objects.hashCode(name); + } +} diff --git a/src/main/java/net/minecraftforge/registries/RegistryManager.java b/src/main/java/net/minecraftforge/registries/RegistryManager.java new file mode 100644 index 0000000000..8c3c8fdb32 --- /dev/null +++ b/src/main/java/net/minecraftforge/registries/RegistryManager.java @@ -0,0 +1,127 @@ +package net.minecraftforge.registries; + +import java.util.Map; +import java.util.Set; + +import javax.annotation.Nullable; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.common.collect.Sets.SetView; + +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.common.FMLLog; +import net.minecraftforge.registries.ForgeRegistry.Snapshot; +import net.minecraftforge.registries.IForgeRegistry.*; + +public class RegistryManager +{ + public static final RegistryManager ACTIVE = new RegistryManager("ACTIVE"); + public static final RegistryManager VANILLA = new RegistryManager("VANILLA"); + public static final RegistryManager FROZEN = new RegistryManager("FROZEN"); + + BiMap>> registries = HashBiMap.create(); + private BiMap>, ResourceLocation> superTypes = HashBiMap.create(); + private Set persisted = Sets.newHashSet(); + private final String name; + + public RegistryManager(String name) + { + this.name = name; + } + + public String getName() + { + return this.name; + } + + @SuppressWarnings("unchecked") + public > Class getSuperType(ResourceLocation key) + { + return (Class)superTypes.inverse().get(key); + } + + @SuppressWarnings("unchecked") + public > ForgeRegistry getRegistry(ResourceLocation key) + { + return (ForgeRegistry)this.registries.get(key); + } + + public > IForgeRegistry getRegistry(Class cls) + { + return getRegistry(superTypes.get(cls)); + } + + public > ResourceLocation getName(IForgeRegistry reg) + { + return this.registries.inverse().get(reg); + } + + public > ForgeRegistry getRegistry(ResourceLocation key, RegistryManager other) + { + if (!this.registries.containsKey(key)) + { + ForgeRegistry ot = other.getRegistry(key); + if (ot == null) + return null; + this.registries.put(key, ot.copy(this)); + this.superTypes.put(ot.getRegistrySuperType(), key); + if (other.persisted.contains(key)) + this.persisted.add(key); + } + return getRegistry(key); + } + + > ForgeRegistry createRegistry(ResourceLocation name, Class type, ResourceLocation defaultKey, int min, int max, + @Nullable AddCallback add, @Nullable ClearCallback clear, @Nullable CreateCallback create, + boolean persisted, boolean allowOverrides, boolean isModifiable, @Nullable DummyFactory dummyFactory) + { + Set> parents = Sets.newHashSet(); + findSuperTypes(type, parents); + SetView> overlappedTypes = Sets.intersection(parents, superTypes.keySet()); + if (!overlappedTypes.isEmpty()) + { + Class foundType = overlappedTypes.iterator().next(); + FMLLog.severe("Found existing registry of type %1s named %2s, you cannot create a new registry (%3s) with type %4s, as %4s has a parent of that type", foundType, superTypes.get(foundType), name, type); + throw new IllegalArgumentException("Duplicate registry parent type found - you can only have one registry for a particular super type"); + } + ForgeRegistry reg = new ForgeRegistry(type, defaultKey, min, max, create, add, clear, this, allowOverrides, isModifiable, dummyFactory); + registries.put(name, reg); + superTypes.put(type, name); + if (persisted) + this.persisted.add(name); + return getRegistry(name); + } + + private void findSuperTypes(Class type, Set> types) + { + if (type == null || type == Object.class) + { + return; + } + types.add(type); + for (Class interfac : type.getInterfaces()) + { + findSuperTypes(interfac, types); + } + findSuperTypes(type.getSuperclass(), types); + } + + public Map takeSnapshot(boolean savingToDisc) + { + Map ret = Maps.newHashMap(); + Set keys = savingToDisc ? this.persisted : this.registries.keySet(); + keys.forEach(name -> ret.put(name, getRegistry(name).makeSnapshot())); + return ret; + } + + //Public for testing only + public void clean() + { + this.persisted.clear(); + this.registries.clear(); + this.superTypes.clear(); + } +} diff --git a/src/main/resources/forge_at.cfg b/src/main/resources/forge_at.cfg index 984a846785..5708de8f85 100644 --- a/src/main/resources/forge_at.cfg +++ b/src/main/resources/forge_at.cfg @@ -150,8 +150,6 @@ public net.minecraft.client.renderer.BufferBuilder func_178972_a(IIII)V # putCol public net.minecraft.network.status.server.SPacketServerInfo field_149297_a # GSON #Main FML Access Transformer configuration file -# TileEntity addMapping -#public net.minecraft.tileentity.TileEntity func_145826_a(Ljava/lang/Class;Ljava/lang/String;)V # EntityList addMappings #public net.minecraft.entity.EntityList func_75618_a(Ljava/lang/Class;Ljava/lang/String;I)V #public net.minecraft.entity.EntityList func_75614_a(Ljava/lang/Class;Ljava/lang/String;III)V @@ -189,8 +187,6 @@ public net.minecraft.client.Minecraft field_110450_ap # mcDefaultResourcePack public net.minecraft.client.Minecraft func_71370_a(II)V # resize public net.minecraft.client.Minecraft func_180510_a(Lnet/minecraft/client/renderer/texture/TextureManager;)V # drawSplashScreen public net.minecraft.client.Minecraft func_184119_a(Lnet/minecraft/item/ItemStack;Lnet/minecraft/tileentity/TileEntity;)Lnet/minecraft/item/ItemStack; # storeTEInStack -## ItemBlock -public net.minecraft.item.ItemBlock field_150939_a ## DedicatedServer public net.minecraft.server.dedicated.DedicatedServer field_71341_l # pendingCommandList ## SaveFormatOld diff --git a/src/test/java/net/minecraftforge/debug/CanApplyAtEnchantingTableTest.java b/src/test/java/net/minecraftforge/debug/CanApplyAtEnchantingTableTest.java index f0e03c7fc7..5f65683968 100644 --- a/src/test/java/net/minecraftforge/debug/CanApplyAtEnchantingTableTest.java +++ b/src/test/java/net/minecraftforge/debug/CanApplyAtEnchantingTableTest.java @@ -4,13 +4,14 @@ import net.minecraft.enchantment.Enchantment; import net.minecraft.init.Enchantments; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -@Mod(modid = "canapplyatenchantingtabletest", name = "CanApplyAtEnchantingTableTest", version = "0.0.0", acceptableRemoteVersions = "*") +@Mod(modid = CanApplyAtEnchantingTableTest.MODID, name = "CanApplyAtEnchantingTableTest", version = "0.0.0", acceptableRemoteVersions = "*") public class CanApplyAtEnchantingTableTest { + public static final String MODID = "canapplyatenchantingtabletest"; public static final boolean ENABLE = false; public static final Item testItem = new Item() @@ -34,12 +35,14 @@ public class CanApplyAtEnchantingTableTest } }; - @Mod.EventHandler - public void preInit(FMLPreInitializationEvent event) + @Mod.EventBusSubscriber(modid = MODID) + public static class Registration { - if (ENABLE) + @SubscribeEvent + public static void registrItems(RegistryEvent.Register event) { - GameRegistry.register(testItem.setRegistryName("test_item").setUnlocalizedName("FortuneEnchantableOnly").setMaxStackSize(1)); + if (ENABLE) + event.getRegistry().register(testItem.setRegistryName("test_item").setUnlocalizedName("FortuneEnchantableOnly").setMaxStackSize(1)); } } } diff --git a/src/test/java/net/minecraftforge/debug/ClientCommandTest.java b/src/test/java/net/minecraftforge/debug/ClientCommandTest.java index dfaa89acf4..89a19ac5d8 100644 --- a/src/test/java/net/minecraftforge/debug/ClientCommandTest.java +++ b/src/test/java/net/minecraftforge/debug/ClientCommandTest.java @@ -10,7 +10,8 @@ import net.minecraftforge.client.ClientCommandHandler; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.event.FMLInitializationEvent; -import net.minecraftforge.fml.common.registry.GameData; +import net.minecraftforge.fml.common.registry.ForgeRegistries; +import net.minecraftforge.registries.GameData; import javax.annotation.Nullable; import java.util.Arrays; @@ -51,7 +52,7 @@ public class ClientCommandTest { if (args.length > 0) { - return getListOfStringsMatchingLastWord(args, GameData.getBlockRegistry().getKeys()); + return getListOfStringsMatchingLastWord(args, ForgeRegistries.BLOCKS.getKeys()); } return Collections.emptyList(); diff --git a/src/test/java/net/minecraftforge/debug/CustomSpriteTest.java b/src/test/java/net/minecraftforge/debug/CustomSpriteTest.java index ed19a00ce8..621e588539 100644 --- a/src/test/java/net/minecraftforge/debug/CustomSpriteTest.java +++ b/src/test/java/net/minecraftforge/debug/CustomSpriteTest.java @@ -11,10 +11,10 @@ import net.minecraft.creativetab.CreativeTabs; import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.event.TextureStitchEvent; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.registry.GameRegistry; import org.apache.logging.log4j.Logger; import javax.annotation.Nonnull; @@ -32,13 +32,22 @@ public class CustomSpriteTest static final String NAME = "Custom sprite test"; private static Logger logger; + + @Mod.EventBusSubscriber(modid = MOD_ID) + public static class Registration + { + @SubscribeEvent + public static void registrBlocks(RegistryEvent.Register event) + { + event.getRegistry().register(new Block(Material.WOOD).setRegistryName(MOD_ID, "custom_sprite_block").setCreativeTab(CreativeTabs.MISC)); + } + } + @Mod.EventHandler public void preInit(FMLPreInitializationEvent event) { logger = event.getModLog(); MinecraftForge.EVENT_BUS.register(this); - Block block = new Block(Material.WOOD).setRegistryName(MOD_ID, "custom_sprite_block").setCreativeTab(CreativeTabs.MISC); - GameRegistry.register(block); } @SubscribeEvent diff --git a/src/test/java/net/minecraftforge/debug/DynBucketTest.java b/src/test/java/net/minecraftforge/debug/DynBucketTest.java index ec0a801414..c92b31444c 100644 --- a/src/test/java/net/minecraftforge/debug/DynBucketTest.java +++ b/src/test/java/net/minecraftforge/debug/DynBucketTest.java @@ -14,9 +14,12 @@ import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.Ingredient; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; import net.minecraft.network.play.server.SPacketUpdateTileEntity; +import net.minecraft.potion.Potion; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResult; import net.minecraft.util.EnumActionResult; @@ -30,9 +33,11 @@ import net.minecraft.util.text.TextComponentString; import net.minecraft.world.World; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.common.ForgeVersion; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.debug.ModelFluidDebug.TestFluid; import net.minecraftforge.debug.ModelFluidDebug.TestGas; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.entity.player.FillBucketEvent; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; @@ -52,6 +57,7 @@ import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.eventhandler.Event.Result; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.wrapper.CombinedInvWrapper; @@ -64,14 +70,21 @@ import javax.annotation.Nullable; public class DynBucketTest { public static final String MODID = "dynbuckettest"; - public static final Item dynBucket = new DynBucket(); - public static final Item dynBottle = new DynBottle(); private static final ResourceLocation simpleTankName = new ResourceLocation(MODID, "simpletank"); private static final ResourceLocation testItemName = new ResourceLocation(MODID, "testitem"); private static final boolean ENABLE = true; private static Logger logger; + @ObjectHolder("testitem") + public static final Item TEST_ITEM = null; + @ObjectHolder("simpletank") + public static final Block TANK_BLOCK = null; + @ObjectHolder("simpletank") + public static final Item TANK_ITEM = null; + @ObjectHolder("dynbottle") + public static final Item DYN_BOTTLE = null; + static { if (ENABLE && ModelFluidDebug.ENABLE) @@ -80,20 +93,18 @@ public class DynBucketTest } } + @SuppressWarnings("unused") + public DynBucketTest() + { + if (!ENABLE || !ModelFluidDebug.ENABLE) + MinecraftForge.EVENT_BUS.register(this); + } + @SidedProxy public static CommonProxy proxy; - public static class CommonProxy - { - void setupModels() - { - } - } - - public static class ServerProxy extends CommonProxy - { - } - + public static class CommonProxy { void setupModels(){} } + public static class ServerProxy extends CommonProxy{} public static class ClientProxy extends CommonProxy { @SuppressWarnings("unused") @@ -105,10 +116,10 @@ public class DynBucketTest return; } - ModelLoader.setBucketModelDefinition(dynBucket); + ModelLoader.setBucketModelDefinition(DYN_BOTTLE); final ModelResourceLocation bottle = new ModelResourceLocation(new ResourceLocation(ForgeVersion.MOD_ID, "dynbottle"), "inventory"); - ModelLoader.setCustomMeshDefinition(dynBottle, new ItemMeshDefinition() + ModelLoader.setCustomMeshDefinition(DYN_BOTTLE, new ItemMeshDefinition() { @Override public ModelResourceLocation getModelLocation(@Nonnull ItemStack stack) @@ -116,38 +127,48 @@ public class DynBucketTest return bottle; } }); - ModelBakery.registerItemVariants(dynBottle, bottle); + ModelBakery.registerItemVariants(DYN_BOTTLE, bottle); ModelLoader.setCustomModelResourceLocation(Item.REGISTRY.getObject(simpleTankName), 0, new ModelResourceLocation(simpleTankName, "normal")); ModelLoader.setCustomModelResourceLocation(Item.REGISTRY.getObject(testItemName), 0, new ModelResourceLocation(new ResourceLocation("minecraft", "stick"), "inventory")); } } - @SuppressWarnings("unused") + @Mod.EventBusSubscriber(modid = MODID) + public static class Registration + { + @SubscribeEvent + public static void registrBlocks(RegistryEvent.Register event) + { + event.getRegistry().register(new BlockSimpleTank().setRegistryName(simpleTankName)); + } + + @SubscribeEvent + public static void registrItems(RegistryEvent.Register event) + { + FluidRegistry.addBucketForFluid(FluidRegistry.getFluid(TestFluid.name)); + FluidRegistry.addBucketForFluid(FluidRegistry.getFluid(TestGas.name)); + + event.getRegistry().registerAll( + new TestItem().setRegistryName(testItemName), + new ItemBlock(TANK_BLOCK).setRegistryName(simpleTankName), + new DynBottle() + ); + } + + @SubscribeEvent + public static void registrRecipes(RegistryEvent.Register event) + { + ItemStack filledBucket = FluidUtil.getFilledBucket(new FluidStack(TestFluid.instance, Fluid.BUCKET_VOLUME)); + GameRegistry.addShapelessRecipe(new ResourceLocation(MODID, "diamond_to_fluid"), null, filledBucket, Ingredient.func_193368_a(Items.DIAMOND)); + } + } + @EventHandler public void preInit(FMLPreInitializationEvent event) { - if (!ENABLE || !ModelFluidDebug.ENABLE) - { - return; - } - logger = event.getModLog(); - GameRegistry.register(new TestItem(), testItemName); - Block tank = new BlockSimpleTank(); - GameRegistry.register(tank, simpleTankName); - GameRegistry.register(new ItemBlock(tank), simpleTankName); GameRegistry.registerTileEntity(TileSimpleTank.class, "simpletank"); - - FluidRegistry.addBucketForFluid(FluidRegistry.getFluid(TestFluid.name)); - FluidRegistry.addBucketForFluid(FluidRegistry.getFluid(TestGas.name)); - - //GameRegistry.registerItem(dynBucket, "dynbucket"); - GameRegistry.register(dynBottle); - ItemStack filledBucket = FluidUtil.getFilledBucket(new FluidStack(TestFluid.instance, Fluid.BUCKET_VOLUME)); - //GameRegistry.addShapelessRecipe(new ItemStack(Items.DIAMOND), filledBucket); - proxy.setupModels(); - //MinecraftForge.EVENT_BUS.register(this); } @SubscribeEvent @@ -224,32 +245,6 @@ public class DynBucketTest } } - public static class DynBucket extends Item - { - public DynBucket() - { - setUnlocalizedName("dynbucket"); - setMaxStackSize(1); - setHasSubtypes(true); - setCreativeTab(CreativeTabs.MISC); - } - - @Override - public void getSubItems(CreativeTabs tab, NonNullList subItems) - { - if (!this.isInCreativeTab(tab)) - return; - for (int i = 0; i < 4; i++) - { - ItemStack bucket = new ItemStack(this, 1, i); - if (FluidUtil.getFluidContained(bucket) != null) - { - subItems.add(bucket); - } - } - } - } - public static class DynBottle extends UniversalBucket { public DynBottle() diff --git a/src/test/java/net/minecraftforge/debug/FluidPlacementTest.java b/src/test/java/net/minecraftforge/debug/FluidPlacementTest.java index 2374bf9ac3..274f40ee1e 100644 --- a/src/test/java/net/minecraftforge/debug/FluidPlacementTest.java +++ b/src/test/java/net/minecraftforge/debug/FluidPlacementTest.java @@ -1,5 +1,6 @@ package net.minecraftforge.debug; +import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.ItemMeshDefinition; @@ -8,7 +9,6 @@ import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.block.statemap.StateMapperBase; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; @@ -22,6 +22,7 @@ import net.minecraft.world.World; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fluids.BlockFluidFinite; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; @@ -33,7 +34,7 @@ import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -57,38 +58,52 @@ public class FluidPlacementTest @EventHandler public void preInit(FMLPreInitializationEvent event) { - if (ENABLE && ModelFluidDebug.ENABLE) - { - proxy.preInit(event); - } + if (!ENABLE || !ModelFluidDebug.ENABLE) + return; + proxy.preInit(); } - public static class CommonProxy + + @Mod.EventBusSubscriber(modid = MODID) + public static class Registration { - public void preInit(FMLPreInitializationEvent event) + @SubscribeEvent + public static void registrBlocks(RegistryEvent.Register event) { + if (!ENABLE || !ModelFluidDebug.ENABLE) + return; + event.getRegistry().registerAll( + FiniteFluidBlock.instance + ); + } + @SubscribeEvent + public static void registrItems(RegistryEvent.Register event) + { + if (!ENABLE || !ModelFluidDebug.ENABLE) + return; FluidRegistry.registerFluid(FiniteFluid.instance); FluidRegistry.addBucketForFluid(FiniteFluid.instance); - GameRegistry.register(EmptyFluidContainer.instance); - GameRegistry.register(FluidContainer.instance); - GameRegistry.register(FiniteFluidBlock.instance); - GameRegistry.register(new ItemBlock(FiniteFluidBlock.instance).setRegistryName(FiniteFluidBlock.instance.getRegistryName())); + event.getRegistry().registerAll( + EmptyFluidContainer.instance, + FluidContainer.instance, + new ItemBlock(FiniteFluidBlock.instance).setRegistryName(FiniteFluidBlock.instance.getRegistryName()) + ); MinecraftForge.EVENT_BUS.register(FluidContainer.instance); } } - public static class ServerProxy extends CommonProxy - { + public static class CommonProxy { + public void preInit(){} } + public static class ServerProxy extends CommonProxy{} public static class ClientProxy extends CommonProxy { private static ModelResourceLocation fluidLocation = new ModelResourceLocation(MODID.toLowerCase() + ":" + FiniteFluidBlock.name, "normal"); @Override - public void preInit(FMLPreInitializationEvent event) + public void preInit() { - super.preInit(event); Item fluid = Item.getItemFromBlock(FiniteFluidBlock.instance); ModelLoader.setCustomModelResourceLocation(EmptyFluidContainer.instance, 0, new ModelResourceLocation("forge:bucket", "inventory")); ModelLoader.setBucketModelDefinition(FluidContainer.instance); @@ -246,7 +261,7 @@ public class FluidPlacementTest { if (!this.isInCreativeTab(tab)) return; - Fluid[] fluids = new Fluid[]{FluidRegistry.WATER, FluidRegistry.LAVA, FiniteFluid.instance, ModelFluidDebug.TestFluid.instance}; + Fluid[] fluids = new Fluid[]{FluidRegistry.WATER, FluidRegistry.LAVA, FiniteFluid.instance, ModelFluidDebug.FLUID}; // add 16 variable fillings for (Fluid fluid : fluids) { diff --git a/src/test/java/net/minecraftforge/debug/ItemCanDestroyBlocksInCreativeTest.java b/src/test/java/net/minecraftforge/debug/ItemCanDestroyBlocksInCreativeTest.java index b51bc4ff14..12e330c609 100644 --- a/src/test/java/net/minecraftforge/debug/ItemCanDestroyBlocksInCreativeTest.java +++ b/src/test/java/net/minecraftforge/debug/ItemCanDestroyBlocksInCreativeTest.java @@ -6,9 +6,9 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.event.FMLInitializationEvent; -import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @Mod(modid = ItemCanDestroyBlocksInCreativeTest.MODID, name = "Item.canDestroyBlockInCreative() Test", version = "1.0", acceptableRemoteVersions = "*") public class ItemCanDestroyBlocksInCreativeTest @@ -16,23 +16,27 @@ public class ItemCanDestroyBlocksInCreativeTest public static final boolean ENABLE = true; public static final String MODID = "item_can_destroy_blocks_in_creative_test"; - public static Item testItem = new Item() + @Mod.EventBusSubscriber(modid = MODID) + public static class Registration { - @Override - public boolean canDestroyBlockInCreative(World world, BlockPos pos, ItemStack stack, EntityPlayer player) + @SubscribeEvent + public static void registrItems(RegistryEvent.Register event) { - return false; - } - }.setRegistryName(MODID, "item_test") - .setUnlocalizedName(MODID + ".item_test") - .setCreativeTab(CreativeTabs.TOOLS); + if (!ENABLE) + return; - @Mod.EventHandler - public static void init(FMLInitializationEvent event) - { - if (ENABLE) - { - GameRegistry.register(testItem); + Item test = new Item() + { + @Override + public boolean canDestroyBlockInCreative(World world, BlockPos pos, ItemStack stack, EntityPlayer player) + { + return false; + } + }.setRegistryName(MODID, "item_test") + .setUnlocalizedName(MODID + ".item_test") + .setCreativeTab(CreativeTabs.TOOLS); + + event.getRegistry().register(test); } } -} \ No newline at end of file +} diff --git a/src/test/java/net/minecraftforge/debug/ItemLayerModelDebug.java b/src/test/java/net/minecraftforge/debug/ItemLayerModelDebug.java index 434b080273..8b725439a0 100644 --- a/src/test/java/net/minecraftforge/debug/ItemLayerModelDebug.java +++ b/src/test/java/net/minecraftforge/debug/ItemLayerModelDebug.java @@ -11,12 +11,12 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; +import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.Mod.EventHandler; -import net.minecraftforge.fml.common.SidedProxy; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; import javax.annotation.Nullable; import java.util.Random; @@ -26,43 +26,27 @@ public class ItemLayerModelDebug { public static final String MODID = "forgedebugitemlayermodel"; public static final String VERSION = "1.0"; + @ObjectHolder("test_item") + public static final Item TEST_ITEM = null; - @SidedProxy - public static CommonProxy proxy; - - @EventHandler - public void preInit(FMLPreInitializationEvent event) + @Mod.EventBusSubscriber(modid = MODID) + public static class Registration { - proxy.preInit(event); - } - - public static class CommonProxy - { - public void preInit(FMLPreInitializationEvent event) + @SubscribeEvent + public static void registrItems(RegistryEvent.Register event) { - GameRegistry.register(TestItem.instance); + event.getRegistry().register(new TestItem()); } - } - public static class ServerProxy extends CommonProxy - { - } - - public static class ClientProxy extends CommonProxy - { - private static ModelResourceLocation modelLocation = new ModelResourceLocation(MODID.toLowerCase() + ":" + TestItem.name, "inventory"); - - @Override - public void preInit(FMLPreInitializationEvent event) + @SubscribeEvent + public static void registerModels(ModelRegistryEvent event) { - super.preInit(event); - ModelLoader.setCustomModelResourceLocation(TestItem.instance, 0, modelLocation); + ModelLoader.setCustomModelResourceLocation(TEST_ITEM, 0, new ModelResourceLocation(MODID.toLowerCase() + ":" + TestItem.name, "inventory")); } } public static final class TestItem extends Item { - public static final TestItem instance = new TestItem(); public static final String name = "test_item"; private TestItem() diff --git a/src/test/java/net/minecraftforge/debug/ItemTileDebug.java b/src/test/java/net/minecraftforge/debug/ItemTileDebug.java index a37eb729cc..c597af24ba 100644 --- a/src/test/java/net/minecraftforge/debug/ItemTileDebug.java +++ b/src/test/java/net/minecraftforge/debug/ItemTileDebug.java @@ -1,5 +1,6 @@ package net.minecraftforge.debug; +import net.minecraft.block.Block; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; @@ -9,6 +10,7 @@ import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; +import net.minecraft.potion.Potion; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; @@ -16,6 +18,9 @@ import net.minecraftforge.client.ForgeHooksClient; import net.minecraftforge.client.event.ModelBakeEvent; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.debug.ObjectHolderTest.CustomRegistryEntry; +import net.minecraftforge.debug.ObjectHolderTest.ICustomRegistryEntry; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; @@ -23,7 +28,10 @@ import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.registry.ForgeRegistries; import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; +import net.minecraftforge.registries.RegistryBuilder; import static org.lwjgl.opengl.GL11.*; @@ -31,8 +39,8 @@ import static org.lwjgl.opengl.GL11.*; public class ItemTileDebug { public static final String MODID = "forgedebugitemtile"; - - private static String blockName = MODID.toLowerCase() + ":" + TestBlock.name; + @ObjectHolder(TestBlock.name) + public static final Block TEST_BLOCK = null; @SidedProxy public static CommonProxy proxy; @@ -49,34 +57,43 @@ public class ItemTileDebug proxy.init(event); } + @Mod.EventBusSubscriber(modid = MODID) + public static class Registration + { + @SubscribeEvent + public static void registerBlocks(RegistryEvent.Register event) + { + event.getRegistry().register(new TestBlock()); + } + + @SubscribeEvent + public static void registerItems(RegistryEvent.Register event) + { + event.getRegistry().register(new ItemBlock(TEST_BLOCK).setRegistryName(TEST_BLOCK.getRegistryName())); + } + } + public static class CommonProxy { public void preInit(FMLPreInitializationEvent event) { - GameRegistry.register(TestBlock.instance); - GameRegistry.register(new ItemBlock(TestBlock.instance).setRegistryName(TestBlock.instance.getRegistryName())); GameRegistry.registerTileEntity(CustomTileEntity.class, MODID.toLowerCase() + ":custom_tile_entity"); } - - public void init(FMLInitializationEvent event) - { - } + public void init(FMLInitializationEvent event){} } - public static class ServerProxy extends CommonProxy - { - } + public static class ServerProxy extends CommonProxy{} public static class ClientProxy extends CommonProxy { - private static ModelResourceLocation itemLocation = new ModelResourceLocation(blockName, "normal"); + private static ModelResourceLocation itemLocation = new ModelResourceLocation(TEST_BLOCK.getRegistryName(), "normal"); @SuppressWarnings("deprecation") @Override public void preInit(FMLPreInitializationEvent event) { super.preInit(event); - Item item = Item.getItemFromBlock(TestBlock.instance); + Item item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(MODID, TestBlock.name)); ForgeHooksClient.registerTESRItemStack(item, 0, CustomTileEntity.class); ModelLoader.setCustomModelResourceLocation(item, 0, itemLocation); MinecraftForge.EVENT_BUS.register(BakeEventHandler.instance); @@ -100,7 +117,7 @@ public class ItemTileDebug @SubscribeEvent public void onModelBakeEvent(ModelBakeEvent event) { - event.getModelManager().getBlockModelShapes().registerBuiltInBlocks(TestBlock.instance); + event.getModelManager().getBlockModelShapes().registerBuiltInBlocks(TEST_BLOCK); } } @@ -134,7 +151,6 @@ public class ItemTileDebug public static class TestBlock extends BlockContainer { - public static final TestBlock instance = new TestBlock(); public static final String name = "custom_model_block"; private TestBlock() diff --git a/src/test/java/net/minecraftforge/debug/ModelAnimationDebug.java b/src/test/java/net/minecraftforge/debug/ModelAnimationDebug.java index fb421fefcc..0340a6444e 100644 --- a/src/test/java/net/minecraftforge/debug/ModelAnimationDebug.java +++ b/src/test/java/net/minecraftforge/debug/ModelAnimationDebug.java @@ -44,6 +44,8 @@ import net.minecraftforge.common.model.animation.IAnimationStateMachine; import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; import net.minecraftforge.common.property.Properties; +import net.minecraftforge.debug.ItemTileDebug.TestBlock; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.client.registry.IRenderFactory; import net.minecraftforge.fml.client.registry.RenderingRegistry; @@ -52,8 +54,11 @@ import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.Mod.Instance; import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.registry.EntityRegistry; import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; + import org.apache.logging.log4j.Logger; import javax.annotation.Nonnull; @@ -65,9 +70,12 @@ public class ModelAnimationDebug public static final String MODID = "forgedebugmodelanimation"; public static final String VERSION = "0.0"; - public static String blockName = "test_animation_block"; - public static ResourceLocation blockId = new ResourceLocation(MODID, blockName); + public static final String blockName = "test_animation_block"; public static final PropertyDirection FACING = PropertyDirection.create("facing"); + @ObjectHolder(blockName) + public static final Block TEST_BLOCK = null; + @ObjectHolder(blockName) + public static final Item TEST_ITEM = null; @Instance(MODID) public static ModelAnimationDebug instance; @@ -76,16 +84,20 @@ public class ModelAnimationDebug public static CommonProxy proxy; private static Logger logger; - public static abstract class CommonProxy + + @Mod.EventBusSubscriber(modid = MODID) + public static class Registration { - public void preInit(FMLPreInitializationEvent event) + @SubscribeEvent + public static void registerBlocks(RegistryEvent.Register event) { - GameRegistry.register(new Block(Material.WOOD) + event.getRegistry().register( + new Block(Material.WOOD) { { setCreativeTab(CreativeTabs.BUILDING_BLOCKS); setUnlocalizedName(MODID + "." + blockName); - setRegistryName(blockId); + setRegistryName(new ResourceLocation(MODID, blockName)); } @Override @@ -166,14 +178,28 @@ public class ModelAnimationDebug return true; } }); - GameRegistry.register(new ItemBlock(Block.REGISTRY.getObject(blockId)) - { - @Override - public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable NBTTagCompound nbt) + } + + @SubscribeEvent + public static void registerItems(RegistryEvent.Register event) + { + event.getRegistry().register( + new ItemBlock(TEST_BLOCK) { - return new ItemAnimationHolder(); - } - }.setRegistryName(blockId)); + @Override + public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable NBTTagCompound nbt) + { + return new ItemAnimationHolder(); + } + }.setRegistryName(TEST_BLOCK.getRegistryName()) + ); + } + } + + public static abstract class CommonProxy + { + public void preInit(FMLPreInitializationEvent event) + { GameRegistry.registerTileEntity(Chest.class, MODID + ":" + "tile_" + blockName); } @@ -197,7 +223,7 @@ public class ModelAnimationDebug { super.preInit(event); B3DLoader.INSTANCE.addDomain(MODID); - ModelLoader.setCustomModelResourceLocation(Item.REGISTRY.getObject(blockId), 0, new ModelResourceLocation(blockId, "inventory")); + ModelLoader.setCustomModelResourceLocation(TEST_ITEM, 0, new ModelResourceLocation(TEST_ITEM.getRegistryName(), "inventory")); ClientRegistry.bindTileEntitySpecialRenderer(Chest.class, new AnimationTESR() { @Override diff --git a/src/test/java/net/minecraftforge/debug/ModelBakeEventDebug.java b/src/test/java/net/minecraftforge/debug/ModelBakeEventDebug.java index 09583e3f19..a26b7fc79a 100644 --- a/src/test/java/net/minecraftforge/debug/ModelBakeEventDebug.java +++ b/src/test/java/net/minecraftforge/debug/ModelBakeEventDebug.java @@ -2,6 +2,8 @@ package net.minecraftforge.debug; import com.google.common.collect.ImmutableList; import com.google.common.primitives.Ints; + +import net.minecraft.block.Block; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; @@ -31,18 +33,18 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.client.event.ModelBakeEvent; +import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; import net.minecraftforge.common.property.Properties; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.Mod.EventHandler; -import net.minecraftforge.fml.common.SidedProxy; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; import javax.annotation.Nullable; import java.util.ArrayList; @@ -56,6 +58,13 @@ public class ModelBakeEventDebug public static final int cubeSize = 3; private static ResourceLocation blockName = new ResourceLocation(MODID, CustomModelBlock.name); + private static ModelResourceLocation blockLocation = new ModelResourceLocation(blockName, "normal"); + private static ModelResourceLocation itemLocation = new ModelResourceLocation(blockName, "inventory"); + + @ObjectHolder(CustomModelBlock.name) + public static final Block CUSTOM_BLOCK = null; + @ObjectHolder(CustomModelBlock.name) + public static final Block CUSTOM_ITEM = null; @SuppressWarnings("unchecked") public static final IUnlistedProperty[] properties = new IUnlistedProperty[6]; @@ -68,41 +77,28 @@ public class ModelBakeEventDebug } } - @SidedProxy - public static CommonProxy proxy; - - @EventHandler - public void preInit(FMLPreInitializationEvent event) + @Mod.EventBusSubscriber(modid = MODID) + public static class Registration { - proxy.preInit(event); - } - - public static class CommonProxy - { - public void preInit(FMLPreInitializationEvent event) + @SubscribeEvent + public static void registerBlocks(RegistryEvent.Register event) { - GameRegistry.register(CustomModelBlock.instance); - GameRegistry.register(new ItemBlock(CustomModelBlock.instance).setRegistryName(CustomModelBlock.instance.getRegistryName())); + event.getRegistry().register(new CustomModelBlock()); GameRegistry.registerTileEntity(CustomTileEntity.class, MODID.toLowerCase() + ":custom_tile_entity"); } - } - public static class ServerProxy extends CommonProxy - { - } - - public static class ClientProxy extends CommonProxy - { - private static ModelResourceLocation blockLocation = new ModelResourceLocation(blockName, "normal"); - private static ModelResourceLocation itemLocation = new ModelResourceLocation(blockName, "inventory"); - - @Override - public void preInit(FMLPreInitializationEvent event) + @SubscribeEvent + public static void registerItems(RegistryEvent.Register event) { - super.preInit(event); - Item item = Item.getItemFromBlock(CustomModelBlock.instance); + event.getRegistry().register(new ItemBlock(CUSTOM_BLOCK).setRegistryName(CUSTOM_BLOCK.getRegistryName())); + } + + @SubscribeEvent + public static void registerModels(ModelRegistryEvent event) + { + Item item = Item.getItemFromBlock(CUSTOM_BLOCK); ModelLoader.setCustomModelResourceLocation(item, 0, itemLocation); - ModelLoader.setCustomStateMapper(CustomModelBlock.instance, new StateMapperBase() + ModelLoader.setCustomStateMapper(CUSTOM_BLOCK, new StateMapperBase() { protected ModelResourceLocation getModelResourceLocation(IBlockState p_178132_1_) { @@ -127,14 +123,13 @@ public class ModelBakeEventDebug TextureAtlasSprite base = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite("minecraft:blocks/slime"); TextureAtlasSprite overlay = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite("minecraft:blocks/redstone_block"); IBakedModel customModel = new CustomModel(base, overlay); - event.getModelRegistry().putObject(ClientProxy.blockLocation, customModel); - event.getModelRegistry().putObject(ClientProxy.itemLocation, customModel); + event.getModelRegistry().putObject(blockLocation, customModel); + event.getModelRegistry().putObject(itemLocation, customModel); } } public static class CustomModelBlock extends BlockContainer { - public static final CustomModelBlock instance = new CustomModelBlock(); public static final String name = "custom_model_block"; private CustomModelBlock() diff --git a/src/test/java/net/minecraftforge/debug/ModelFluidDebug.java b/src/test/java/net/minecraftforge/debug/ModelFluidDebug.java index 305ac87fd2..16bc4ad024 100644 --- a/src/test/java/net/minecraftforge/debug/ModelFluidDebug.java +++ b/src/test/java/net/minecraftforge/debug/ModelFluidDebug.java @@ -1,28 +1,27 @@ package net.minecraftforge.debug; +import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.ItemMeshDefinition; import net.minecraft.client.renderer.block.model.ModelBakery; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.block.statemap.StateMapperBase; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.common.ForgeVersion; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fluids.BlockFluidClassic; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; -import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.registry.GameRegistry; - -import javax.annotation.Nonnull; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; @Mod(modid = ModelFluidDebug.MODID, name = "ForgeDebugModelFluid", version = ModelFluidDebug.VERSION, acceptableRemoteVersions = "*") public class ModelFluidDebug @@ -31,94 +30,93 @@ public class ModelFluidDebug public static final String VERSION = "1.0"; public static final boolean ENABLE = true; + private static ModelResourceLocation fluidLocation = new ModelResourceLocation(MODID.toLowerCase() + ":" + TestFluidBlock.name, "fluid"); + private static ModelResourceLocation gasLocation = new ModelResourceLocation(MODID.toLowerCase() + ":" + TestFluidBlock.name, "gas"); + private static ModelResourceLocation milkLocation = new ModelResourceLocation(MODID.toLowerCase() + ":" + TestFluidBlock.name, "milk"); + @ObjectHolder(TestFluidBlock.name) + public static final Block FLUID_BLOCK = null; + @ObjectHolder(TestFluidBlock.name) + public static final Item FLUID_ITEM = null; + @ObjectHolder(TestGasBlock.name) + public static final Block GAS_BLOCK = null; + @ObjectHolder(TestGasBlock.name) + public static final Item GAS_ITEM = null; + @ObjectHolder(MilkFluidBlock.name) + public static final Block MILK_BLOCK = null; + @ObjectHolder(MilkFluidBlock.name) + public static final Item MILK_ITEM = null; - @SidedProxy - public static CommonProxy proxy; + //Used in DynBucketTest/FluidPlacementTest, TODO: Make this a full registry with @ObjectHolder? + public static final Fluid MILK = new Fluid("milk", new ResourceLocation(ForgeVersion.MOD_ID, "blocks/milk_still"), new ResourceLocation(ForgeVersion.MOD_ID, "blocks/milk_flow")); + public static final Fluid FLUID = new TestFluid(); + public static final Fluid GAS = new TestGas(); - public static final Fluid milkFluid = new Fluid("milk", new ResourceLocation(ForgeVersion.MOD_ID, "blocks/milk_still"), new ResourceLocation(ForgeVersion.MOD_ID, "blocks/milk_flow")); @EventHandler public void preInit(FMLPreInitializationEvent event) { if (ENABLE) { - proxy.preInit(event); + FluidRegistry.registerFluid(FLUID); + FluidRegistry.registerFluid(GAS); + FluidRegistry.registerFluid(MILK); } } - public static class CommonProxy + @Mod.EventBusSubscriber(modid = MODID) + public static class Registration { - public void preInit(FMLPreInitializationEvent event) + @SubscribeEvent + public static void registerBlocks(RegistryEvent.Register event) { - FluidRegistry.registerFluid(TestFluid.instance); - FluidRegistry.registerFluid(TestGas.instance); - FluidRegistry.registerFluid(milkFluid); - GameRegistry.register(TestFluidBlock.instance); - GameRegistry.register(new ItemBlock(TestFluidBlock.instance).setRegistryName(TestFluidBlock.instance.getRegistryName())); - GameRegistry.register(TestGasBlock.instance); - GameRegistry.register(new ItemBlock(TestGasBlock.instance).setRegistryName(TestGasBlock.instance.getRegistryName())); - GameRegistry.register(MilkFluidBlock.instance); - GameRegistry.register(new ItemBlock(MilkFluidBlock.instance).setRegistryName(MilkFluidBlock.instance.getRegistryName())); + if (!ENABLE) + return; + event.getRegistry().registerAll( + new TestFluidBlock(), + new TestGasBlock(), + new MilkFluidBlock() + ); } - } - public static class ServerProxy extends CommonProxy - { - } - - public static class ClientProxy extends CommonProxy - { - private static ModelResourceLocation fluidLocation = new ModelResourceLocation(MODID.toLowerCase() + ":" + TestFluidBlock.name, "fluid"); - private static ModelResourceLocation gasLocation = new ModelResourceLocation(MODID.toLowerCase() + ":" + TestFluidBlock.name, "gas"); - private static ModelResourceLocation milkLocation = new ModelResourceLocation(MODID.toLowerCase() + ":" + TestFluidBlock.name, "milk"); - - @Override - public void preInit(FMLPreInitializationEvent event) + @SubscribeEvent + public static void registerItems(RegistryEvent.Register event) { - super.preInit(event); - Item fluid = Item.getItemFromBlock(TestFluidBlock.instance); - Item gas = Item.getItemFromBlock(TestGasBlock.instance); - Item milk = Item.getItemFromBlock(MilkFluidBlock.instance); + if (!ENABLE) + return; + event.getRegistry().registerAll( + new ItemBlock(FLUID_BLOCK).setRegistryName(FLUID_BLOCK.getRegistryName()), + new ItemBlock(GAS_BLOCK).setRegistryName(GAS_BLOCK.getRegistryName()), + new ItemBlock(MILK_BLOCK).setRegistryName(MILK_BLOCK.getRegistryName()) + ); + } + + @SubscribeEvent + public static void registerModels(ModelRegistryEvent event) + { + if (!ENABLE) + return; // no need to pass the locations here, since they'll be loaded by the block model logic. - ModelBakery.registerItemVariants(fluid); - ModelBakery.registerItemVariants(gas); - ModelBakery.registerItemVariants(milk); - ModelLoader.setCustomMeshDefinition(fluid, new ItemMeshDefinition() - { - public ModelResourceLocation getModelLocation(@Nonnull ItemStack stack) - { - return fluidLocation; - } - }); - ModelLoader.setCustomMeshDefinition(gas, new ItemMeshDefinition() - { - public ModelResourceLocation getModelLocation(@Nonnull ItemStack stack) - { - return gasLocation; - } - }); - ModelLoader.setCustomMeshDefinition(milk, new ItemMeshDefinition() - { - public ModelResourceLocation getModelLocation(@Nonnull ItemStack stack) - { - return milkLocation; - } - }); - ModelLoader.setCustomStateMapper(TestFluidBlock.instance, new StateMapperBase() + ModelBakery.registerItemVariants(FLUID_ITEM); + ModelBakery.registerItemVariants(GAS_ITEM); + ModelBakery.registerItemVariants(MILK_ITEM); + ModelLoader.setCustomMeshDefinition(FLUID_ITEM, is -> fluidLocation); + ModelLoader.setCustomMeshDefinition(GAS_ITEM, is -> gasLocation); + ModelLoader.setCustomMeshDefinition(MILK_ITEM, is -> milkLocation); + ModelLoader.setCustomStateMapper(FLUID_BLOCK, new StateMapperBase() { protected ModelResourceLocation getModelResourceLocation(IBlockState state) { return fluidLocation; } }); - ModelLoader.setCustomStateMapper(TestGasBlock.instance, new StateMapperBase() + ModelLoader.setCustomStateMapper(GAS_BLOCK, new StateMapperBase() { protected ModelResourceLocation getModelResourceLocation(IBlockState state) { return gasLocation; } }); - ModelLoader.setCustomStateMapper(MilkFluidBlock.instance, new StateMapperBase() + ModelLoader.setCustomStateMapper(MILK_BLOCK, new StateMapperBase() { protected ModelResourceLocation getModelResourceLocation(IBlockState state) { @@ -131,7 +129,6 @@ public class ModelFluidDebug public static final class TestFluid extends Fluid { public static final String name = "testfluid"; - public static final TestFluid instance = new TestFluid(); private TestFluid() { @@ -148,7 +145,6 @@ public class ModelFluidDebug public static final class TestGas extends Fluid { public static final String name = "testgas"; - public static final TestGas instance = new TestGas(); private TestGas() { @@ -166,12 +162,11 @@ public class ModelFluidDebug public static final class TestFluidBlock extends BlockFluidClassic { - public static final TestFluidBlock instance = new TestFluidBlock(); public static final String name = "test_fluid_block"; private TestFluidBlock() { - super(TestFluid.instance, Material.WATER); + super(FLUID, Material.WATER); setCreativeTab(CreativeTabs.BUILDING_BLOCKS); setUnlocalizedName(MODID + ":" + name); setRegistryName(new ResourceLocation(MODID, name)); @@ -180,12 +175,11 @@ public class ModelFluidDebug public static final class MilkFluidBlock extends BlockFluidClassic { - public static final MilkFluidBlock instance = new MilkFluidBlock(); public static final String name = "milk_fluid_block"; private MilkFluidBlock() { - super(milkFluid, Material.WATER); + super(MILK, Material.WATER); setCreativeTab(CreativeTabs.BUILDING_BLOCKS); setUnlocalizedName(MODID + ":" + name); setRegistryName(new ResourceLocation(MODID, name)); @@ -194,12 +188,11 @@ public class ModelFluidDebug public static final class TestGasBlock extends BlockFluidClassic { - public static final TestGasBlock instance = new TestGasBlock(); public static final String name = "test_gas_block"; private TestGasBlock() { - super(TestGas.instance, Material.LAVA); + super(GAS, Material.LAVA); setCreativeTab(CreativeTabs.BUILDING_BLOCKS); setUnlocalizedName(MODID + ":" + name); setRegistryName(new ResourceLocation(MODID, name)); diff --git a/src/test/java/net/minecraftforge/debug/ModelLoaderRegistryDebug.java b/src/test/java/net/minecraftforge/debug/ModelLoaderRegistryDebug.java index a54196d5f0..a013e52cdf 100644 --- a/src/test/java/net/minecraftforge/debug/ModelLoaderRegistryDebug.java +++ b/src/test/java/net/minecraftforge/debug/ModelLoaderRegistryDebug.java @@ -1,7 +1,6 @@ package net.minecraftforge.debug; import com.google.common.base.Optional; -import com.google.common.collect.Lists; import com.google.common.collect.UnmodifiableIterator; import net.minecraft.block.Block; import net.minecraft.block.ITileEntityProvider; @@ -28,6 +27,7 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.TextComponentString; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.client.model.b3d.B3DLoader; import net.minecraftforge.client.model.obj.OBJLoader; @@ -39,11 +39,13 @@ import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; import net.minecraftforge.common.property.Properties; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.registry.GameRegistry; -import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; import org.apache.logging.log4j.Logger; import javax.vecmath.AxisAngle4d; @@ -62,71 +64,100 @@ public class ModelLoaderRegistryDebug public static final String VERSION = "1.0"; private static Logger logger; + @ObjectHolder(CustomModelBlock.name) + public static final Block CUSTOM_MODEL_BLOCK = null; + @ObjectHolder(OBJTesseractBlock.name) + public static final Block TESSERACT_BLOCK = null; + @ObjectHolder(OBJVertexColoring1.name) + public static final Block VERTEX_COLOR_1 = null; + @ObjectHolder(OBJVertexColoring2.name) + public static final Block VERTEX_COLOR_2 = null; + @ObjectHolder(OBJDirectionBlock.name) + public static final Block DIRECTION = null; + @ObjectHolder(OBJDirectionEye.name) + public static final Block DIRECTION_EYE = null; + @ObjectHolder(OBJDynamicEye.name) + public static final Block DYNAMIC_EYE = null; + @ObjectHolder(OBJCustomDataBlock.name) + public static final Block CUSTOM_DATA = null; + @EventHandler public void preInit(FMLPreInitializationEvent event) { if (!ENABLED) - { return; - } logger = event.getModLog(); - List blocks = Lists.newArrayList(); - blocks.add(CustomModelBlock.instance); - blocks.add(OBJTesseractBlock.instance); - blocks.add(OBJVertexColoring1.instance); - //blocks.add(OBJDirectionEye.instance); - blocks.add(OBJVertexColoring2.instance); - blocks.add(OBJDirectionBlock.instance); - blocks.add(OBJCustomDataBlock.instance); - //blocks.add(OBJDynamicEye.instance); - for (Block block : blocks) - { - GameRegistry.register(block); - GameRegistry.register(new ItemBlock(block).setRegistryName(block.getRegistryName())); - } - GameRegistry.registerTileEntity(OBJTesseractTileEntity.class, OBJTesseractBlock.name); - GameRegistry.registerTileEntity(OBJVertexColoring2TileEntity.class, OBJVertexColoring2.name); - //GameRegistry.registerTileEntity(OBJDynamicEyeTileEntity.class, OBJDynamicEye.name); - if (event.getSide() == Side.CLIENT) - { - clientPreInit(); - } } - private void clientPreInit() + + @Mod.EventBusSubscriber(modid = MODID) + public static class Registration { - B3DLoader.INSTANCE.addDomain(MODID.toLowerCase()); - Item item = Item.getItemFromBlock(CustomModelBlock.instance); - ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(MODID.toLowerCase() + ":" + CustomModelBlock.name, "inventory")); + @SubscribeEvent + public static void registerBlocks(RegistryEvent.Register event) + { + if (!ENABLED) + return; + event.getRegistry().registerAll( + new CustomModelBlock(), + new OBJTesseractBlock(), + new OBJVertexColoring1(), + new OBJVertexColoring2(), + new OBJDirectionBlock(), + //new OBJDirectionEye(), + //new OBJDynamicEye(), + new OBJCustomDataBlock() + ); + GameRegistry.registerTileEntity(OBJTesseractTileEntity.class, OBJTesseractBlock.name); + GameRegistry.registerTileEntity(OBJVertexColoring2TileEntity.class, OBJVertexColoring2.name); + //GameRegistry.registerTileEntity(OBJDynamicEyeTileEntity.class, OBJDynamicEye.name); + } - OBJLoader.INSTANCE.addDomain(MODID.toLowerCase()); - Item item2 = Item.getItemFromBlock(OBJTesseractBlock.instance); - ModelLoader.setCustomModelResourceLocation(item2, 0, new ModelResourceLocation(MODID.toLowerCase() + ":" + OBJTesseractBlock.name, "inventory")); + @SubscribeEvent + public static void registerItems(RegistryEvent.Register event) + { + if (!ENABLED) + return; + Block[] blocks = { + CUSTOM_MODEL_BLOCK, + TESSERACT_BLOCK, + VERTEX_COLOR_1, + VERTEX_COLOR_2, + DIRECTION, + //DIRECTION_EYE, + //DYNAMIC_EYE, + CUSTOM_DATA + }; + for (Block block : blocks) + event.getRegistry().register(new ItemBlock(block).setRegistryName(block.getRegistryName())); + } - Item item3 = Item.getItemFromBlock(OBJVertexColoring1.instance); - ModelLoader.setCustomModelResourceLocation(item3, 0, new ModelResourceLocation(MODID.toLowerCase() + ":" + OBJVertexColoring1.name, "inventory")); - - //Item item4 = Item.getItemFromBlock(OBJDirectionEye.instance); - //ModelLoader.setCustomModelResourceLocation(item4, 0, new ModelResourceLocation(MODID.toLowerCase() + ":" + OBJDirectionEye.name, "inventory")); - - Item item5 = Item.getItemFromBlock(OBJVertexColoring2.instance); - ModelLoader.setCustomModelResourceLocation(item5, 0, new ModelResourceLocation(MODID.toLowerCase() + ":" + OBJVertexColoring2.name, "inventory")); - - Item item6 = Item.getItemFromBlock(OBJDirectionBlock.instance); - ModelLoader.setCustomModelResourceLocation(item6, 0, new ModelResourceLocation(MODID.toLowerCase() + ":" + OBJDirectionBlock.name, "inventory")); - - Item item7 = Item.getItemFromBlock(OBJCustomDataBlock.instance); - ModelLoader.setCustomModelResourceLocation(item7, 0, new ModelResourceLocation(MODID.toLowerCase() + ":" + OBJCustomDataBlock.name, "inventory")); - - //Item item8 = Item.getItemFromBlock(OBJDynamicEye.instance); - //ModelLoader.setCustomModelResourceLocation(item8, 0, new ModelResourceLocation(MODID.toLowerCase() + ":" + OBJDynamicEye.name, "inventory")); + @SubscribeEvent + public static void registerModels(ModelRegistryEvent event) + { + if (!ENABLED) + return; + B3DLoader.INSTANCE.addDomain(MODID.toLowerCase()); + OBJLoader.INSTANCE.addDomain(MODID.toLowerCase()); + Block[] blocks = { + CUSTOM_MODEL_BLOCK, + TESSERACT_BLOCK, + VERTEX_COLOR_1, + VERTEX_COLOR_2, + DIRECTION, + //DIRECTION_EYE, + //DYNAMIC_EYE, + CUSTOM_DATA + }; + for (Block block : blocks) + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0, new ModelResourceLocation(block.getRegistryName(), "inventory")); + } } public static class CustomModelBlock extends Block { public static final PropertyDirection FACING = PropertyDirection.create("facing"); - public static final CustomModelBlock instance = new CustomModelBlock(); public static final String name = "custom_model_block"; private int counter = 1; @@ -243,7 +274,6 @@ public class ModelLoaderRegistryDebug */ public static class OBJTesseractBlock extends Block implements ITileEntityProvider { - public static final OBJTesseractBlock instance = new OBJTesseractBlock(); public static final String name = "obj_tesseract_block"; private OBJTesseractBlock() @@ -404,7 +434,6 @@ public class ModelLoaderRegistryDebug */ public static class OBJVertexColoring1 extends Block { - public static final OBJVertexColoring1 instance = new OBJVertexColoring1(); public static final String name = "obj_vertex_coloring1"; private OBJVertexColoring1() @@ -445,7 +474,6 @@ public class ModelLoaderRegistryDebug public static class OBJDirectionEye extends Block { public static final PropertyDirection FACING = PropertyDirection.create("facing"); - public static final OBJDirectionEye instance = new OBJDirectionEye(); public static final String name = "obj_direction_eye"; private OBJDirectionEye() @@ -529,7 +557,6 @@ public class ModelLoaderRegistryDebug */ public static class OBJVertexColoring2 extends Block implements ITileEntityProvider { - public static final OBJVertexColoring2 instance = new OBJVertexColoring2(); public static final String name = "obj_vertex_coloring2"; private OBJVertexColoring2() @@ -633,7 +660,6 @@ public class ModelLoaderRegistryDebug public static class OBJDirectionBlock extends Block { public static final PropertyDirection FACING = PropertyDirection.create("facing"); - public static final OBJDirectionBlock instance = new OBJDirectionBlock(); public static final String name = "obj_direction_block"; private OBJDirectionBlock() @@ -720,7 +746,6 @@ public class ModelLoaderRegistryDebug public static final PropertyBool SOUTH = PropertyBool.create("south"); public static final PropertyBool WEST = PropertyBool.create("west"); public static final PropertyBool EAST = PropertyBool.create("east"); - public static final OBJCustomDataBlock instance = new OBJCustomDataBlock(); public static final String name = "obj_custom_data_block"; private OBJCustomDataBlock() @@ -777,7 +802,6 @@ public class ModelLoaderRegistryDebug */ public static class OBJDynamicEye extends Block implements ITileEntityProvider { - public static final OBJDynamicEye instance = new OBJDynamicEye(); public static final String name = "obj_dynamic_eye"; private OBJDynamicEye() diff --git a/src/test/java/net/minecraftforge/debug/MultiLayerModelDebug.java b/src/test/java/net/minecraftforge/debug/MultiLayerModelDebug.java index 67f12f8da8..6eb6e0f8f2 100644 --- a/src/test/java/net/minecraftforge/debug/MultiLayerModelDebug.java +++ b/src/test/java/net/minecraftforge/debug/MultiLayerModelDebug.java @@ -9,76 +9,75 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.Mod.EventHandler; -import net.minecraftforge.fml.common.SidedProxy; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; @Mod(modid = MultiLayerModelDebug.MODID, name = "ForgeDebugMultiLayerModel", version = MultiLayerModelDebug.VERSION, acceptableRemoteVersions = "*") public class MultiLayerModelDebug { + private static final boolean ENABLED = true; public static final String MODID = "forgedebugmultilayermodel"; public static final String VERSION = "0.0"; - private static String blockName = "test_layer_block"; + private static final String blockName = "test_layer_block"; private static final ResourceLocation blockId = new ResourceLocation(MODID, blockName); + @ObjectHolder(blockName) + public static final Block TEST_BLOCK = null; - @SidedProxy - public static CommonProxy proxy; - - public static class CommonProxy + @Mod.EventBusSubscriber(modid = MODID) + public static class Registration { - public void preInit(FMLPreInitializationEvent event) + @SubscribeEvent + public static void registerBlocks(RegistryEvent.Register event) { - GameRegistry.register(new Block(Material.WOOD) - { + if (!ENABLED) + return; + event.getRegistry().register( + new Block(Material.WOOD) { - setCreativeTab(CreativeTabs.BUILDING_BLOCKS); - setUnlocalizedName(MODID + "." + blockName); - setRegistryName(blockId); - } + { + setCreativeTab(CreativeTabs.BUILDING_BLOCKS); + setUnlocalizedName(MODID + "." + blockName); + setRegistryName(blockId); + } - @Override - public boolean isOpaqueCube(IBlockState state) - { - return false; - } + @Override + public boolean isOpaqueCube(IBlockState state) + { + return false; + } - @Override - public boolean isFullCube(IBlockState state) - { - return false; - } + @Override + public boolean isFullCube(IBlockState state) + { + return false; + } - @Override - public boolean canRenderInLayer(IBlockState state, BlockRenderLayer layer) - { - return layer == BlockRenderLayer.SOLID || layer == BlockRenderLayer.TRANSLUCENT; + @Override + public boolean canRenderInLayer(IBlockState state, BlockRenderLayer layer) + { + return layer == BlockRenderLayer.SOLID || layer == BlockRenderLayer.TRANSLUCENT; + } } - }); - GameRegistry.register(new ItemBlock(Block.REGISTRY.getObject(blockId)).setRegistryName(blockId)); + ); } - } - public static class ServerProxy extends CommonProxy - { - } - - public static class ClientProxy extends CommonProxy - { - @Override - public void preInit(FMLPreInitializationEvent event) + @SubscribeEvent + public static void registerItems(RegistryEvent.Register event) { - super.preInit(event); - ModelLoader.setCustomModelResourceLocation(Item.REGISTRY.getObject(blockId), 0, new ModelResourceLocation(blockId, "inventory")); + event.getRegistry().register(new ItemBlock(TEST_BLOCK).setRegistryName(TEST_BLOCK.getRegistryName())); } - } - @EventHandler - public void preInit(FMLPreInitializationEvent event) - { - proxy.preInit(event); + @SubscribeEvent + public static void registerModels(ModelRegistryEvent event) + { + if (!ENABLED) + return; + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(TEST_BLOCK), 0, new ModelResourceLocation(blockId, "inventory")); + } } } diff --git a/src/test/java/net/minecraftforge/debug/NBTShareTagItemTest.java b/src/test/java/net/minecraftforge/debug/NBTShareTagItemTest.java index 11c665cfdd..fe0266707a 100644 --- a/src/test/java/net/minecraftforge/debug/NBTShareTagItemTest.java +++ b/src/test/java/net/minecraftforge/debug/NBTShareTagItemTest.java @@ -5,41 +5,53 @@ import net.minecraft.creativetab.CreativeTabs; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.Ingredient; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.registry.GameRegistry; -import net.minecraftforge.fml.relauncher.Side; - +import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; import javax.annotation.Nullable; -@Mod(modid = NBTShareTagItemTest.MOD_ID, name = "NBTShareTag Item Test", version = "1.0.0", acceptableRemoteVersions = "*") +@Mod(modid = NBTShareTagItemTest.MODID, name = "NBTShareTag Item Test", version = "1.0.0", acceptableRemoteVersions = "*") public class NBTShareTagItemTest { - public static final String MOD_ID = "nbtsharetagitemtest"; - private static final ResourceLocation itemName = new ResourceLocation(MOD_ID, "nbt_share_tag_item"); + public static final String MODID = "nbtsharetagitemtest"; + private static final ResourceLocation itemName = new ResourceLocation(MODID, "nbt_share_tag_item"); + @ObjectHolder("nbt_share_tag_item") + public static final Item TEST_ITEM = null; - @Mod.EventHandler - public void preInit(FMLPreInitializationEvent event) + @Mod.EventBusSubscriber(modid = MODID) + public static class Registration { - ShareTagItem item = new ShareTagItem(); - item.setRegistryName(itemName); - GameRegistry.register(item); - - if (event.getSide() == Side.CLIENT) + @SubscribeEvent + public static void registerRecipes(RegistryEvent.Register event) { - ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(itemName, "inventory")); + ItemStack crafted = new ItemStack(TEST_ITEM); + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setBoolean("crafted", true); + crafted.setTagCompound(nbt); + + GameRegistry.addShapelessRecipe(new ResourceLocation(MODID, "nbt_share"), null, crafted, Ingredient.func_193367_a(Items.STICK)); } - ItemStack crafted = new ItemStack(item); - NBTTagCompound craftedNBT = new NBTTagCompound(); - craftedNBT.setBoolean("crafted", true); - crafted.setTagCompound(craftedNBT); - //CraftingManager.getInstance().addShapelessRecipe(crafted, new ItemStack(Items.STICK)); + @SubscribeEvent + public static void registerItems(RegistryEvent.Register event) + { + event.getRegistry().register(new ShareTagItem().setRegistryName(itemName)); + } + + @SubscribeEvent + public static void registerModels(ModelRegistryEvent event) + { + ModelLoader.setCustomModelResourceLocation(TEST_ITEM, 0, new ModelResourceLocation(itemName, "inventory")); + } } public static class ShareTagItem extends Item diff --git a/src/test/java/net/minecraftforge/debug/NoBedSleepingTest.java b/src/test/java/net/minecraftforge/debug/NoBedSleepingTest.java index 77d698b7e7..06231b1883 100644 --- a/src/test/java/net/minecraftforge/debug/NoBedSleepingTest.java +++ b/src/test/java/net/minecraftforge/debug/NoBedSleepingTest.java @@ -16,6 +16,7 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; +import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.Capability; @@ -24,14 +25,14 @@ import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.common.capabilities.ICapabilitySerializable; import net.minecraftforge.event.AttachCapabilitiesEvent; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.entity.player.PlayerWakeUpEvent; import net.minecraftforge.event.entity.player.SleepingLocationCheckEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.eventhandler.Event.Result; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -43,38 +44,30 @@ public class NoBedSleepingTest public static final String VERSION = "1.0"; @CapabilityInject(IExtraSleeping.class) private static final Capability SLEEP_CAP = null; + @ObjectHolder(ItemSleepingPill.name) + public static final Item SLEEPING_PILL = null; - @SidedProxy - public static CommonProxy proxy = null; - - public static abstract class CommonProxy + @Mod.EventBusSubscriber(modid = MODID) + public static class Registration { - public void preInit(FMLPreInitializationEvent event) + @SubscribeEvent + public static void registerItems(RegistryEvent.Register event) { - GameRegistry.register(ItemSleepingPill.instance); - CapabilityManager.INSTANCE.register(IExtraSleeping.class, new Storage(), DefaultImpl.class); - MinecraftForge.EVENT_BUS.register(new EventHandler()); + event.getRegistry().register(new ItemSleepingPill()); } - } - public static final class ServerProxy extends CommonProxy - { - } - - public static final class ClientProxy extends CommonProxy - { - @Override - public void preInit(FMLPreInitializationEvent event) + @SubscribeEvent + public static void registerModels(ModelRegistryEvent event) { - super.preInit(event); - ModelLoader.setCustomModelResourceLocation(ItemSleepingPill.instance, 0, new ModelResourceLocation(new ResourceLocation(MODID, ItemSleepingPill.name), "inventory")); + ModelLoader.setCustomModelResourceLocation(SLEEPING_PILL, 0, new ModelResourceLocation(SLEEPING_PILL.getRegistryName(), "inventory")); } } @Mod.EventHandler public void preInit(FMLPreInitializationEvent event) { - proxy.preInit(event); + CapabilityManager.INSTANCE.register(IExtraSleeping.class, new Storage(), DefaultImpl.class); + MinecraftForge.EVENT_BUS.register(new EventHandler()); } public static class EventHandler @@ -180,7 +173,6 @@ public class NoBedSleepingTest public static class ItemSleepingPill extends Item { - public static final ItemSleepingPill instance = new ItemSleepingPill(); public static final String name = "sleeping_pill"; private ItemSleepingPill() diff --git a/src/test/java/net/minecraftforge/debug/NoPotionEffectRenderTest.java b/src/test/java/net/minecraftforge/debug/NoPotionEffectRenderTest.java index d2b83b9ea7..c048a61959 100644 --- a/src/test/java/net/minecraftforge/debug/NoPotionEffectRenderTest.java +++ b/src/test/java/net/minecraftforge/debug/NoPotionEffectRenderTest.java @@ -5,7 +5,7 @@ import net.minecraft.potion.PotionEffect; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.registry.GameData; +import net.minecraftforge.fml.common.registry.ForgeRegistries; @Mod(modid = NoPotionEffectRenderTest.modID, name = "No Potion Effect Render Test", version = "0.0.0", acceptableRemoteVersions = "*") public class NoPotionEffectRenderTest @@ -15,8 +15,8 @@ public class NoPotionEffectRenderTest @Mod.EventHandler public void preInit(FMLPreInitializationEvent event) { - TestPotion INSTANCE = new TestPotion(new ResourceLocation(modID, "test_potion"), false, 0xff00ff); - GameData.getPotionRegistry().register(-1, new ResourceLocation(modID, "test_potion"), INSTANCE); + TestPotion INSTANCE = (TestPotion)new TestPotion(new ResourceLocation(modID, "test_potion"), false, 0xff00ff).setRegistryName(new ResourceLocation(modID, "test_potion")); + ForgeRegistries.POTIONS.register(INSTANCE); } public static class TestPotion extends Potion diff --git a/src/test/java/net/minecraftforge/debug/ObjectHolderTest.java b/src/test/java/net/minecraftforge/debug/ObjectHolderTest.java index 2a03d472b0..61237b3e09 100644 --- a/src/test/java/net/minecraftforge/debug/ObjectHolderTest.java +++ b/src/test/java/net/minecraftforge/debug/ObjectHolderTest.java @@ -9,15 +9,13 @@ import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.registry.GameRegistry; -import net.minecraftforge.fml.common.registry.IForgeRegistry; -import net.minecraftforge.fml.common.registry.IForgeRegistryEntry; -import net.minecraftforge.fml.common.registry.RegistryBuilder; +import net.minecraftforge.registries.IForgeRegistryEntry; +import net.minecraftforge.registries.RegistryBuilder; @Mod(modid = ObjectHolderTest.MODID, name = "ObjectHolderTests", version = "1.0", acceptableRemoteVersions = "*") public class ObjectHolderTest { public static final String MODID = "objectholdertest"; - public static IForgeRegistry registry; @Mod.EventHandler public void init(FMLInitializationEvent event) @@ -64,7 +62,7 @@ public class ObjectHolderTest public static void registerPotions(RegistryEvent.Register event) { event.getRegistry().register( - new ObjectHolderTest.PotionForge(new ResourceLocation(ObjectHolderTest.MODID, "forge_potion"), false, 0xff00ff) // test automatic id distribution + new ObjectHolderTest.PotionForge(new ResourceLocation(ObjectHolderTest.MODID, "forge_potion"), false, 0xff00ff) // test automatic id distribution ); } @@ -72,68 +70,65 @@ public class ObjectHolderTest public static void registerInterfaceRegistryForge(RegistryEvent.Register event) { event.getRegistry().register( - new CustomRegistryEntry().setRegistryName(new ResourceLocation(MODID, "custom_entry_by_interface")) + new CustomRegistryEntry().setRegistryName(new ResourceLocation(MODID, "custom_entry_by_interface")) ); event.getRegistry().register( - new CustomRegistryEntry().setRegistryName(new ResourceLocation(MODID, "custom_entry")) + new CustomRegistryEntry().setRegistryName(new ResourceLocation(MODID, "custom_entry")) ); } } -} + interface ICustomRegistryEntry extends IForgeRegistryEntry{} -class CustomRegistryEntry implements ICustomRegistryEntry -{ - private ResourceLocation name; - @Override - public ICustomRegistryEntry setRegistryName(ResourceLocation name) + static class CustomRegistryEntry implements ICustomRegistryEntry { - this.name = name; - return this; + private ResourceLocation name; + + @Override + public ICustomRegistryEntry setRegistryName(ResourceLocation name) + { + this.name = name; + return this; + } + + @Override + public ResourceLocation getRegistryName() + { + return name; + } + + @Override + public Class getRegistryType() + { + return ICustomRegistryEntry.class; + } } - @Override - public ResourceLocation getRegistryName() + @GameRegistry.ObjectHolder("minecraft") + static class VanillaObjectHolder { - return name; + //Tests importing vanilla objects that need the @ObjectHolder annotation to get a valid ResourceLocation + @GameRegistry.ObjectHolder("ui.button.click") + public static final SoundEvent uiButtonClick = null; + public static final Block air = null; + public static final Block nonExistentBlock = null; } - @Override - public Class getRegistryType() + @GameRegistry.ObjectHolder(ObjectHolderTest.MODID) + static class ForgeObjectHolder { - return ICustomRegistryEntry.class; + //Tests using subclasses for injections + public static final ObjectHolderTest.PotionForge forge_potion = null; + } + + @GameRegistry.ObjectHolder(ObjectHolderTest.MODID) + static class CustomRegistryObjectHolder + { + //Tests whether custom registries can be used + public static final ICustomRegistryEntry custom_entry = null; + + //Tests whether interfaces can be used + public static final ICustomRegistryEntry custom_entry_by_interface = null; } } - -interface ICustomRegistryEntry extends IForgeRegistryEntry -{ - -} - -@GameRegistry.ObjectHolder("minecraft") -class VanillaObjectHolder -{ - //Tests importing vanilla objects that need the @ObjectHolder annotation to get a valid ResourceLocation - @GameRegistry.ObjectHolder("ui.button.click") - public static final SoundEvent uiButtonClick = null; - public static final Block air = null; - public static final Block nonExistentBlock = null; -} - -@GameRegistry.ObjectHolder(ObjectHolderTest.MODID) -class ForgeObjectHolder -{ - //Tests using subclasses for injections - public static final ObjectHolderTest.PotionForge forge_potion = null; -} - -@GameRegistry.ObjectHolder(ObjectHolderTest.MODID) -class CustomRegistryObjectHolder -{ - //Tests whether custom registries can be used - public static final ICustomRegistryEntry custom_entry = null; - - //Tests whether interfaces can be used - public static final ICustomRegistryEntry custom_entry_by_interface = null; -} diff --git a/src/test/java/net/minecraftforge/debug/PotionCurativeItemDebug.java b/src/test/java/net/minecraftforge/debug/PotionCurativeItemDebug.java index 0920e6247a..853b9abe2e 100644 --- a/src/test/java/net/minecraftforge/debug/PotionCurativeItemDebug.java +++ b/src/test/java/net/minecraftforge/debug/PotionCurativeItemDebug.java @@ -8,9 +8,10 @@ import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.potion.PotionType; import net.minecraft.world.World; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; import java.util.ArrayList; import java.util.Collections; @@ -23,33 +24,43 @@ import java.util.List; * 3. Drink incurable_potion from Brewing creative tab * 4. Relog to test that changes to curative items persist, then try drinking milk and eating medicine: they should have no effect */ -@Mod(modid = PotionCurativeItemDebug.MOD_ID, name = "Potion Curative Item Debug", version = "1.0", acceptableRemoteVersions = "*") +@Mod(modid = PotionCurativeItemDebug.MODID, name = "Potion Curative Item Debug", version = "1.0", acceptableRemoteVersions = "*") public class PotionCurativeItemDebug { public static final boolean ENABLED = false; - public static final String MOD_ID = "potion_curative_item_debug"; + public static final String MODID = "potion_curative_item_debug"; + @ObjectHolder("medicine") + public static final Item MEDICINE = null; + private static Potion INCURABLE_POTION; - @Mod.EventHandler - public void preInit(FMLPreInitializationEvent evt) + @Mod.EventBusSubscriber(modid = MODID) + public static class Registration { - if (!ENABLED) + @SubscribeEvent + public static void registerItems(RegistryEvent.Register event) { - return; + if (!ENABLED) return; + event.getRegistry().register(new Medicine().setRegistryName(MODID, "medicine")); } + @SubscribeEvent + public static void registerPotions(RegistryEvent.Register event) + { + if (!ENABLED) return; + INCURABLE_POTION = new IncurablePotion().setRegistryName(MODID, "incurable_potion"); + event.getRegistry().register(INCURABLE_POTION); + } + @SubscribeEvent + public static void registerPotionTypes(RegistryEvent.Register event) + { + if (!ENABLED) return; + // Register PotionType that can be cured with medicine + PotionEffect curable = new PotionEffect(INCURABLE_POTION, 1200); + curable.setCurativeItems(Collections.singletonList(new ItemStack(MEDICINE))); + event.getRegistry().register(new PotionType(curable).setRegistryName(MODID, "curable_potion_type")); - Item medicine = new Medicine().setRegistryName(MOD_ID, "medicine"); - GameRegistry.register(medicine); - - Potion incurablePotion = new IncurablePotion().setRegistryName(MOD_ID, "incurable_potion"); - GameRegistry.register(incurablePotion); - - // Register PotionType that can be cured with medicine - PotionEffect curable = new PotionEffect(incurablePotion, 1200); - curable.setCurativeItems(Collections.singletonList(new ItemStack(medicine))); - GameRegistry.register(new PotionType(curable).setRegistryName(MOD_ID, "curable_potion_type")); - - // Register PotionType that can't be cured - GameRegistry.register(new PotionType(new PotionEffect(incurablePotion, 1200)).setRegistryName(MOD_ID, "incurable_potion_type")); + // Register PotionType that can't be cured + event.getRegistry().register(new PotionType(new PotionEffect(INCURABLE_POTION, 1200)).setRegistryName(MODID, "incurable_potion_type")); + } } private static class IncurablePotion extends Potion diff --git a/src/test/java/net/minecraftforge/debug/PotionRegistryDebug.java b/src/test/java/net/minecraftforge/debug/PotionRegistryDebug.java index 2aef6b8448..52ead16f6a 100644 --- a/src/test/java/net/minecraftforge/debug/PotionRegistryDebug.java +++ b/src/test/java/net/minecraftforge/debug/PotionRegistryDebug.java @@ -15,7 +15,8 @@ import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.ForgeVersion; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.registry.GameData; +import net.minecraftforge.fml.common.registry.ForgeRegistries; +import net.minecraftforge.registries.GameData; import java.util.Random; @@ -27,10 +28,10 @@ public class PotionRegistryDebug @Mod.EventHandler public void preInit(FMLPreInitializationEvent event) { - Potion forge = new PotionForge(new ResourceLocation(ForgeVersion.MOD_ID, "forge"), false, 0xff00ff); // test automatic id distribution - Potion forgy = new PotionForge(new ResourceLocation(ForgeVersion.MOD_ID, "forgy"), true, 0x00ff00); // test that ids above 127 work - GameData.getPotionRegistry().register(-1, new ResourceLocation(ForgeVersion.MOD_ID, "forge"), forge); //TODo: Generic this out in GameRegistry, 'RegistryEntry' base type? - GameData.getPotionRegistry().register(200, new ResourceLocation(ForgeVersion.MOD_ID, "forgy"), forgy); + Potion forge = new PotionForge(new ResourceLocation(ForgeVersion.MOD_ID, "forge"), false, 0xff00ff).setRegistryName(new ResourceLocation(ForgeVersion.MOD_ID, "forge")); // test automatic id distribution + Potion forgy = new PotionForge(new ResourceLocation(ForgeVersion.MOD_ID, "forgy"), true, 0x00ff00).setRegistryName(new ResourceLocation(ForgeVersion.MOD_ID, "forgy")); // test that ids above 127 work + ForgeRegistries.POTIONS.register(forge); + Potion.REGISTRY.register(200, forgy.getRegistryName(), forgy); Random rand = new Random(); TIntSet taken = new TIntHashSet(100); diff --git a/src/test/java/net/minecraftforge/debug/TileEntityLoadingTest.java b/src/test/java/net/minecraftforge/debug/TileEntityLoadingTest.java index 88aa48c34c..3dd8f36947 100644 --- a/src/test/java/net/minecraftforge/debug/TileEntityLoadingTest.java +++ b/src/test/java/net/minecraftforge/debug/TileEntityLoadingTest.java @@ -4,36 +4,56 @@ import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; + import org.apache.logging.log4j.Logger; import javax.annotation.Nullable; -@Mod(modid = TileEntityLoadingTest.MOD_ID, name = "TileEntity#onLoad() test mod", version = "1.0", acceptableRemoteVersions = "*") +@Mod(modid = TileEntityLoadingTest.MODID, name = "TileEntity#onLoad() test mod", version = "1.0", acceptableRemoteVersions = "*") public class TileEntityLoadingTest { public static final boolean ENABLED = false; - static final String MOD_ID = "te_loading_test"; + static final String MODID = "te_loading_test"; static final boolean DEBUG = false; private static Logger logger; - private static final Block testBlock = new TestBlock(); + @ObjectHolder(TestBlock.NAME) + private static final Block TEST_BLOCK = null; + + @Mod.EventBusSubscriber(modid = MODID) + public static class Registration + { + @SubscribeEvent + public static void registerBlocks(RegistryEvent.Register event) + { + if (!ENABLED) return; + event.getRegistry().register(new TestBlock()); + GameRegistry.registerTileEntity(TestTE.class, (new ResourceLocation(MODID, TestBlock.NAME)).toString()); + } + @SubscribeEvent + public static void registerItems(RegistryEvent.Register event) + { + if (!ENABLED) return; + event.getRegistry().register(new ItemBlock(TEST_BLOCK).setRegistryName(TEST_BLOCK.getRegistryName())); + } + } @Mod.EventHandler public static void preInit(FMLPreInitializationEvent event) { if (ENABLED) - { logger = event.getModLog(); - GameRegistry.register(testBlock); - GameRegistry.register(new ItemBlock(testBlock).setRegistryName(testBlock.getRegistryName())); - GameRegistry.registerTileEntity(TestTE.class, testBlock.getRegistryName().toString()); - } } public static class TestBlock extends Block @@ -44,7 +64,7 @@ public class TileEntityLoadingTest { super(Material.ANVIL); setRegistryName(NAME); - setUnlocalizedName(MOD_ID + "." + NAME); + setUnlocalizedName(MODID + "." + NAME); setCreativeTab(CreativeTabs.BUILDING_BLOCKS); } diff --git a/src/test/java/net/minecraftforge/debug/WrenchRotateDebug.java b/src/test/java/net/minecraftforge/debug/WrenchRotateDebug.java index e078ddbcbd..0c8ccea2d2 100644 --- a/src/test/java/net/minecraftforge/debug/WrenchRotateDebug.java +++ b/src/test/java/net/minecraftforge/debug/WrenchRotateDebug.java @@ -2,7 +2,6 @@ package net.minecraftforge.debug; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.ItemMeshDefinition; import net.minecraft.client.renderer.block.model.ModelBakery; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.creativetab.CreativeTabs; @@ -15,58 +14,37 @@ import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.SidedProxy; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; @Mod(modid = WrenchRotateDebug.modID, name = "Wrench Rotate Debug", version = "0.0.0", acceptableRemoteVersions = "*") public class WrenchRotateDebug { public static final String modID = "wrenchrotatedebug"; private static final ResourceLocation testWrenchName = new ResourceLocation(modID, "test_wrench"); + @ObjectHolder("test_wrench") + public static final Item TEST_WRENCH = null; - @SidedProxy - public static CommonProxy proxy; - @Mod.EventHandler - public void preInit(FMLPreInitializationEvent event) + @Mod.EventBusSubscriber(modid = modID) + public static class Registration { - TestWrench wrench = new TestWrench(); - wrench.setRegistryName(testWrenchName); - - GameRegistry.register(wrench); - proxy.setupModel(wrench); - } - - public static class CommonProxy - { - void setupModel(TestWrench wrench) + @SubscribeEvent + public static void registerItems(RegistryEvent.Register event) { + event.getRegistry().register(new TestWrench().setRegistryName(testWrenchName)); } - } - public static class ServerProxy extends CommonProxy - { - } - - public static class ClientProxy extends CommonProxy - { - @SuppressWarnings("unused") - @Override - void setupModel(TestWrench wrench) + @SubscribeEvent + public static void registerModels(ModelRegistryEvent event) { final ModelResourceLocation wrenchName = new ModelResourceLocation(testWrenchName, "inventory"); - ModelBakery.registerItemVariants(wrench, wrenchName); - ModelLoader.setCustomMeshDefinition(wrench, new ItemMeshDefinition() - { - @Override - public ModelResourceLocation getModelLocation(ItemStack stack) - { - return wrenchName; - } - }); + ModelBakery.registerItemVariants(TEST_WRENCH, wrenchName); + ModelLoader.setCustomMeshDefinition(TEST_WRENCH, is -> wrenchName); } } diff --git a/src/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java b/src/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java index 83e12de35a..2b2429834e 100644 --- a/src/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java +++ b/src/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java @@ -7,6 +7,8 @@ import net.minecraft.init.Bootstrap; import net.minecraftforge.fml.common.DummyModContainer; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.ModMetadata; +import net.minecraftforge.registries.GameData; + import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/src/test/java/net/minecraftforge/fml/common/registry/DummyBlockReplacementTest.java b/src/test/java/net/minecraftforge/fml/common/registry/DummyBlockReplacementTest.java index 7fe54876c0..00add31110 100644 --- a/src/test/java/net/minecraftforge/fml/common/registry/DummyBlockReplacementTest.java +++ b/src/test/java/net/minecraftforge/fml/common/registry/DummyBlockReplacementTest.java @@ -8,10 +8,18 @@ import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.DummyModContainer; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.ModMetadata; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.GameData; +import net.minecraftforge.registries.ObjectHolderRegistry; +import net.minecraftforge.registries.RegistryManager; + import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; +import com.google.common.collect.Maps; + +import java.util.Map; import java.util.Set; import static org.junit.Assert.*; @@ -44,48 +52,49 @@ public class DummyBlockReplacementTest @Test public void testDummyBlockReplacement() { - final PersistentRegistryManager.GameDataSnapshot snapshot = PersistentRegistryManager.takeSnapshot(); - PersistentRegistryManager.freezeData(); + final Map snapshot = Maps.newHashMap(); + GameData.freezeData(); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); - final FMLControlledNamespacedRegistry blockRegistry = (FMLControlledNamespacedRegistry) PersistentRegistryManager.findRegistryByType(Block.class); + final ForgeRegistry blockRegistry = (ForgeRegistry)RegistryManager.ACTIVE.getRegistry(Block.class); Block fnd = blockRegistry.getValue(myDirt); assertNotEquals("Didn't find my block", fnd, testDirtBlock); assertEquals("Found a default air block", fnd, Blocks.AIR); // Insert a dummy reference to my dirt - snapshot.entries.get(PersistentRegistryManager.BLOCKS).ids.put(myDirt, 218); - PersistentRegistryManager.injectSnapshot(snapshot, true, true); + snapshot.put(GameData.BLOCKS, new ForgeRegistry.Snapshot()); + snapshot.get(GameData.BLOCKS).ids.put(myDirt, 218); + GameData.injectSnapshot(snapshot, true, true); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); fnd = blockRegistry.getValue(myDirt); assertNotEquals("Did not find my block", fnd, testDirtBlock); assertTrue("Found a dummy air block", fnd.getClass().getName().endsWith("BlockDummyAir")); - final Set dummied = PersistentRegistryManager.takeSnapshot().entries.get(PersistentRegistryManager.BLOCKS).dummied; + final Set dummied = RegistryManager.ACTIVE.takeSnapshot(false).get(GameData.BLOCKS).dummied; assertTrue("Found my block in the dummy list", dummied.contains(myDirt)); - PersistentRegistryManager.revertToFrozen(); + GameData.revertToFrozen(); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); fnd = blockRegistry.getValue(myDirt); assertNotEquals("Did not find my block", fnd, testDirtBlock); assertEquals("Found a default air block", fnd, Blocks.AIR); - GameRegistry.register(testDirtBlock, myDirt); + RegistryManager.ACTIVE.getRegistry(Block.class).register(testDirtBlock.setRegistryName(myDirt)); fnd = blockRegistry.getValue(myDirt); assertEquals("Found my block", fnd, testDirtBlock); // Add dummied entry in - snapshot.entries.get(PersistentRegistryManager.BLOCKS).dummied.add(myDirt); + snapshot.get(GameData.BLOCKS).dummied.add(myDirt); // Loading locally - we should resuscitate our block - PersistentRegistryManager.injectSnapshot(snapshot, true, true); + GameData.injectSnapshot(snapshot, true, true); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); fnd = blockRegistry.getValue(myDirt); assertEquals("Found my block", fnd, testDirtBlock); - PersistentRegistryManager.revertToFrozen(); + GameData.revertToFrozen(); // Sent remotely, we should NOT resuscitate our block - PersistentRegistryManager.injectSnapshot(snapshot, false, false); + GameData.injectSnapshot(snapshot, false, false); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); fnd = blockRegistry.getValue(myDirt); assertNotEquals("Did not find my block", fnd, testDirtBlock); diff --git a/src/test/java/net/minecraftforge/fml/common/registry/FreezingTests.java b/src/test/java/net/minecraftforge/fml/common/registry/FreezingTests.java index 4aaaaae022..750a79e8d4 100644 --- a/src/test/java/net/minecraftforge/fml/common/registry/FreezingTests.java +++ b/src/test/java/net/minecraftforge/fml/common/registry/FreezingTests.java @@ -4,13 +4,24 @@ import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.GameData; +import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.IForgeRegistryEntry; +import net.minecraftforge.registries.RegistryBuilder; +import net.minecraftforge.registries.RegistryManager; + import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; +import com.google.common.collect.Maps; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; +import java.util.Map; + /** * Created by cpw on 04/07/16. */ @@ -24,7 +35,7 @@ public class FreezingTests private static RTest r4; private static RTest r5; private static RTest r6; - private static PersistentRegistryManager.GameDataSnapshot ss; + private static Map ss; static class RTest extends IForgeRegistryEntry.Impl { @@ -42,67 +53,58 @@ public class FreezingTests { Loader.instance(); System.setProperty("fml.queryResult", "confirm"); + System.setProperty("forge.disableVanillaGameData", "true"); registry = new RegistryBuilder().setName(resloc).setType(RTest.class).setIDRange(0, 255).create(); - new RegistryBuilder().setName(PersistentRegistryManager.BLOCKS).setType(Block.class).setIDRange(0, 255).create(); - new RegistryBuilder().setName(PersistentRegistryManager.ITEMS).setType(Item.class).setIDRange(0, 255).create(); + new RegistryBuilder().setName(GameData.BLOCKS).setType(Block.class).setIDRange(0, 255).create(); + new RegistryBuilder().setName(GameData.ITEMS).setType(Item.class).setIDRange(0, 255).create(); r1 = new RTest("test1"); r2 = new RTest("test2"); r3 = new RTest("test3"); r4 = new RTest("test4"); r5 = new RTest("test5"); r6 = new RTest("test6"); - ss = new PersistentRegistryManager.GameDataSnapshot(); - ss.entries.put(PersistentRegistryManager.BLOCKS, new PersistentRegistryManager.GameDataSnapshot.Entry()); - ss.entries.put(PersistentRegistryManager.ITEMS, new PersistentRegistryManager.GameDataSnapshot.Entry()); - PersistentRegistryManager.findRegistryByType(RTest.class).register(r1); - PersistentRegistryManager.findRegistryByType(RTest.class).register(r2); - PersistentRegistryManager.findRegistryByType(RTest.class).register(r3); - PersistentRegistryManager.findRegistryByType(RTest.class).register(r4); - ss.entries.put(resloc, new PersistentRegistryManager.GameDataSnapshot.Entry(PersistentRegistryManager.PersistentRegistry.ACTIVE.getRegistry(RTest.class))); - PersistentRegistryManager.PersistentRegistry.ACTIVE.clean(); - PersistentRegistryManager.PersistentRegistry.FROZEN.clean(); + ss = Maps.newHashMap(); + ss.put(GameData.BLOCKS, new ForgeRegistry.Snapshot()); + ss.put(GameData.ITEMS, new ForgeRegistry.Snapshot()); + RegistryManager.ACTIVE.getRegistry(RTest.class).register(r1); + RegistryManager.ACTIVE.getRegistry(RTest.class).register(r2); + RegistryManager.ACTIVE.getRegistry(RTest.class).register(r3); + RegistryManager.ACTIVE.getRegistry(RTest.class).register(r4); + ss.put(resloc, ((ForgeRegistry)RegistryManager.ACTIVE.getRegistry(RTest.class)).makeSnapshot()); + RegistryManager.ACTIVE.clean(); + RegistryManager.FROZEN.clean(); registry = new RegistryBuilder().setName(resloc).setType(RTest.class).setIDRange(0, 255).create(); - new RegistryBuilder().setName(PersistentRegistryManager.BLOCKS).setType(Block.class).setIDRange(0, 255).create(); - new RegistryBuilder().setName(PersistentRegistryManager.ITEMS).setType(Item.class).setIDRange(0, 255).create(); + new RegistryBuilder().setName(GameData.BLOCKS).setType(Block.class).setIDRange(0, 255).create(); + new RegistryBuilder().setName(GameData.ITEMS).setType(Item.class).setIDRange(0, 255).create(); } @Test public void testFreezeCycle() { - PersistentRegistryManager.findRegistryByType(RTest.class).register(r6); - PersistentRegistryManager.findRegistryByType(RTest.class).register(r5); - PersistentRegistryManager.findRegistryByType(RTest.class).register(r4); - PersistentRegistryManager.findRegistryByType(RTest.class).register(r3); - FMLControlledNamespacedRegistry r = (FMLControlledNamespacedRegistry) PersistentRegistryManager.findRegistry(r3); - int r3id = r.getId(r3); - PersistentRegistryManager.freezeData(); - RTest q1 = PersistentRegistryManager.PersistentRegistry.FROZEN.getRegistry(RTest.class).getValue(new ResourceLocation("test3")); - assertEquals("Frozen object is the same", r3, q1); - q1 = PersistentRegistryManager.PersistentRegistry.ACTIVE.getRegistry(RTest.class).getValue(new ResourceLocation("test3")); - assertEquals("Active object is the same", r3, q1); - PersistentRegistryManager.injectSnapshot(ss, false, false); - assertNotEquals("IDs don't match", r3id, r.getId(r3)); - q1 = PersistentRegistryManager.PersistentRegistry.FROZEN.getRegistry(RTest.class).getValue(new ResourceLocation("test3")); - assertEquals("Frozen object is the same", r3, q1); - q1 = PersistentRegistryManager.PersistentRegistry.ACTIVE.getRegistry(RTest.class).getValue(new ResourceLocation("test3")); - assertEquals("Active object is the same", r3, q1); - PersistentRegistryManager.revertToFrozen(); - assertEquals("IDs match", r3id, r.getId(r3)); - q1 = PersistentRegistryManager.PersistentRegistry.FROZEN.getRegistry(RTest.class).getValue(new ResourceLocation("test3")); - assertEquals("Frozen object is the same", r3, q1); - q1 = PersistentRegistryManager.PersistentRegistry.ACTIVE.getRegistry(RTest.class).getValue(new ResourceLocation("test3")); - assertEquals("Active object is the same", r3, q1); - PersistentRegistryManager.injectSnapshot(ss, true, true); - assertNotEquals("IDs don't match", r3id, r.getId(r3)); - q1 = PersistentRegistryManager.PersistentRegistry.FROZEN.getRegistry(RTest.class).getValue(new ResourceLocation("test3")); - assertEquals("Frozen object is the same", r3, q1); - q1 = PersistentRegistryManager.PersistentRegistry.ACTIVE.getRegistry(RTest.class).getValue(new ResourceLocation("test3")); - assertEquals("Active object is the same", r3, q1); - PersistentRegistryManager.revertToFrozen(); - assertEquals("IDs match", r3id, r.getId(r3)); - q1 = PersistentRegistryManager.PersistentRegistry.FROZEN.getRegistry(RTest.class).getValue(new ResourceLocation("test3")); - assertEquals("Frozen object is the same", r3, q1); - q1 = PersistentRegistryManager.PersistentRegistry.ACTIVE.getRegistry(RTest.class).getValue(new ResourceLocation("test3")); - assertEquals("Active object is the same", r3, q1); + RegistryManager.ACTIVE.getRegistry(RTest.class).register(r6); + RegistryManager.ACTIVE.getRegistry(RTest.class).register(r5); + RegistryManager.ACTIVE.getRegistry(RTest.class).register(r4); + RegistryManager.ACTIVE.getRegistry(RTest.class).register(r3); + ForgeRegistry r = (ForgeRegistry)RegistryManager.ACTIVE.getRegistry(r3.getRegistryType()); + int r3id = r.getID(r3); + GameData.freezeData(); + assertEquals("Frozen object is the same", r3, RegistryManager.FROZEN.getRegistry(RTest.class).getValue(new ResourceLocation("test3"))); + assertEquals("Active object is the same", r3, RegistryManager.ACTIVE.getRegistry(RTest.class).getValue(new ResourceLocation("test3"))); + GameData.injectSnapshot(ss, false, false); + assertNotEquals("IDs don't match", r3id, r.getID(r3)); + assertEquals("Frozen object is the same", r3, RegistryManager.FROZEN.getRegistry(RTest.class).getValue(new ResourceLocation("test3"))); + assertEquals("Active object is the same", r3, RegistryManager.ACTIVE.getRegistry(RTest.class).getValue(new ResourceLocation("test3"))); + GameData.revertToFrozen(); + assertEquals("IDs match", r3id, r.getID(r3)); + assertEquals("Frozen object is the same", r3, RegistryManager.FROZEN.getRegistry(RTest.class).getValue(new ResourceLocation("test3"))); + assertEquals("Active object is the same", r3, RegistryManager.ACTIVE.getRegistry(RTest.class).getValue(new ResourceLocation("test3"))); + GameData.injectSnapshot(ss, true, true); + assertNotEquals("IDs don't match", r3id, r.getID(r3)); + assertEquals("Frozen object is the same", r3, RegistryManager.FROZEN.getRegistry(RTest.class).getValue(new ResourceLocation("test3"))); + assertEquals("Active object is the same", r3, RegistryManager.ACTIVE.getRegistry(RTest.class).getValue(new ResourceLocation("test3"))); + GameData.revertToFrozen(); + assertEquals("IDs match", r3id, r.getID(r3)); + assertEquals("Frozen object is the same", r3, RegistryManager.FROZEN.getRegistry(RTest.class).getValue(new ResourceLocation("test3"))); + assertEquals("Active object is the same", r3, RegistryManager.ACTIVE.getRegistry(RTest.class).getValue(new ResourceLocation("test3"))); } } diff --git a/src/test/java/net/minecraftforge/fml/common/registry/ItemBlockSubstitutionRemoveRestoreTest.java b/src/test/java/net/minecraftforge/fml/common/registry/ItemBlockSubstitutionRemoveRestoreTest.java index 7ab4438593..03a1dffda6 100644 --- a/src/test/java/net/minecraftforge/fml/common/registry/ItemBlockSubstitutionRemoveRestoreTest.java +++ b/src/test/java/net/minecraftforge/fml/common/registry/ItemBlockSubstitutionRemoveRestoreTest.java @@ -1,5 +1,6 @@ package net.minecraftforge.fml.common.registry; +import net.minecraft.block.Block; import net.minecraft.block.BlockDirt; import net.minecraft.init.Blocks; import net.minecraft.init.Bootstrap; @@ -11,6 +12,11 @@ import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.DummyModContainer; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.ModMetadata; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.GameData; +import net.minecraftforge.registries.ObjectHolderRegistry; +import net.minecraftforge.registries.RegistryManager; + import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; @@ -20,6 +26,8 @@ import javax.annotation.Nonnull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; +import java.util.Map; + /** * Substitution test harness - tests that substitutions behave correctly */ @@ -62,28 +70,30 @@ public class ItemBlockSubstitutionRemoveRestoreTest @Test public void testSubstitutionRemovalAndRestore() throws Exception { - GameRegistry.addSubstitutionAlias("minecraft:dirt", GameRegistry.Type.ITEM, myDirtInstance); - PersistentRegistryManager.freezeData(); + RegistryManager.ACTIVE.getRegistry(Item.class).register(myDirtInstance.setRegistryName(myDirt)); + GameData.freezeData(); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); - final FMLControlledNamespacedRegistry itemRegistry = (FMLControlledNamespacedRegistry) PersistentRegistryManager.findRegistryByType(Item.class); + final ForgeRegistry itemRegistry = (ForgeRegistry)RegistryManager.ACTIVE.getRegistry(Item.class); // TEST 1: Does my substitute take effect? The substitute should be found in the registry ItemBlock dirtitem = (ItemBlock) itemRegistry.getValue(myDirt); assertEquals("ItemBlock points at my block", myDirtInstance, dirtitem); // TEST 2: Does the substitute get removed when told by remote operation? The substitute should NOT be found in the registry - final PersistentRegistryManager.GameDataSnapshot snapshot = PersistentRegistryManager.takeSnapshot(); - snapshot.entries.get(PersistentRegistryManager.ITEMS).substitutions.clear(); - PersistentRegistryManager.injectSnapshot(snapshot, false, false); + /* Why should it not be found? Substitutions are no longer special cases + Map snapshot = RegistryManager.ACTIVE.takeSnapshot(false); + snapshot.get(GameData.ITEMS).substitutions.clear(); + GameData.injectSnapshot(snapshot, false, false); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); + */ dirtitem = (ItemBlock) itemRegistry.getValue(myDirt); assertEquals("ItemBlock points at vanilla block", originalDirt, dirtitem); assertNotEquals("ItemBlock points at my block", myDirtInstance, dirtitem); // TEST 3: Does the substitute get restored when reverting to frozen state? The substitute should be found in the registry again - PersistentRegistryManager.revertToFrozen(); + GameData.revertToFrozen(); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); dirtitem = (ItemBlock) itemRegistry.getValue(myDirt); assertEquals("ItemBlock points at my block", myDirtInstance, dirtitem); diff --git a/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionInjectionTest.java b/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionInjectionTest.java index 322aac2d35..f18e422180 100644 --- a/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionInjectionTest.java +++ b/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionInjectionTest.java @@ -11,6 +11,11 @@ import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.DummyModContainer; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.ModMetadata; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.GameData; +import net.minecraftforge.registries.ObjectHolderRegistry; +import net.minecraftforge.registries.RegistryManager; + import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; @@ -20,14 +25,16 @@ import javax.annotation.Nonnull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import java.util.Map; + /** * Substitution test harness - tests that substitutions behave correctly */ @RunWith(ForgeTestRunner.class) public class SubstitutionInjectionTest { - private ResourceLocation myDirt = new ResourceLocation("minecraft:dirt"); - private BlockDirt toSub = new BlockDirt() + private ResourceLocation MC_DIRT = new ResourceLocation("minecraft:dirt"); + private Block toSub = (new BlockDirt() { @Override @Nonnull @@ -35,7 +42,7 @@ public class SubstitutionInjectionTest { return "SUB" + super.toString() + "SUB"; } - }; + }).setRegistryName(MC_DIRT); @BeforeClass public static void setup() @@ -51,23 +58,24 @@ public class SubstitutionInjectionTest @Test public void testSubstitutionInjection() throws Exception { - final FMLControlledNamespacedRegistry blockRegistry = (FMLControlledNamespacedRegistry) PersistentRegistryManager.findRegistryByType(Block.class); - final FMLControlledNamespacedRegistry itemRegistry = (FMLControlledNamespacedRegistry) PersistentRegistryManager.findRegistryByType(Item.class); + final ForgeRegistry blockRegistry = (ForgeRegistry)RegistryManager.ACTIVE.getRegistry(Block.class); + final ForgeRegistry itemRegistry = (ForgeRegistry)RegistryManager.ACTIVE.getRegistry(Item.class); // Capture snapshot prior to registering the substitution - this is a world state "pre-substitute" - final PersistentRegistryManager.GameDataSnapshot snapshot = PersistentRegistryManager.takeSnapshot(); + final Map snapshot = RegistryManager.ACTIVE.takeSnapshot(false); - Block fnd = blockRegistry.getValue(myDirt); + Block fnd = blockRegistry.getValue(MC_DIRT); + Block vanilDirt = Blocks.DIRT; Block currDirt = Blocks.DIRT; // TEST 0: Verify that input state is correct assertEquals("Got vanilla dirt ", currDirt, fnd); // TEST 0a: Validate that the ItemBlock for Dirt points at vanilla dirt - ItemBlock dirtitem = (ItemBlock) itemRegistry.getValue(myDirt); + ItemBlock dirtitem = (ItemBlock) itemRegistry.getValue(MC_DIRT); assertEquals("ItemBlock points at my block", currDirt, dirtitem.block); - GameRegistry.addSubstitutionAlias("minecraft:dirt", GameRegistry.Type.BLOCK, toSub); - PersistentRegistryManager.freezeData(); + blockRegistry.register(toSub); //Register a new object, with the same vanilla name, Should cause the item to be replaced + GameData.freezeData(); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); // This should not throw an exception try @@ -80,61 +88,58 @@ public class SubstitutionInjectionTest } // TEST 1: Does my substitute take effect? The substitute should be found in the registry - fnd = blockRegistry.getValue(myDirt); + fnd = blockRegistry.getValue(MC_DIRT); currDirt = Blocks.DIRT; - assertEquals("Got my dirt substitute - Blocks", toSub, currDirt); - assertEquals("Got my dirt substitute - Blocks and registry", currDirt, fnd); - assertEquals("Got my dirt substitute - registry", toSub, fnd); + assertEquals("Got vanilla dirt - Blocks", toSub, currDirt); + assertEquals("ObjectHolder didn't apply - Blocks and registry", currDirt, fnd); + assertEquals("Got vanilla dirt - registry", toSub, fnd); // TEST 1a: Validate that the ItemBlock for Dirt now points at my dirt - dirtitem = (ItemBlock) itemRegistry.getValue(myDirt); - assertEquals("ItemBlock points at my block", toSub, dirtitem.block); + dirtitem = (ItemBlock) itemRegistry.getValue(MC_DIRT); + assertEquals("ItemBlock points at vanilla block", toSub, dirtitem.getBlock()); - // TEST 2: Does the substitute get injected when told by loading operation? The substitute should be found in the registry - PersistentRegistryManager.injectSnapshot(snapshot, true, true); + // TEST 2: Is the substitute still in the registry? The snapshot was taken before the substitute was added so it should NOT exist + GameData.injectSnapshot(snapshot, true, true); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); - fnd = blockRegistry.getValue(myDirt); + fnd = blockRegistry.getValue(MC_DIRT); currDirt = Blocks.DIRT; - assertEquals("Got my dirt substitute - Blocks", toSub, currDirt); - assertEquals("Got my dirt substitute - Blocks and registry", currDirt, fnd); - assertEquals("Got my dirt substitute - registry", toSub, fnd); - - dirtitem = (ItemBlock) itemRegistry.getValue(myDirt); - assertEquals("ItemBlock points at my block", toSub, dirtitem.block); + assertEquals("Got my dirt substitute - Blocks", vanilDirt, currDirt); + assertEquals("ObjectHolder didn't apply - Blocks and registry", currDirt, fnd); + assertEquals("Got my dirt substitute - registry", vanilDirt, fnd); + dirtitem = (ItemBlock) itemRegistry.getValue(MC_DIRT); + assertEquals("ItemBlock points at my block", toSub, dirtitem.getBlock()); // TEST 3: Does the substitute get restored when reverting to frozen state? The substitute should be found in the registry again - PersistentRegistryManager.revertToFrozen(); + GameData.revertToFrozen(); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); - fnd = blockRegistry.getValue(myDirt); + fnd = blockRegistry.getValue(MC_DIRT); currDirt = Blocks.DIRT; - assertEquals("Got my dirt substitute - Blocks", toSub, currDirt); - assertEquals("Got my dirt substitute - Blocks and registry", currDirt, fnd); - assertEquals("Got my dirt substitute - registry", toSub, fnd); - dirtitem = (ItemBlock) itemRegistry.getValue(myDirt); - assertEquals("ItemBlock points at my block", toSub, dirtitem.block); + assertEquals("Got vanilla dirt - Blocks", toSub, currDirt); + assertEquals("ObjectHolder didn't apply - Blocks and registry", currDirt, fnd); + assertEquals("Got vanilla dirt - registry", toSub, fnd); + dirtitem = (ItemBlock) itemRegistry.getValue(MC_DIRT); + assertEquals("ItemBlock points at vanilla block", toSub, dirtitem.getBlock()); - // TEST 2 repeat: Does the substitute get injected when told by loading operation? The substitute should be found in the registry - PersistentRegistryManager.injectSnapshot(snapshot, true, true); + // TEST 2 repeat: Is the substitute still in the registry? The snapshot was taken before the substitute was added so it should NOT exist + GameData.injectSnapshot(snapshot, true, true); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); - fnd = blockRegistry.getValue(myDirt); + fnd = blockRegistry.getValue(MC_DIRT); currDirt = Blocks.DIRT; - assertEquals("Got my dirt substitute - Blocks", toSub, currDirt); - assertEquals("Got my dirt substitute - Blocks and registry", currDirt, fnd); - assertEquals("Got my dirt substitute - registry", toSub, fnd); - - dirtitem = (ItemBlock) itemRegistry.getValue(myDirt); - assertEquals("ItemBlock points at my block", toSub, dirtitem.block); + assertEquals("Got my dirt substitute - Blocks", vanilDirt, currDirt); + assertEquals("ObjectHolder didn't apply - Blocks and registry", currDirt, fnd); + assertEquals("Got my dirt substitute - registry", vanilDirt, fnd); + dirtitem = (ItemBlock) itemRegistry.getValue(MC_DIRT); + assertEquals("ItemBlock points at my block", toSub, dirtitem.getBlock()); // TEST 3 repeat: Does the substitute get restored when reverting to frozen state? The substitute should be found in the registry again - PersistentRegistryManager.revertToFrozen(); + GameData.revertToFrozen(); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); - fnd = blockRegistry.getValue(myDirt); + fnd = blockRegistry.getValue(MC_DIRT); currDirt = Blocks.DIRT; - assertEquals("Got my dirt substitute - Blocks", toSub, currDirt); - assertEquals("Got my dirt substitute - Blocks and registry", currDirt, fnd); - assertEquals("Got my dirt substitute - registry", toSub, fnd); - dirtitem = (ItemBlock) itemRegistry.getValue(myDirt); - assertEquals("ItemBlock points at my block", toSub, dirtitem.block); - + assertEquals("Got vanilla dirt - Blocks", toSub, currDirt); + assertEquals("ObjectHolder didn't apply - Blocks and registry", currDirt, fnd); + assertEquals("Got vanilla dirt - registry", toSub, fnd); + dirtitem = (ItemBlock) itemRegistry.getValue(MC_DIRT); + assertEquals("ItemBlock points at vanilla block", toSub, dirtitem.getBlock()); } } diff --git a/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionRemoveRestoreTest.java b/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionRemoveRestoreTest.java index efd76218f9..946507a7de 100644 --- a/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionRemoveRestoreTest.java +++ b/src/test/java/net/minecraftforge/fml/common/registry/SubstitutionRemoveRestoreTest.java @@ -10,6 +10,11 @@ import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.DummyModContainer; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.ModMetadata; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.GameData; +import net.minecraftforge.registries.ObjectHolderRegistry; +import net.minecraftforge.registries.RegistryManager; + import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; @@ -17,17 +22,16 @@ import org.junit.runner.RunWith; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; +import java.util.Map; + /** * Substitution test harness - tests that substitutions behave correctly */ @RunWith(ForgeTestRunner.class) public class SubstitutionRemoveRestoreTest { - private ResourceLocation myDirt = new ResourceLocation("minecraft:dirt"); - private BlockDirt toSub = new BlockDirt() - { - - }; + private ResourceLocation MC_DIRT = new ResourceLocation("minecraft:dirt"); + private Block toSub = (new BlockDirt(){}).setRegistryName(MC_DIRT); @BeforeClass public static void setup() @@ -43,48 +47,53 @@ public class SubstitutionRemoveRestoreTest @Test public void testSubstitutionRemovalAndRestore() throws Exception { - GameRegistry.addSubstitutionAlias("minecraft:dirt", GameRegistry.Type.BLOCK, toSub); - PersistentRegistryManager.freezeData(); + /* TODO: Figure this one out, We dont prevent the client from loading subs when the server says not to.. + * Why should we as long as the item is on both sides we should be fine. It's on the modder to make sure they are compatible. + * + final ForgeRegistry blockRegistry = (ForgeRegistry)RegistryManager.ACTIVE.getRegistry(Block.class); + final ForgeRegistry itemRegistry = (ForgeRegistry)RegistryManager.ACTIVE.getRegistry(Item.class); + Block vanilla = blockRegistry.getValue(MC_DIRT); + blockRegistry.register(toSub); + + GameData.freezeData(); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); - final FMLControlledNamespacedRegistry blockRegistry = (FMLControlledNamespacedRegistry) PersistentRegistryManager.findRegistryByType(Block.class); - final FMLControlledNamespacedRegistry itemRegistry = (FMLControlledNamespacedRegistry) PersistentRegistryManager.findRegistryByType(Item.class); // TEST 1: Does my substitute take effect? The substitute should be found in the registry - Block fnd = blockRegistry.getValue(myDirt); + Block fnd = blockRegistry.getValue(MC_DIRT); Block currDirt = Blocks.DIRT; - assertEquals("Got my dirt substitute - Blocks", toSub, currDirt); - assertEquals("Got my dirt substitute - Blocks and registry", currDirt, fnd); - assertEquals("Got my dirt substitute - registry", toSub, fnd); - - ItemBlock dirtitem = (ItemBlock) itemRegistry.getValue(myDirt); - assertEquals("ItemBlock points at my block", toSub, dirtitem.block); + assertEquals("Got Vanilla Dirt - Blocks", toSub, currDirt); + assertEquals("ObjectHolder didn't apply - Blocks and registry", currDirt, fnd); + assertEquals("Got Vanilla Dirt - registry", toSub, fnd); + ItemBlock dirtitem = (ItemBlock)itemRegistry.getValue(MC_DIRT); + assertEquals("ItemBlock points at my block", toSub, dirtitem.getBlock()); // TEST 2: Does the substitute get removed when told by remote operation? The substitute should NOT be found in the registry - final PersistentRegistryManager.GameDataSnapshot snapshot = PersistentRegistryManager.takeSnapshot(); + final Map snapshot = RegistryManager.ACTIVE.takeSnapshot(false); snapshot.entries.get(PersistentRegistryManager.BLOCKS).substitutions.clear(); PersistentRegistryManager.injectSnapshot(snapshot, false, false); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); - fnd = blockRegistry.getValue(myDirt); + fnd = blockRegistry.getValue(MC_DIRT); currDirt = Blocks.DIRT; assertNotEquals("Got my dirt substitute - Blocks", toSub, currDirt); assertEquals("Got my dirt substitute - Blocks and registry", currDirt, fnd); assertNotEquals("Got my dirt substitute - registry", toSub, fnd); - dirtitem = (ItemBlock) itemRegistry.getValue(myDirt); + dirtitem = (ItemBlock) itemRegistry.getValue(MC_DIRT); assertEquals("ItemBlock points at vanilla block", currDirt, dirtitem.block); assertNotEquals("ItemBlock points at my block", toSub, dirtitem.block); // TEST 3: Does the substitute get restored when reverting to frozen state? The substitute should be found in the registry again PersistentRegistryManager.revertToFrozen(); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); - fnd = blockRegistry.getValue(myDirt); + fnd = blockRegistry.getValue(MC_DIRT); currDirt = Blocks.DIRT; assertEquals("Got my dirt substitute - Blocks", toSub, currDirt); assertEquals("Got my dirt substitute - Blocks and registry", currDirt, fnd); assertEquals("Got my dirt substitute - registry", toSub, fnd); - dirtitem = (ItemBlock) itemRegistry.getValue(myDirt); + dirtitem = (ItemBlock) itemRegistry.getValue(MC_DIRT); assertEquals("ItemBlock points at my block", toSub, dirtitem.block); + */ } } diff --git a/src/test/java/net/minecraftforge/fml/common/registry/VanillaRegistryTests.java b/src/test/java/net/minecraftforge/fml/common/registry/VanillaRegistryTests.java index 39641fe09b..8f7589fcae 100644 --- a/src/test/java/net/minecraftforge/fml/common/registry/VanillaRegistryTests.java +++ b/src/test/java/net/minecraftforge/fml/common/registry/VanillaRegistryTests.java @@ -8,6 +8,10 @@ import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.RegistryManager; + import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; @@ -37,7 +41,7 @@ public class VanillaRegistryTests assertEquals("We have all the items via GameData", 411, Item.REGISTRY.getKeys().size()); // Our lookups find the same stuff vanilla sees - final IForgeRegistry blocks = PersistentRegistryManager.findRegistry(Blocks.AIR); + final IForgeRegistry blocks = RegistryManager.ACTIVE.getRegistry(Block.class); assertEquals("We have the right blocks for a block", blocks, Block.REGISTRY); // We can look up stuff through our APIs @@ -49,7 +53,7 @@ public class VanillaRegistryTests assertEquals("We got air when we asked for cheese", Blocks.AIR, blch); // Our lookups find the same stuff vanilla sees - final IForgeRegistry items = PersistentRegistryManager.findRegistry(Items.BED); + final IForgeRegistry items = RegistryManager.ACTIVE.getRegistry(Item.class); assertEquals("We have the right items for an item", items, Item.REGISTRY); // We can look up stuff through our APIs @@ -64,13 +68,12 @@ public class VanillaRegistryTests @Test public void testRegistration() { - Block myBlock = GameRegistry.register(new Block(Material.CAKE) - { - }, new ResourceLocation("minecraft:testy")); + final IForgeRegistry blocks = RegistryManager.ACTIVE.getRegistry(Block.class); + Block myBlock = (new Block(Material.CAKE){}).setRegistryName(new ResourceLocation("minecraft:testy")); + blocks.register(myBlock); assertNotNull("Registered my block", myBlock); // Our lookups find the same stuff vanilla sees - final IForgeRegistry blocks = PersistentRegistryManager.findRegistry(myBlock); assertEquals("We have the right blocks for a block", blocks, Block.REGISTRY); Block found = blocks.getValue(new ResourceLocation("minecraft:testy")); @@ -80,8 +83,8 @@ public class VanillaRegistryTests @Test public void testRegistryStates() { - final FMLControlledNamespacedRegistry blockVanilla = PersistentRegistryManager.PersistentRegistry.VANILLA.getRegistry(Block.class); - final FMLControlledNamespacedRegistry blockActive = PersistentRegistryManager.PersistentRegistry.ACTIVE.getRegistry(Block.class); + final ForgeRegistry blockVanilla = (ForgeRegistry)RegistryManager.VANILLA.getRegistry(Block.class); + final ForgeRegistry blockActive = (ForgeRegistry)RegistryManager.ACTIVE.getRegistry(Block.class); assertNotEquals("Registry states are distinct", blockActive, blockVanilla); @@ -90,8 +93,8 @@ public class VanillaRegistryTests assertEquals("Stone from active and vanilla are the same", stoneActive, stoneVanilla); - int activeId = blockActive.getId(stoneActive); - int vanillaId = blockVanilla.getId(stoneVanilla); + int activeId = blockActive.getID(stoneActive); + int vanillaId = blockVanilla.getID(stoneVanilla); assertEquals("Stone has correct id", 1, activeId); assertEquals("Stone has correct id", 1, vanillaId);