From 66cb48557113b6fda3e43401139c45e0b909b162 Mon Sep 17 00:00:00 2001 From: glowredman <35727266+glowredman@users.noreply.github.com> Date: Thu, 25 Jul 2024 13:52:32 +0200 Subject: [PATCH 01/11] Move FML mixins to extra package --- .../com/mitchej123/hodgepodge/mixins/Mixins.java | 16 ++++++++-------- .../early/{forge => fml}/MixinASMDataTable.java | 2 +- .../{forge => fml}/MixinFMLClientHandler.java | 2 +- .../{forge => fml}/MixinFMLProxyPacket.java | 2 +- .../{forge => fml}/MixinLanguageRegistry.java | 2 +- .../{forge => fml}/MixinNetworkDispatcher.java | 2 +- .../{forge => fml}/MixinOpenGuiHandler.java | 4 ++-- .../mixins/early/ic2/MixinLocalization.java | 11 +++++++---- 8 files changed, 22 insertions(+), 19 deletions(-) rename src/main/java/com/mitchej123/hodgepodge/mixins/early/{forge => fml}/MixinASMDataTable.java (97%) rename src/main/java/com/mitchej123/hodgepodge/mixins/early/{forge => fml}/MixinFMLClientHandler.java (94%) rename src/main/java/com/mitchej123/hodgepodge/mixins/early/{forge => fml}/MixinFMLProxyPacket.java (98%) rename src/main/java/com/mitchej123/hodgepodge/mixins/early/{forge => fml}/MixinLanguageRegistry.java (98%) rename src/main/java/com/mitchej123/hodgepodge/mixins/early/{forge => fml}/MixinNetworkDispatcher.java (97%) rename src/main/java/com/mitchej123/hodgepodge/mixins/early/{forge => fml}/MixinOpenGuiHandler.java (96%) diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java b/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java index 96b5d70f..b1f427a4 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java @@ -200,8 +200,8 @@ public enum Mixins { FIX_BOGUS_INTEGRATED_SERVER_NPE(new Builder("Fix bogus FMLProxyPacket NPEs on integrated server crashes") .setPhase(Phase.EARLY).setSide(Side.BOTH) .addMixinClasses( - "forge.MixinFMLProxyPacket", - "forge.MixinNetworkDispatcher", + "fml.MixinFMLProxyPacket", + "fml.MixinNetworkDispatcher", "minecraft.NetworkManagerAccessor") .setApplyIf(() -> FixesConfig.fixBogusIntegratedServerNPEs).addTargetedMod(TargetedMod.VANILLA)), @@ -277,7 +277,7 @@ public enum Mixins { .setPhase(Phase.EARLY).addTargetedMod(TargetedMod.VANILLA).setApplyIf(() -> TweaksConfig.enhanceNightVision) .addMixinClasses("minecraft.MixinEntityRenderer_EnhanceNightVision")), OPTIMIZE_ASMDATATABLE_INDEX(new Builder("Optimize ASM DataTable Index").setPhase(Phase.EARLY).setSide(Side.BOTH) - .addMixinClasses("forge.MixinASMDataTable").setApplyIf(() -> SpeedupsConfig.optimizeASMDataTable) + .addMixinClasses("fml.MixinASMDataTable").setApplyIf(() -> SpeedupsConfig.optimizeASMDataTable) .addTargetedMod(TargetedMod.VANILLA)), SQUASH_BED_ERROR_MESSAGE(new Builder("Stop \"You can only sleep at night\" message filling the chat") .addMixinClasses("minecraft.MixinNetHandlerPlayClient").addTargetedMod(TargetedMod.VANILLA) @@ -297,7 +297,7 @@ public enum Mixins { .addMixinClasses("forge.MixinGuiIngameForge_CrosshairInvertColors").setSide(Side.CLIENT) .setApplyIf(() -> TweaksConfig.dontInvertCrosshairColor).addTargetedMod(TargetedMod.VANILLA)), FIX_OPENGUIHANDLER_WINDOWID(new Builder("Fix OpenGuiHandler").setPhase(Phase.EARLY).setSide(Side.BOTH) - .addMixinClasses("forge.MixinOpenGuiHandler").setApplyIf(() -> FixesConfig.fixForgeOpenGuiHandlerWindowId) + .addMixinClasses("fml.MixinOpenGuiHandler").setApplyIf(() -> FixesConfig.fixForgeOpenGuiHandlerWindowId) .addTargetedMod(TargetedMod.VANILLA)), FIX_KEYBIND_CONFLICTS(new Builder("Trigger all conflicting keybinds").setPhase(Phase.EARLY).setSide(Side.CLIENT) .addMixinClasses("minecraft.MixinKeyBinding", "minecraft.MixinMinecraft_UpdateKeys") @@ -443,10 +443,10 @@ public enum Mixins { "ic2.MixinIC2ArmorSolarHelmet", "ic2.MixinIC2ArmorStaticBoots") .setApplyIf(() -> FixesConfig.fixIc2ArmorLag).addTargetedMod(TargetedMod.IC2)), - IC2_RESOURCE_PACK_TRANSLATION_FIX(new Builder("IC2 Resource Pack Translation Fix").setPhase(Phase.EARLY) - .setSide(Side.CLIENT) - .addMixinClasses("forge.MixinLanguageRegistry", "forge.MixinFMLClientHandler", "ic2.MixinLocalization") - .setApplyIf(() -> FixesConfig.fixIc2ResourcePackTranslation).addTargetedMod(TargetedMod.IC2)), + IC2_RESOURCE_PACK_TRANSLATION_FIX( + new Builder("IC2 Resource Pack Translation Fix").setPhase(Phase.EARLY).setSide(Side.CLIENT) + .addMixinClasses("fml.MixinLanguageRegistry", "fml.MixinFMLClientHandler", "ic2.MixinLocalization") + .setApplyIf(() -> FixesConfig.fixIc2ResourcePackTranslation).addTargetedMod(TargetedMod.IC2)), // Disable update checkers BIBLIOCRAFT_UPDATE_CHECK(new Builder("Yeet Bibliocraft Update Check").setPhase(Phase.LATE).setSide(Side.CLIENT) diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinASMDataTable.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinASMDataTable.java similarity index 97% rename from src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinASMDataTable.java rename to src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinASMDataTable.java index 3aaaa7ba..86445a84 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinASMDataTable.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinASMDataTable.java @@ -1,4 +1,4 @@ -package com.mitchej123.hodgepodge.mixins.early.forge; +package com.mitchej123.hodgepodge.mixins.early.fml; import java.io.File; import java.util.HashMap; diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinFMLClientHandler.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinFMLClientHandler.java similarity index 94% rename from src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinFMLClientHandler.java rename to src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinFMLClientHandler.java index 441d9b87..ec8aff01 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinFMLClientHandler.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinFMLClientHandler.java @@ -1,4 +1,4 @@ -package com.mitchej123.hodgepodge.mixins.early.forge; +package com.mitchej123.hodgepodge.mixins.early.fml; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinFMLProxyPacket.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinFMLProxyPacket.java similarity index 98% rename from src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinFMLProxyPacket.java rename to src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinFMLProxyPacket.java index 92429c35..2f5f2eea 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinFMLProxyPacket.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinFMLProxyPacket.java @@ -1,4 +1,4 @@ -package com.mitchej123.hodgepodge.mixins.early.forge; +package com.mitchej123.hodgepodge.mixins.early.fml; import net.minecraft.network.Packet; diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinLanguageRegistry.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinLanguageRegistry.java similarity index 98% rename from src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinLanguageRegistry.java rename to src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinLanguageRegistry.java index cc4a14b6..315f56b4 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinLanguageRegistry.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinLanguageRegistry.java @@ -1,4 +1,4 @@ -package com.mitchej123.hodgepodge.mixins.early.forge; +package com.mitchej123.hodgepodge.mixins.early.fml; import java.io.File; import java.io.IOException; diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinNetworkDispatcher.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinNetworkDispatcher.java similarity index 97% rename from src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinNetworkDispatcher.java rename to src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinNetworkDispatcher.java index e13df981..e1c163dc 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinNetworkDispatcher.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinNetworkDispatcher.java @@ -1,4 +1,4 @@ -package com.mitchej123.hodgepodge.mixins.early.forge; +package com.mitchej123.hodgepodge.mixins.early.fml; import java.lang.ref.WeakReference; diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinOpenGuiHandler.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinOpenGuiHandler.java similarity index 96% rename from src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinOpenGuiHandler.java rename to src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinOpenGuiHandler.java index 568be96f..26ecfdeb 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinOpenGuiHandler.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinOpenGuiHandler.java @@ -1,4 +1,4 @@ -package com.mitchej123.hodgepodge.mixins.early.forge; +package com.mitchej123.hodgepodge.mixins.early.fml; import static org.objectweb.asm.Opcodes.PUTFIELD; @@ -21,7 +21,7 @@ import cpw.mods.fml.common.network.internal.OpenGuiHandler; import io.netty.channel.SimpleChannelInboundHandler; -@Mixin(value = { OpenGuiHandler.class }) +@Mixin(value = OpenGuiHandler.class) public abstract class MixinOpenGuiHandler extends SimpleChannelInboundHandler { /* diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/ic2/MixinLocalization.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/ic2/MixinLocalization.java index 8ac496a6..77ae812f 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/ic2/MixinLocalization.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/ic2/MixinLocalization.java @@ -8,6 +8,9 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; +import com.mitchej123.hodgepodge.mixins.early.fml.MixinLanguageRegistry; +import com.mitchej123.hodgepodge.mixins.hooks.IC2ResourcePack; + import cpw.mods.fml.common.registry.LanguageRegistry; import ic2.core.init.Localization; @@ -17,8 +20,8 @@ public class MixinLocalization { /** * Translations are delegated to vanilla lang system * - * @see com.mitchej123.hodgepodge.mixins.early.forge.MixinLanguageRegistry - * @see com.mitchej123.hodgepodge.mixins.hooks.IC2ResourcePack + * @see MixinLanguageRegistry + * @see IC2ResourcePack */ @Redirect( method = "postInit", @@ -32,8 +35,8 @@ public class MixinLocalization { /** * @author miozune * @reason Translations are delegated to vanilla lang system - * @see com.mitchej123.hodgepodge.mixins.early.forge.MixinLanguageRegistry - * @see com.mitchej123.hodgepodge.mixins.hooks.IC2ResourcePack + * @see MixinLanguageRegistry + * @see IC2ResourcePack */ @Overwrite(remap = false) protected static Map getStringTranslateMap() { From f4e2809aca66e24018d287a009072e5aa1336e4f Mon Sep 17 00:00:00 2001 From: glowredman <35727266+glowredman@users.noreply.github.com> Date: Thu, 25 Jul 2024 13:53:52 +0200 Subject: [PATCH 02/11] Add stats for modded items/blocks --- .../com/mitchej123/hodgepodge/Hodgepodge.java | 10 +++ .../hodgepodge/config/TweaksConfig.java | 5 ++ .../mitchej123/hodgepodge/mixins/Mixins.java | 4 ++ .../mixins/early/fml/MixinGameRegistry.java | 69 +++++++++++++++++++ .../hodgepodge/util/StatHandler.java | 65 +++++++++++++++++ 5 files changed, 153 insertions(+) create mode 100644 src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinGameRegistry.java create mode 100644 src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java diff --git a/src/main/java/com/mitchej123/hodgepodge/Hodgepodge.java b/src/main/java/com/mitchej123/hodgepodge/Hodgepodge.java index 3fd5dbab..c083eb07 100644 --- a/src/main/java/com/mitchej123/hodgepodge/Hodgepodge.java +++ b/src/main/java/com/mitchej123/hodgepodge/Hodgepodge.java @@ -4,14 +4,17 @@ import com.mitchej123.hodgepodge.client.HodgepodgeClient; import com.mitchej123.hodgepodge.commands.DebugCommand; +import com.mitchej123.hodgepodge.config.TweaksConfig; import com.mitchej123.hodgepodge.net.NetworkHandler; import com.mitchej123.hodgepodge.util.AnchorAlarm; +import com.mitchej123.hodgepodge.util.StatHandler; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.ICrashCallable; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.event.FMLInitializationEvent; +import cpw.mods.fml.common.event.FMLModIdMappingEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.event.FMLServerStartingEvent; @@ -90,6 +93,13 @@ public void onServerStarting(FMLServerStartingEvent aEvent) { EVENT_HANDLER.setAidTriggerDisabled(false); } + @EventHandler + public void onModIdMapping(FMLModIdMappingEvent event) { + if (TweaksConfig.addModItemStats) { + StatHandler.remap(event.remappedIds); + } + } + /** * Block any clients older than 2.5.36 from joining servers to ensure the fastBlockPlacingDisableServerSide setting * is respected diff --git a/src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java b/src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java index 11ffc738..572a5bf6 100644 --- a/src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java +++ b/src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java @@ -158,6 +158,11 @@ public class TweaksConfig { @Config.RequiresMcRestart public static boolean unbindKeybindsByDefault; + @Config.Comment("Adds non-vanilla blocks/items to the statistics") + @Config.DefaultBoolean(true) + @Config.RequiresMcRestart + public static boolean addModItemStats; + // Automagy @Config.Comment("Implement container for thirsty tank") diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java b/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java index b1f427a4..78e40332 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java @@ -398,6 +398,10 @@ public enum Mixins { .addMixinClasses("minecraft.MixinMinecraft_FixDuplicateSounds") .setApplyIf(() -> FixesConfig.fixDuplicateSounds)), + ADD_MOD_ITEM_STATS(new Builder("Add stats for modded items").addMixinClasses("fml.MixinGameRegistry") + .addTargetedMod(TargetedMod.VANILLA).setApplyIf(() -> TweaksConfig.addModItemStats).setPhase(Phase.EARLY) + .setSide(Side.BOTH)), + // Ic2 adjustments IC2_UNPROTECTED_GET_BLOCK_FIX(new Builder("IC2 Kinetic Fix").setPhase(Phase.EARLY).setSide(Side.BOTH) .addMixinClasses("ic2.MixinIc2WaterKinetic").setApplyIf(() -> FixesConfig.fixIc2UnprotectedGetBlock) diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinGameRegistry.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinGameRegistry.java new file mode 100644 index 00000000..975f6f3d --- /dev/null +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinGameRegistry.java @@ -0,0 +1,69 @@ +package com.mitchej123.hodgepodge.mixins.early.fml; + +import net.minecraft.block.Block; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.stats.StatCrafting; +import net.minecraft.stats.StatList; +import net.minecraft.util.ChatComponentTranslation; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.sugar.Local; + +import cpw.mods.fml.common.registry.GameRegistry; + +@Mixin(GameRegistry.class) +public class MixinGameRegistry { + + @ModifyExpressionValue( + at = @At( + target = "Lcpw/mods/fml/common/registry/GameData;registerItem(Lnet/minecraft/item/Item;Ljava/lang/String;)I", + value = "INVOKE"), + method = "registerBlock(Lnet/minecraft/block/Block;Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Object;)Lnet/minecraft/block/Block;", + remap = false) + private static int hodgepodge$registerBlockStats(int itemId, Block block, Class itemclass, + String name, Object[] itemCtorArgs, @Local ItemBlock i) { + if (block.getEnableStats()) { + StatCrafting statMine = hodgepodge$createAndRegisterStat("stat.mineBlock", i); + StatList.mineBlockStatArray[itemId] = statMine; + StatList.objectMineStats.add(statMine); + } + StatList.objectUseStats[itemId] = hodgepodge$createAndRegisterStat("stat.useItem", i); + StatList.objectCraftStats[itemId] = hodgepodge$createAndRegisterStat("stat.craftItem", i); + return itemId; + } + + @ModifyExpressionValue( + at = @At( + target = "Lcpw/mods/fml/common/registry/GameData;registerItem(Lnet/minecraft/item/Item;Ljava/lang/String;)I", + value = "INVOKE"), + method = "registerItem(Lnet/minecraft/item/Item;Ljava/lang/String;Ljava/lang/String;)Lnet/minecraft/item/Item;", + remap = false) + private static int hodgepodge$registerItemStats(int itemId, Item item, String name, String modId) { + if (item.isDamageable()) { + StatList.objectBreakStats[itemId] = hodgepodge$createAndRegisterStat("stat.breakItem", item); + } + StatCrafting statCraft = hodgepodge$createAndRegisterStat("stat.useItem", item); + StatList.objectUseStats[itemId] = statCraft; + if (!(item instanceof ItemBlock)) { + StatList.itemStats.add(statCraft); + } + StatList.objectCraftStats[itemId] = hodgepodge$createAndRegisterStat("stat.craftItem", item); + return itemId; + } + + @Unique + private static StatCrafting hodgepodge$createAndRegisterStat(String key, Item item) { + StatCrafting stat = new StatCrafting( + key + '.' + item.delegate.name(), + new ChatComponentTranslation(key, new ItemStack(item).func_151000_E()), + item); + stat.registerStat(); + return stat; + } +} diff --git a/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java b/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java new file mode 100644 index 00000000..c205a088 --- /dev/null +++ b/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java @@ -0,0 +1,65 @@ +package com.mitchej123.hodgepodge.util; + +import net.minecraft.stats.StatBase; +import net.minecraft.stats.StatList; + +import com.google.common.collect.ImmutableList; + +import cpw.mods.fml.common.event.FMLModIdMappingEvent.ModRemapping; +import cpw.mods.fml.common.event.FMLModIdMappingEvent.RemapTarget; + +public class StatHandler { + + // stat arrays mapped to the frozen ids + private static final StatBase[] STATS_MINE = new StatBase[StatList.mineBlockStatArray.length]; + private static final StatBase[] STATS_CRAFT = new StatBase[StatList.objectCraftStats.length]; + private static final StatBase[] STATS_USE = new StatBase[StatList.objectUseStats.length]; + private static final StatBase[] STATS_BREAK = new StatBase[StatList.objectBreakStats.length]; + private static boolean initFrozenStats = true; + + public static void remap(ImmutableList remappedIds) { + if (initFrozenStats) { + // init stat arrays mapped to the frozen ids + arraycopy(StatList.mineBlockStatArray, STATS_MINE); + arraycopy(StatList.objectCraftStats, STATS_CRAFT); + arraycopy(StatList.objectUseStats, STATS_USE); + arraycopy(StatList.objectBreakStats, STATS_BREAK); + initFrozenStats = true; + } + if (remappedIds.isEmpty()) { + // we are reverting to frozen ids + arraycopy(STATS_MINE, StatList.mineBlockStatArray); + arraycopy(STATS_CRAFT, StatList.objectCraftStats); + arraycopy(STATS_USE, StatList.objectUseStats); + arraycopy(STATS_BREAK, StatList.objectBreakStats); + return; + } + + final StatBase[] statsMine = StatList.mineBlockStatArray.clone(); + final StatBase[] statsCraft = StatList.objectCraftStats.clone(); + final StatBase[] statsUse = StatList.objectUseStats.clone(); + final StatBase[] statsBreak = StatList.objectBreakStats.clone(); + + // remap the stats with changed id + for (ModRemapping remapping : remappedIds) { + if (remapping.remapTarget == RemapTarget.BLOCK) { + continue; + } + final int newId = remapping.newId; + final int oldId = remapping.oldId; + statsMine[newId] = StatList.mineBlockStatArray[oldId]; + statsCraft[newId] = StatList.objectCraftStats[oldId]; + statsUse[newId] = StatList.objectUseStats[oldId]; + statsBreak[newId] = StatList.objectBreakStats[oldId]; + } + arraycopy(statsMine, StatList.mineBlockStatArray); + arraycopy(statsCraft, StatList.objectCraftStats); + arraycopy(statsUse, StatList.objectUseStats); + arraycopy(statsBreak, StatList.objectBreakStats); + } + + private static void arraycopy(T[] src, T[] dest) { + System.arraycopy(src, 0, dest, 0, src.length); + } + +} From e7705a9c7e58500ee05b0a3af2b311102746c853 Mon Sep 17 00:00:00 2001 From: glowredman <35727266+glowredman@users.noreply.github.com> Date: Thu, 25 Jul 2024 21:57:14 +0200 Subject: [PATCH 03/11] Address some warnings --- .../early/forge/MixinGuiIngameForge_CrosshairInvertColors.java | 2 +- .../minecraft/MixinEntityLivingBase_HidePotionParticles.java | 2 +- .../hodgepodge/mixins/early/minecraft/MixinEntityPlayerMP.java | 2 -- .../mixins/early/minecraft/MixinGuiContainerCreative.java | 2 +- .../early/minecraft/MixinGuiNewChat_TransparentChat.java | 2 +- .../early/minecraft/MixinServerConfigurationManager.java | 1 - .../mitchej123/hodgepodge/mixins/hooks/IC2ResourcePack.java | 3 +-- .../hodgepodge/mixins/late/projecte/MixinObjHandler.java | 1 - 8 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinGuiIngameForge_CrosshairInvertColors.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinGuiIngameForge_CrosshairInvertColors.java index f4c7070b..ccfe0197 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinGuiIngameForge_CrosshairInvertColors.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/forge/MixinGuiIngameForge_CrosshairInvertColors.java @@ -5,7 +5,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import com.llamalad7.mixinextras.injector.WrapWithCondition; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; @Mixin(GuiIngameForge.class) public class MixinGuiIngameForge_CrosshairInvertColors { diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinEntityLivingBase_HidePotionParticles.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinEntityLivingBase_HidePotionParticles.java index 8e991899..9aab2216 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinEntityLivingBase_HidePotionParticles.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinEntityLivingBase_HidePotionParticles.java @@ -7,7 +7,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import com.llamalad7.mixinextras.injector.WrapWithCondition; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import com.mitchej123.hodgepodge.config.TweaksConfig; /** diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinEntityPlayerMP.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinEntityPlayerMP.java index 19366271..0684a411 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinEntityPlayerMP.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinEntityPlayerMP.java @@ -36,7 +36,6 @@ public abstract class MixinEntityPlayerMP extends EntityLivingBase { ServersideAttributeMap oldAttributeMap = (ServersideAttributeMap) oldPlayer.getAttributeMap(); // Grab the watched attributes - @SuppressWarnings("unchecked") Collection watchedAttribs = oldAttributeMap.getWatchedAttributes(); if (!watchedAttribs.isEmpty()) { @@ -64,7 +63,6 @@ public abstract class MixinEntityPlayerMP extends EntityLivingBase { } // Helper method based on 1.12 - @SuppressWarnings("unchecked") @Unique private Collection getModifiers(ModifiableAttributeInstance attr) { Set toReturn = Sets.newHashSet(); diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinGuiContainerCreative.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinGuiContainerCreative.java index f8a6dd98..31955b17 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinGuiContainerCreative.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinGuiContainerCreative.java @@ -15,7 +15,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import com.llamalad7.mixinextras.injector.WrapWithCondition; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; @Mixin(GuiContainerCreative.class) public abstract class MixinGuiContainerCreative extends GuiContainer { diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinGuiNewChat_TransparentChat.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinGuiNewChat_TransparentChat.java index de5d2138..1f32d198 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinGuiNewChat_TransparentChat.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinGuiNewChat_TransparentChat.java @@ -6,7 +6,7 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; -import com.llamalad7.mixinextras.injector.WrapWithCondition; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; @Mixin(GuiNewChat.class) public abstract class MixinGuiNewChat_TransparentChat { diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinServerConfigurationManager.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinServerConfigurationManager.java index 26b99610..111a298a 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinServerConfigurationManager.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinServerConfigurationManager.java @@ -29,7 +29,6 @@ public class MixinServerConfigurationManager { private void hodgepodge$sendEntityProperties(EntityPlayerMP player, int dimension, Teleporter teleporter, CallbackInfo ci) { ServersideAttributeMap attributeMap = (ServersideAttributeMap) player.getAttributeMap(); - @SuppressWarnings("unchecked") Collection watchedAttribs = attributeMap.getWatchedAttributes(); if (!watchedAttribs.isEmpty()) { player.playerNetServerHandler diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/hooks/IC2ResourcePack.java b/src/main/java/com/mitchej123/hodgepodge/mixins/hooks/IC2ResourcePack.java index 2bfd3574..b796c974 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/hooks/IC2ResourcePack.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/hooks/IC2ResourcePack.java @@ -47,9 +47,8 @@ public boolean resourceExists(ResourceLocation rl) { return zipFile.getEntry(locationToName(rl)) != null || fallbackResourcePack.resourceExists(rl); } - @SuppressWarnings("rawtypes") @Override - public Set getResourceDomains() { + public Set getResourceDomains() { return ImmutableSet.of("ic2", "minecraft"); } diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/late/projecte/MixinObjHandler.java b/src/main/java/com/mitchej123/hodgepodge/mixins/late/projecte/MixinObjHandler.java index e05245c9..636be881 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/late/projecte/MixinObjHandler.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/late/projecte/MixinObjHandler.java @@ -15,7 +15,6 @@ @Mixin(ObjHandler.class) public class MixinObjHandler { - @SuppressWarnings("unchecked") @Redirect( method = "registerPhiloStoneSmelting", at = @At( From 92b116aa09224ad2a517297da071a7b158883027 Mon Sep 17 00:00:00 2001 From: glowredman <35727266+glowredman@users.noreply.github.com> Date: Fri, 26 Jul 2024 16:08:53 +0200 Subject: [PATCH 04/11] Add modded entity stats --- .../com/mitchej123/hodgepodge/Hodgepodge.java | 8 ++ .../hodgepodge/config/TweaksConfig.java | 9 ++ .../mitchej123/hodgepodge/mixins/Mixins.java | 8 ++ .../mixins/early/minecraft/MixinStatList.java | 29 +++++++ .../early/minecraft/MixinStatsMobsList.java | 87 +++++++++++++++++++ .../hodgepodge/util/StatHandler.java | 71 +++++++++++++++ src/main/resources/META-INF/hodgepodge_at.cfg | 1 + 7 files changed, 213 insertions(+) create mode 100644 src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatList.java create mode 100644 src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatsMobsList.java diff --git a/src/main/java/com/mitchej123/hodgepodge/Hodgepodge.java b/src/main/java/com/mitchej123/hodgepodge/Hodgepodge.java index c083eb07..4afd6ed8 100644 --- a/src/main/java/com/mitchej123/hodgepodge/Hodgepodge.java +++ b/src/main/java/com/mitchej123/hodgepodge/Hodgepodge.java @@ -17,6 +17,7 @@ import cpw.mods.fml.common.event.FMLModIdMappingEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; +import cpw.mods.fml.common.event.FMLServerStartedEvent; import cpw.mods.fml.common.event.FMLServerStartingEvent; import cpw.mods.fml.common.network.NetworkCheckHandler; import cpw.mods.fml.common.versioning.ArtifactVersion; @@ -93,6 +94,13 @@ public void onServerStarting(FMLServerStartingEvent aEvent) { EVENT_HANDLER.setAidTriggerDisabled(false); } + @EventHandler + public void onServerStarted(FMLServerStartedEvent event) { + if (TweaksConfig.addModEntityStats) { + StatHandler.addEntityStats(); + } + } + @EventHandler public void onModIdMapping(FMLModIdMappingEvent event) { if (TweaksConfig.addModItemStats) { diff --git a/src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java b/src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java index 572a5bf6..9fcf3270 100644 --- a/src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java +++ b/src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java @@ -163,6 +163,15 @@ public class TweaksConfig { @Config.RequiresMcRestart public static boolean addModItemStats; + @Config.Comment("Adds non-vanilla entities to the statistics") + @Config.DefaultBoolean(true) + @Config.RequiresMcRestart + public static boolean addModEntityStats; + + @Config.Comment("Sort Mob stats lexicographically (Requires addModEntityStats)") + @Config.DefaultBoolean(true) + public static boolean sortEntityStats; + // Automagy @Config.Comment("Implement container for thirsty tank") diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java b/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java index 78e40332..9cbc5625 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java @@ -402,6 +402,14 @@ public enum Mixins { .addTargetedMod(TargetedMod.VANILLA).setApplyIf(() -> TweaksConfig.addModItemStats).setPhase(Phase.EARLY) .setSide(Side.BOTH)), + ADD_MOD_ENTITY_STATS(new Builder("Add stats for modded entities").addMixinClasses("minecraft.MixinStatList") + .addTargetedMod(TargetedMod.VANILLA).setApplyIf(() -> TweaksConfig.addModEntityStats).setPhase(Phase.EARLY) + .setSide(Side.BOTH)), + + ADD_MOD_ENTITY_STATS_CLIENT(new Builder("Add stats for modded entities (client side)") + .addMixinClasses("minecraft.MixinStatsMobsList").addTargetedMod(TargetedMod.VANILLA) + .setApplyIf(() -> TweaksConfig.addModEntityStats).setPhase(Phase.EARLY).setSide(Side.CLIENT)), + // Ic2 adjustments IC2_UNPROTECTED_GET_BLOCK_FIX(new Builder("IC2 Kinetic Fix").setPhase(Phase.EARLY).setSide(Side.BOTH) .addMixinClasses("ic2.MixinIc2WaterKinetic").setApplyIf(() -> FixesConfig.fixIc2UnprotectedGetBlock) diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatList.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatList.java new file mode 100644 index 00000000..0fede5c2 --- /dev/null +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatList.java @@ -0,0 +1,29 @@ +package com.mitchej123.hodgepodge.mixins.early.minecraft; + +import net.minecraft.entity.EntityList.EntityEggInfo; +import net.minecraft.stats.StatList; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.mitchej123.hodgepodge.util.StatHandler; +import com.mitchej123.hodgepodge.util.StatHandler.EntityInfo; + +@Mixin(StatList.class) +public class MixinStatList { + + @ModifyExpressionValue( + at = @At( + target = "Lnet/minecraft/entity/EntityList;getStringFromID(I)Ljava/lang/String;", + value = "INVOKE"), + method = { "func_151182_a", "func_151176_b" }) // these methods create and register the stats for + // killing/being killed by the specified entity + private static String hodgepodge$getEntityName(String original, EntityEggInfo info) { + if (info instanceof EntityInfo) { + return StatHandler.currentEntityName; + } + return original; + } + +} diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatsMobsList.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatsMobsList.java new file mode 100644 index 00000000..000ce8a0 --- /dev/null +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatsMobsList.java @@ -0,0 +1,87 @@ +package com.mitchej123.hodgepodge.mixins.early.minecraft; + +import java.util.Comparator; +import java.util.List; + +import net.minecraft.entity.EntityList; +import net.minecraft.entity.EntityList.EntityEggInfo; +import net.minecraft.stats.StatFileWriter; +import net.minecraft.util.StatCollector; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.sugar.Local; +import com.mitchej123.hodgepodge.config.TweaksConfig; +import com.mitchej123.hodgepodge.util.StatHandler; +import com.mitchej123.hodgepodge.util.StatHandler.EntityInfo; + +import cpw.mods.fml.client.FMLClientHandler; + +@Mixin(targets = "net.minecraft.client.gui.achievement.GuiStats$StatsMobsList") +public class MixinStatsMobsList { + + // This List contains all instances of EntityEggInfo for which the stats should be displayed. The order in which + // they are displayed is determined by the List's order + @Shadow + private @Final List field_148222_l; + + @Inject(at = @At("TAIL"), method = "") + private void hodgepodge$addModdedEntities(CallbackInfo ci) { + StatFileWriter stats = FMLClientHandler.instance().getClientPlayerEntity().getStatFileWriter(); + for (EntityEggInfo info : StatHandler.ADDITIONAL_ENTITY_EGGS.values()) { + // Is either the killed Entity or killed by Entity stat non-zero? + // NOTE: StatFileWriter.writeStat() actually reads the stat (writing is done with + // StatFileWriter.func_150873_a()) + if (stats.writeStat(info.field_151512_d) > 0 || stats.writeStat(info.field_151513_e) > 0) { + this.field_148222_l.add(info); + } + } + if (TweaksConfig.sortEntityStats) { + this.field_148222_l.sort(new Comparator<>() { + + @Override + public int compare(EntityEggInfo o1, EntityEggInfo o2) { + if (o1 == null) { + if (o2 == null) { + return 0; + } + return -1; + } + if (o2 == null) { + return 1; + } + String name1 = "entity." + getName(o1) + ".name"; + String name2 = "entity." + getName(o2) + ".name"; + return StatCollector.translateToLocal(name1) + .compareToIgnoreCase(StatCollector.translateToLocal(name2)); + } + + private static String getName(EntityEggInfo eei) { + if (eei instanceof EntityInfo info) { + return info.name; + } else { + return EntityList.getStringFromID(eei.spawnedID); + } + } + }); + } + } + + @ModifyExpressionValue( + at = @At( + target = "Lnet/minecraft/entity/EntityList;getStringFromID(I)Ljava/lang/String;", + value = "INVOKE"), + method = "drawSlot") + private static String hodgepodge$getEntityName(String original, @Local EntityEggInfo entityegginfo) { + if (entityegginfo instanceof EntityInfo info) { + return info.name; + } + return original; + } +} diff --git a/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java b/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java index c205a088..0c48908a 100644 --- a/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java +++ b/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java @@ -1,15 +1,32 @@ package com.mitchej123.hodgepodge.util; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.EntityList.EntityEggInfo; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.stats.StatBase; import net.minecraft.stats.StatList; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.living.LivingDeathEvent; import com.google.common.collect.ImmutableList; import cpw.mods.fml.common.event.FMLModIdMappingEvent.ModRemapping; import cpw.mods.fml.common.event.FMLModIdMappingEvent.RemapTarget; +import cpw.mods.fml.common.eventhandler.EventPriority; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; public class StatHandler { + public static final Map, EntityEggInfo> ADDITIONAL_ENTITY_EGGS = new HashMap<>(); + public static String currentEntityName; + // stat arrays mapped to the frozen ids private static final StatBase[] STATS_MINE = new StatBase[StatList.mineBlockStatArray.length]; private static final StatBase[] STATS_CRAFT = new StatBase[StatList.objectCraftStats.length]; @@ -58,8 +75,62 @@ public static void remap(ImmutableList remappedIds) { arraycopy(statsBreak, StatList.objectBreakStats); } + public static void addEntityStats() { + for (Entry, String> e : EntityList.classToStringMapping.entrySet()) { + Class clazz = e.getKey(); + if (!EntityLivingBase.class.isAssignableFrom(clazz)) { + // only entities extending EntityLivingBase can be killed/can kill the player + continue; + } + @SuppressWarnings("unchecked") + Integer id = (Integer) EntityList.classToIDMapping.getOrDefault(clazz, 256); + if (EntityList.entityEggs.containsKey(id)) { + continue; + } + currentEntityName = e.getValue(); + ADDITIONAL_ENTITY_EGGS.put(clazz, new EntityInfo(id, currentEntityName)); + } + currentEntityName = null; + MinecraftForge.EVENT_BUS.register(new StatHandler()); + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onLivingDeathEvent(LivingDeathEvent event) { + if (event.entityLiving instanceof EntityPlayerMP player) { + // the player was killed + EntityLivingBase attackingEntity = player.func_94060_bK(); + if (attackingEntity == null) { + return; + } + EntityEggInfo info = ADDITIONAL_ENTITY_EGGS.get(attackingEntity.getClass()); + if (info == null) { + return; + } + player.addStat(info.field_151513_e, 1); // "killed by entity" stat + return; + } + if (event.source.getEntity() instanceof EntityPlayer player) { + // the player made a kill + EntityEggInfo info = ADDITIONAL_ENTITY_EGGS.get(event.entityLiving.getClass()); + if (info == null) { + return; + } + player.addStat(info.field_151512_d, 1); // "kill entity" stat + + } + } + private static void arraycopy(T[] src, T[] dest) { System.arraycopy(src, 0, dest, 0, src.length); } + public static class EntityInfo extends EntityEggInfo { + + public final String name; + + public EntityInfo(int id, String name) { + super(id, 0, 0); + this.name = name; + } + } } diff --git a/src/main/resources/META-INF/hodgepodge_at.cfg b/src/main/resources/META-INF/hodgepodge_at.cfg index 26d23123..0da84b3c 100644 --- a/src/main/resources/META-INF/hodgepodge_at.cfg +++ b/src/main/resources/META-INF/hodgepodge_at.cfg @@ -19,3 +19,4 @@ public net.minecraft.client.resources.AbstractResourcePack field_110597_b # reso public net.minecraft.client.resources.FallbackResourceManager field_110540_a # resourcePacks public net.minecraft.client.resources.FileResourcePack field_110600_d # resourcePackZipFile public net.minecraft.client.resources.SimpleReloadableResourceManager field_110548_a # domainResourceManagers +public net.minecraft.entity.EntityList field_75624_e # classToIDMapping From 352b5fa1850cac5961ce46035821b98b92a8ac7e Mon Sep 17 00:00:00 2001 From: glowredman <35727266+glowredman@users.noreply.github.com> Date: Sat, 27 Jul 2024 18:01:56 +0200 Subject: [PATCH 05/11] Hopefully prevent NPEs --- .../hodgepodge/mixins/early/fml/MixinGameRegistry.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinGameRegistry.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinGameRegistry.java index 975f6f3d..a1908053 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinGameRegistry.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinGameRegistry.java @@ -3,7 +3,6 @@ import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; import net.minecraft.stats.StatCrafting; import net.minecraft.stats.StatList; import net.minecraft.util.ChatComponentTranslation; @@ -61,7 +60,7 @@ public class MixinGameRegistry { private static StatCrafting hodgepodge$createAndRegisterStat(String key, Item item) { StatCrafting stat = new StatCrafting( key + '.' + item.delegate.name(), - new ChatComponentTranslation(key, new ItemStack(item).func_151000_E()), + new ChatComponentTranslation(key, new ChatComponentTranslation(item.getUnlocalizedName())), item); stat.registerStat(); return stat; From addddec1de092c8de95135a1f6507b0c0f4b341c Mon Sep 17 00:00:00 2001 From: glowredman <35727266+glowredman@users.noreply.github.com> Date: Tue, 30 Jul 2024 21:47:06 +0200 Subject: [PATCH 06/11] Wrap in try/catch, use more unique stat keys --- .../mixins/early/fml/MixinGameRegistry.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinGameRegistry.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinGameRegistry.java index a1908053..2f39c690 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinGameRegistry.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/fml/MixinGameRegistry.java @@ -13,6 +13,7 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Local; +import com.mitchej123.hodgepodge.Common; import cpw.mods.fml.common.registry.GameRegistry; @@ -58,9 +59,20 @@ public class MixinGameRegistry { @Unique private static StatCrafting hodgepodge$createAndRegisterStat(String key, Item item) { + String unlocalizedName; + try { + unlocalizedName = item.getUnlocalizedName(); + } catch (Exception e) { + String registryName = item.delegate.name(); + unlocalizedName = "item." + registryName + ".name"; + Common.log.warn( + "An Exception occured while invoking Item.getUnlocalizedName() after registering the item {} ({})! Using fallback unlocalized name.", + registryName, + item.getClass().getName()); + } StatCrafting stat = new StatCrafting( - key + '.' + item.delegate.name(), - new ChatComponentTranslation(key, new ChatComponentTranslation(item.getUnlocalizedName())), + key + ".autogen." + item.delegate.name(), + new ChatComponentTranslation(key, new ChatComponentTranslation(unlocalizedName)), item); stat.registerStat(); return stat; From 5b90f2c3e28c62dfc121a3a32e0355203ae0114e Mon Sep 17 00:00:00 2001 From: glowredman <35727266+glowredman@users.noreply.github.com> Date: Sun, 11 Aug 2024 02:09:22 +0200 Subject: [PATCH 07/11] Prevent duplicate initialization of stats --- .../java/com/mitchej123/hodgepodge/util/StatHandler.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java b/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java index 0c48908a..1e127a38 100644 --- a/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java +++ b/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java @@ -41,7 +41,7 @@ public static void remap(ImmutableList remappedIds) { arraycopy(StatList.objectCraftStats, STATS_CRAFT); arraycopy(StatList.objectUseStats, STATS_USE); arraycopy(StatList.objectBreakStats, STATS_BREAK); - initFrozenStats = true; + initFrozenStats = false; } if (remappedIds.isEmpty()) { // we are reverting to frozen ids @@ -76,6 +76,10 @@ public static void remap(ImmutableList remappedIds) { } public static void addEntityStats() { + if (!ADDITIONAL_ENTITY_EGGS.isEmpty()) { + // only populate map once - we don't want duplicate stats + return; + } for (Entry, String> e : EntityList.classToStringMapping.entrySet()) { Class clazz = e.getKey(); if (!EntityLivingBase.class.isAssignableFrom(clazz)) { From 2a11d67953ba03e29f80c507f531bb47c6c8abf3 Mon Sep 17 00:00:00 2001 From: glowredman <35727266+glowredman@users.noreply.github.com> Date: Sun, 11 Aug 2024 02:10:11 +0200 Subject: [PATCH 08/11] Don't remap mine stats for items --- .../com/mitchej123/hodgepodge/util/StatHandler.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java b/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java index 1e127a38..74c27671 100644 --- a/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java +++ b/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java @@ -64,7 +64,15 @@ public static void remap(ImmutableList remappedIds) { } final int newId = remapping.newId; final int oldId = remapping.oldId; - statsMine[newId] = StatList.mineBlockStatArray[oldId]; + + if (newId < 4096 && oldId < 4096) { + statsMine[newId] = StatList.mineBlockStatArray[oldId]; + } else if (newId < 4096 ^ oldId < 4096) { + // 0 - 4095 -> blocks + // 4096+ -> items + // switching domains is unexpected + Common.log.warn("Unexpected remap: oldID={}, newId={}, tag={}", oldId, newId, remapping.tag); + } statsCraft[newId] = StatList.objectCraftStats[oldId]; statsUse[newId] = StatList.objectUseStats[oldId]; statsBreak[newId] = StatList.objectBreakStats[oldId]; From 302903b188a797ef5adce8b12f1d62b3f26de31e Mon Sep 17 00:00:00 2001 From: glowredman <35727266+glowredman@users.noreply.github.com> Date: Sun, 11 Aug 2024 02:12:48 +0200 Subject: [PATCH 09/11] Catch IOOBEs --- .../mitchej123/hodgepodge/mixins/Mixins.java | 5 ++- .../early/minecraft/MixinStatsBlock.java | 41 +++++++++++++++++++ .../early/minecraft/MixinStatsItem.java | 41 +++++++++++++++++++ .../hodgepodge/util/StatHandler.java | 24 +++++++++++ 4 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatsBlock.java create mode 100644 src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatsItem.java diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java b/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java index d3cdbf2c..3db38fd9 100644 --- a/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java @@ -407,8 +407,9 @@ public enum Mixins { .setSide(Side.BOTH)), ADD_MOD_ENTITY_STATS_CLIENT(new Builder("Add stats for modded entities (client side)") - .addMixinClasses("minecraft.MixinStatsMobsList").addTargetedMod(TargetedMod.VANILLA) - .setApplyIf(() -> TweaksConfig.addModEntityStats).setPhase(Phase.EARLY).setSide(Side.CLIENT)), + .addMixinClasses("minecraft.MixinStatsMobsList", "minecraft.MixinStatsBlock", "minecraft.MixinStatsItem") + .addTargetedMod(TargetedMod.VANILLA).setApplyIf(() -> TweaksConfig.addModEntityStats).setPhase(Phase.EARLY) + .setSide(Side.CLIENT)), // Ic2 adjustments IC2_UNPROTECTED_GET_BLOCK_FIX(new Builder("IC2 Kinetic Fix").setPhase(Phase.EARLY).setSide(Side.BOTH) diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatsBlock.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatsBlock.java new file mode 100644 index 00000000..051c838b --- /dev/null +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatsBlock.java @@ -0,0 +1,41 @@ +package com.mitchej123.hodgepodge.mixins.early.minecraft; + +import net.minecraft.stats.StatBase; +import net.minecraft.stats.StatCrafting; + +import org.spongepowered.asm.lib.Opcodes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import com.llamalad7.mixinextras.sugar.Local; +import com.mitchej123.hodgepodge.util.StatHandler; + +@Mixin(targets = "net.minecraft.client.gui.achievement.GuiStats$StatsBlock") +public class MixinStatsBlock { + + @Redirect( + at = @At( + args = "array=get", + opcode = Opcodes.GETSTATIC, + target = "Lnet/minecraft/stats/StatList;objectUseStats:[Lnet/minecraft/stats/StatBase;", + value = "FIELD"), + expect = 2, + method = "") + private StatBase hodgepodge$preventUseAIOOBE(StatBase[] array, int index, @Local StatCrafting statcrafting) { + return StatHandler.checkBounds(array, index, statcrafting); + } + + @Redirect( + at = @At( + args = "array=get", + opcode = Opcodes.GETSTATIC, + target = "Lnet/minecraft/stats/StatList;objectCraftStats:[Lnet/minecraft/stats/StatBase;", + value = "FIELD"), + expect = 2, + method = "") + private StatBase hodgepodge$preventCraftAIOOBE(StatBase[] array, int index, @Local StatCrafting statcrafting) { + return StatHandler.checkBounds(array, index, statcrafting); + } + +} diff --git a/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatsItem.java b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatsItem.java new file mode 100644 index 00000000..4d259af8 --- /dev/null +++ b/src/main/java/com/mitchej123/hodgepodge/mixins/early/minecraft/MixinStatsItem.java @@ -0,0 +1,41 @@ +package com.mitchej123.hodgepodge.mixins.early.minecraft; + +import net.minecraft.stats.StatBase; +import net.minecraft.stats.StatCrafting; + +import org.spongepowered.asm.lib.Opcodes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import com.llamalad7.mixinextras.sugar.Local; +import com.mitchej123.hodgepodge.util.StatHandler; + +@Mixin(targets = "net.minecraft.client.gui.achievement.GuiStats$StatsItem") +public class MixinStatsItem { + + @Redirect( + at = @At( + args = "array=get", + opcode = Opcodes.GETSTATIC, + target = "Lnet/minecraft/stats/StatList;objectBreakStats:[Lnet/minecraft/stats/StatBase;", + value = "FIELD"), + expect = 2, + method = "") + private StatBase hodgepodge$preventBreakAIOOBE(StatBase[] array, int index, @Local StatCrafting statcrafting) { + return StatHandler.checkBounds(array, index, statcrafting); + } + + @Redirect( + at = @At( + args = "array=get", + opcode = Opcodes.GETSTATIC, + target = "Lnet/minecraft/stats/StatList;objectCraftStats:[Lnet/minecraft/stats/StatBase;", + value = "FIELD"), + expect = 2, + method = "") + private StatBase hodgepodge$preventCraftAIOOBE(StatBase[] array, int index, @Local StatCrafting statcrafting) { + return StatHandler.checkBounds(array, index, statcrafting); + } + +} diff --git a/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java b/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java index 74c27671..bb463024 100644 --- a/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java +++ b/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java @@ -10,12 +10,15 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.Item; import net.minecraft.stats.StatBase; +import net.minecraft.stats.StatCrafting; import net.minecraft.stats.StatList; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.living.LivingDeathEvent; import com.google.common.collect.ImmutableList; +import com.mitchej123.hodgepodge.Common; import cpw.mods.fml.common.event.FMLModIdMappingEvent.ModRemapping; import cpw.mods.fml.common.event.FMLModIdMappingEvent.RemapTarget; @@ -132,6 +135,27 @@ public void onLivingDeathEvent(LivingDeathEvent event) { } } + public static StatBase checkBounds(StatBase[] array, int index, StatCrafting statcrafting) { + if (index < 0 || index >= array.length) { + Item item = statcrafting.func_150959_a(); + String name = item == null ? "null" : item.delegate.name(); + if (index == -1) { + Common.log.warn( + "Caught out-of-bounds item ID {} for stat {} of item {}", + index, + statcrafting.statId, + name); + Common.log + .info("You can ignore this warning if {} is not installed on the server!", name.split(":")[0]); + return null; + } + Common.log + .error("Caught out-of-bounds item ID {} for stat {} of item {}", index, statcrafting.statId, name); + return null; + } + return array[index]; + } + private static void arraycopy(T[] src, T[] dest) { System.arraycopy(src, 0, dest, 0, src.length); } From 8ed720ab22de49bb8bd29ded817f475856611d44 Mon Sep 17 00:00:00 2001 From: glowredman <35727266+glowredman@users.noreply.github.com> Date: Sun, 11 Aug 2024 02:13:13 +0200 Subject: [PATCH 10/11] Use a more robust method to check for already registered stats --- .../hodgepodge/commands/DebugCommand.java | 3 +-- .../com/mitchej123/hodgepodge/util/StatHandler.java | 13 ++++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/mitchej123/hodgepodge/commands/DebugCommand.java b/src/main/java/com/mitchej123/hodgepodge/commands/DebugCommand.java index 3552bc31..c7dc3165 100644 --- a/src/main/java/com/mitchej123/hodgepodge/commands/DebugCommand.java +++ b/src/main/java/com/mitchej123/hodgepodge/commands/DebugCommand.java @@ -40,9 +40,8 @@ private void printHelp(ICommandSender sender) { "\"randomNbt [bytes]\" - adds a random byte array of the given size to the held item")); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Override - public List addTabCompletionOptions(ICommandSender sender, String[] ss) { + public List addTabCompletionOptions(ICommandSender sender, String[] ss) { List l = new ArrayList<>(); String test = ss.length == 0 ? "" : ss[0].trim(); if (ss.length == 0 || ss.length == 1 diff --git a/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java b/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java index bb463024..f9f1b3e6 100644 --- a/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java +++ b/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java @@ -86,6 +86,7 @@ public static void remap(ImmutableList remappedIds) { arraycopy(statsBreak, StatList.objectBreakStats); } + @SuppressWarnings("unchecked") public static void addEntityStats() { if (!ADDITIONAL_ENTITY_EGGS.isEmpty()) { // only populate map once - we don't want duplicate stats @@ -97,13 +98,15 @@ public static void addEntityStats() { // only entities extending EntityLivingBase can be killed/can kill the player continue; } - @SuppressWarnings("unchecked") - Integer id = (Integer) EntityList.classToIDMapping.getOrDefault(clazz, 256); - if (EntityList.entityEggs.containsKey(id)) { + currentEntityName = e.getValue(); + // func_151177_a = getOneShotStat + if (StatList.func_151177_a("stat.killEntity." + currentEntityName) != null + || StatList.func_151177_a("stat.entityKilledBy." + currentEntityName) != null) { continue; } - currentEntityName = e.getValue(); - ADDITIONAL_ENTITY_EGGS.put(clazz, new EntityInfo(id, currentEntityName)); + ADDITIONAL_ENTITY_EGGS.put( + clazz, + new EntityInfo((int) EntityList.classToIDMapping.getOrDefault(clazz, 256), currentEntityName)); } currentEntityName = null; MinecraftForge.EVENT_BUS.register(new StatHandler()); From 6923bb32965350873cc5b8c9e36fbe91f347aeba Mon Sep 17 00:00:00 2001 From: glowredman <35727266+glowredman@users.noreply.github.com> Date: Sun, 11 Aug 2024 14:00:50 +0200 Subject: [PATCH 11/11] Add entity exclusion list --- .../hodgepodge/config/TweaksConfig.java | 5 +++++ .../hodgepodge/util/StatHandler.java | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java b/src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java index 9fcf3270..c8f69086 100644 --- a/src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java +++ b/src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java @@ -168,6 +168,11 @@ public class TweaksConfig { @Config.RequiresMcRestart public static boolean addModEntityStats; + @Config.Comment("No stats will be registered for these enties (e.g. because another mod already adds them)") + @Config.DefaultStringList({ "Mob", "Monster" }) + @Config.RequiresMcRestart + public static String[] entityStatsExclusions; + @Config.Comment("Sort Mob stats lexicographically (Requires addModEntityStats)") @Config.DefaultBoolean(true) public static boolean sortEntityStats; diff --git a/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java b/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java index f9f1b3e6..c39b589b 100644 --- a/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java +++ b/src/main/java/com/mitchej123/hodgepodge/util/StatHandler.java @@ -3,6 +3,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityList; @@ -18,8 +19,11 @@ import net.minecraftforge.event.entity.living.LivingDeathEvent; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Sets; import com.mitchej123.hodgepodge.Common; +import com.mitchej123.hodgepodge.config.TweaksConfig; +import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.event.FMLModIdMappingEvent.ModRemapping; import cpw.mods.fml.common.event.FMLModIdMappingEvent.RemapTarget; import cpw.mods.fml.common.eventhandler.EventPriority; @@ -46,6 +50,7 @@ public static void remap(ImmutableList remappedIds) { arraycopy(StatList.objectBreakStats, STATS_BREAK); initFrozenStats = false; } + if (remappedIds.isEmpty()) { // we are reverting to frozen ids arraycopy(STATS_MINE, StatList.mineBlockStatArray); @@ -92,22 +97,36 @@ public static void addEntityStats() { // only populate map once - we don't want duplicate stats return; } + + Set excludedEntities = Sets.newHashSet(TweaksConfig.entityStatsExclusions); + if (Loader.isModLoaded("NotEnoughItems")) { + excludedEntities.add("SnowMan"); + excludedEntities.add("VillagerGolem"); + } + for (Entry, String> e : EntityList.classToStringMapping.entrySet()) { Class clazz = e.getKey(); if (!EntityLivingBase.class.isAssignableFrom(clazz)) { // only entities extending EntityLivingBase can be killed/can kill the player continue; } + currentEntityName = e.getValue(); + if (excludedEntities.contains(currentEntityName)) { + continue; + } + // func_151177_a = getOneShotStat if (StatList.func_151177_a("stat.killEntity." + currentEntityName) != null || StatList.func_151177_a("stat.entityKilledBy." + currentEntityName) != null) { continue; } + ADDITIONAL_ENTITY_EGGS.put( clazz, new EntityInfo((int) EntityList.classToIDMapping.getOrDefault(clazz, 256), currentEntityName)); } + currentEntityName = null; MinecraftForge.EVENT_BUS.register(new StatHandler()); }