ValkyrienSkies / Valkyrien-Skies-2

Valkyrien Skies 2
https://valkyrienskies.org/
GNU Lesser General Public License v3.0
227 stars 99 forks source link

Minor fix, Urgent: Fix soft-overwrite preventing other mods' mobs from despawning with special conditions. #907

Closed ByThePowerOfScience closed 3 months ago

ByThePowerOfScience commented 4 months ago

Replaces a soft-overwrite Inject with a ModifyArg that does the same thing and doesn't prevent other Mixins targeting this method from firing.

StewStrong commented 3 months ago

This code crashes when I try running it

ByThePowerOfScience commented 3 months ago

This code crashes when I try running it

I'll take a look, it's possible I got the args wrong.

StewStrong commented 3 months ago

I think this would work, tho I havent tested it

package org.valkyrienskies.mod.mixin.feature.shipyard_entities;

import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.entity.EntitySectionStorage;
import net.minecraft.world.level.entity.PersistentEntitySectionManager;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.valkyrienskies.mod.mixinducks.world.OfLevel;

@Mixin(PersistentEntitySectionManager.class)
public abstract class MixinPersistentEntitySectionManager implements OfLevel {
    @Shadow
    @Final
    EntitySectionStorage<Entity> sectionStorage;

    @Unique
    private Level valkyrienskies$level;

    @Override
    public Level getLevel() {
        return valkyrienskies$level;
    }

    @Override
    public void setLevel(final Level level) {
        this.valkyrienskies$level = level;
        ((OfLevel) this.sectionStorage).setLevel(level);
    }

    /**
     * This fixes this function randomly crashing. I'm not sure why but the removeIf() function is buggy
     */
    @ModifyArg(
        method = "processUnloads",
        at = @At(
            target = "Lit/unimi/dsi/fastutil/longs/LongSet;removeIf(Ljava/uti l/function/LongPredicate;)Z",
            value = "INVOKE"
        )
    )
    private java.util.function.LongPredicate processUnloads_catchException(
        final java.util.function.LongPredicate par1) {
        return (l) -> {
            try {
                return par1.test(l);
            } catch (final Exception e) {
                e.printStackTrace();
                return false;
            }
        };
    }
}
StewStrong commented 3 months ago

I merged the updated fix in https://github.com/ValkyrienSkies/Valkyrien-Skies-2/commit/dcba513e6d0e8a49903a1b0be5dfb6baedb321f7

ByThePowerOfScience commented 3 months ago

Nevermind, I misunderstood the problem removeIf was having. The function itself is running into a NPE, not something in the predicate.

In that case, do what SmoothChunkLoading does and mix into tick's call of processUnloads and wrap it with a WrapOperation handler. I'll do it in the morning.