Powah! (Rearchitected)

Powah! (Rearchitected)

3M Downloads

ForgeEnvHandler causes other mods to return ClassCastException when attempting to get an invalid Reactor ports' Capabilities

AmmoniumX opened this issue ยท 4 comments

commented

Version: (make sure you are on the latest version before reporting):

  • Minecraft:1.19.2 (Enigmatica 9)
  • Forge: 43.2.14
  • Powah: Powah-4.0.11.jar

Issue description:

Where do I even begin... It's a hard problem so sorry if it looks like I'm not making concise enough, but I believe all the information is necessary.

In an Enigmatica 9 world, which has mods such as Powah, Nature's Aura, etc. Our server got stuck in a crash loop due to a ClassCastException, this can be seen in Crash Log. It's a crash from an attempt to cast owmii.powah.forge.ForgeEnvHandler$7 into de.ellpeck.naturesaura.api.aura.container.IAuraContainer. For context, Nature's Aura's code is just taking nearby BlockEntities around a block and checking for Capabilities:

Helper.getBlockEntitiesInArea(level, pos, 25, tile -> {
**[28]**    var container = tile.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER, null).orElse(null);
    if (container instanceof ISpotDrainable)
        tiles.add((ISpotDrainable) container);
        return false;
    });

The crash specifically pointing to line [28]. I surrounded it with a try catch and some quick debugging logs:

try {
    var container = tile.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER, null).orElse(null);
    if (container instanceof ISpotDrainable) tiles.add((ISpotDrainable) container);
} catch (ClassCastException e) {
    NaturesAura.LOGGER.error("Error getting capability NaturesAuraAPI.CAP_AURA_CONTAINER from BlockEntity "+tile+" at "+tile.getBlockPos());
}

This allowed the server world to be opened in a singleplayer client, and showed the problematic code:
[15:01:31] [Server thread/ERROR]: Error getting capability NaturesAuraAPI.CAP_AURA_CONTAINER from BlockEntity owmii.powah.block.reactor.ReactorPartTile@6be93e93 at BlockPos{x=217, y=72, z=194}
Additionally, this also revealed that a lot of mods were also throwing ClassCastException when checking for capabilities with ForgeEnvHandler, there's multiple of them but here's some from Client Log 1:

[15:01:47] [Server thread/ERROR]: Error executing task on Server
java.lang.ClassCastException: class owmii.powah.forge.ForgeEnvHandler$7 cannot be cast to class net.mehvahdjukaar.supplementaries.api.IAntiqueTextProvider (owmii.powah.forge.ForgeEnvHandler$7 is in module [email protected] of loader 'TRANSFORMER' @7d61468c; net.mehvahdjukaar.supplementaries.api.IAntiqueTextProvider is in module [email protected] of loader 'TRANSFORMER' @7d61468c)

[15:05:16] [Server thread/ERROR]: Exception caught during firing event: class owmii.powah.forge.ForgeEnvHandler$7 cannot be cast to class mekanism.api.security.ISecurityObject (owmii.powah.forge.ForgeEnvHandler$7 is in module [email protected] of loader 'TRANSFORMER' @7d61468c; mekanism.api.security.ISecurityObject is in module [email protected] of loader 'TRANSFORMER' @7d61468c)

Which pointed me to this code in ForgeEnvHandler:

if (event.getObject() instanceof ReactorPartTile reactorPart) {
    event.addCapability(Powah.id("reactor_part"), new ICapabilityProvider() {
        @NotNull
        @Override
        public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
            if (reactorPart.core().isPresent()) {
                if (cap != CapabilityEnergy.ENERGY || reactorPart.isExtractor()) {
                    return reactorPart.core().get().getCapability(cap, side);
                }
            }
            return LazyOptional.empty();
        }
    });
}

I thought that maybe making a check that the reactor core has the capability would help, so I modified it to this:

if (event.getObject() instanceof ReactorPartTile reactorPart) {
                event.addCapability(Powah.id("reactor_part"), new ICapabilityProvider() {
                    @NotNull
                    @Override
                    public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
                        if (reactorPart.core().isPresent()) {
                            if (cap != CapabilityEnergy.ENERGY || reactorPart.isExtractor()) {
                                ReactorTile core = reactorPart.core().get();
                                // Ensure the core actually supports the requested capability
                                LazyOptional<T> coreCapability = core.getCapability(cap, side);
                                if (coreCapability.isPresent()) {
                                    return coreCapability;
                                }
                            }
                        }
                        return LazyOptional.empty();
                    }
                });
            }

And it allowed the world to open again (even without the previous NatAura "patch"), however it still causes similar (thankfully non-crashing) issues:

[16:19:54] [Server thread/ERROR]: Error executing task on Server
java.lang.ClassCastException: class owmii.powah.forge.ForgeEnvHandler$7 cannot be cast to class net.mehvahdjukaar.supplementaries.api.IAntiqueTextProvider (owmii.powah.forge.ForgeEnvHandler$7 is in module [email protected] of loader 'TRANSFORMER' @5731caaf; net.mehvahdjukaar.supplementaries.api.IAntiqueTextProvider is in module [email protected] of loader 'TRANSFORMER' @5731caaf)

So somehow, ForgeEnvHandler is causing other mods to throw a ClassCastException when trying to check for a Reactor Port's capabilities.

Steps to reproduce:

  1. Download Enigmatica 9 modpack
  2. Download server world and paste the world folder in your saves folder
  3. Try opening the world
  4. Result: Crash with ClassCastException
  5. Change the code in ForgeEnvHandler as described above, build and replace in E9 mods folder.
  6. Try opening the world
  7. Result: World does open, but logs show ForgeEnvHandler still causes ClassCastException with some mods
    ...

Is this a crash?, please include it here: (Recommended to use Gist)

Crash Log: https://mclo.gs/X0tvdkV
Client Log: https://mclo.gs/6ooZFQr
...

commented

Can you try without the AECapFix mod?

commented

Can you try without the AECapFix mod?

Yup, removing the AECapFix worked, thank you :)

commented

I should probably point out that your AECapFix version was out of date in that log. I'm pretty sure I fixed this exact issue in the 0.8 build.

commented

Yeah, just tried updating it to version 0.8 and it works as well. Thank you for your help