diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/feature/get_entities/MixinLevel.java b/common/src/main/java/org/valkyrienskies/mod/mixin/feature/get_entities/MixinLevel.java index 863abae56..a459b8699 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/feature/get_entities/MixinLevel.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/feature/get_entities/MixinLevel.java @@ -19,6 +19,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.valkyrienskies.core.util.RateLimiter; import org.valkyrienskies.mod.common.VSGameUtilsKt; +import org.valkyrienskies.mod.util.BugFixUtil; @Mixin(Level.class) public class MixinLevel { @@ -28,11 +29,6 @@ public class MixinLevel { @Unique private static final RateLimiter LIMITER = new RateLimiter(Duration.ofSeconds(5)); - @Unique - private static boolean isCollisionBoxToBig(final AABB aabb) { - return aabb.getXsize() > 1000 || aabb.getYsize() > 1000 || aabb.getZsize() > 1000; - } - @ModifyVariable( method = "getEntities(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/AABB;Ljava/util/function/Predicate;)Ljava/util/List;", at = @At("HEAD"), @@ -59,7 +55,7 @@ private AABB moveAABB2(final AABB aabb) { private void check1(final EntityTypeTest entityTypeTest, final AABB area, final Predicate predicate, final CallbackInfoReturnable> cir) { - if (isCollisionBoxToBig(area)) { + if (BugFixUtil.INSTANCE.isCollisionBoxToBig(area)) { LIMITER.maybeRun(() -> LOGGER.error(new Exception( "Collision box is too big! " + area + " returning empty list! this might break things"))); @@ -76,7 +72,7 @@ private void check1(final EntityTypeTest entityTyp private void check2(@Nullable final Entity entity, final AABB area, final Predicate predicate, final CallbackInfoReturnable> cir) { - if (isCollisionBoxToBig(area)) { + if (BugFixUtil.INSTANCE.isCollisionBoxToBig(area)) { LIMITER.maybeRun(() -> LOGGER.error(new Exception( "Collision box is too big! " + area + " returning empty list! this might break things"))); diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/world/level/MixinBlockCollisions.java b/common/src/main/java/org/valkyrienskies/mod/mixin/world/level/MixinBlockCollisions.java new file mode 100644 index 000000000..28a9f4b31 --- /dev/null +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/world/level/MixinBlockCollisions.java @@ -0,0 +1,53 @@ +package org.valkyrienskies.mod.mixin.world.level; + +import net.minecraft.core.Cursor3D; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.BlockCollisions; +import net.minecraft.world.level.CollisionGetter; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +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 org.valkyrienskies.mod.util.BugFixUtil; + +/** + * Fix game freezing when a too-large AABB is used in a BlockCollisions object + */ +@Mixin(BlockCollisions.class) +public class MixinBlockCollisions { + @Shadow + @Final + @Mutable + private AABB box; + @Shadow + @Final + @Mutable + private Cursor3D cursor; + @Shadow + @Final + @Mutable + private VoxelShape entityShape; + + @Inject(method = "(Lnet/minecraft/world/level/CollisionGetter;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/AABB;Z)V", at = @At("RETURN")) + private void postInit(final CollisionGetter collisionGetter, final Entity entity, final AABB aabb, final boolean bl, final CallbackInfo ci) { + if (BugFixUtil.INSTANCE.isCollisionBoxToBig(aabb)) { + final AABB newBox = new AABB(aabb.minX, aabb.minY, aabb.minZ, aabb.minX, aabb.minY, aabb.minZ); + this.entityShape = Shapes.create(newBox); + this.box = newBox; + final int i = Mth.floor(newBox.minX - 1.0E-7) - 1; + final int j = Mth.floor(newBox.maxX + 1.0E-7) + 1; + final int k = Mth.floor(newBox.minY - 1.0E-7) - 1; + final int l = Mth.floor(newBox.maxY + 1.0E-7) + 1; + final int m = Mth.floor(newBox.minZ - 1.0E-7) - 1; + final int n = Mth.floor(newBox.maxZ + 1.0E-7) + 1; + this.cursor = new Cursor3D(i, k, m, j, l, n); + } + } +} diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/EntityShipCollisionUtils.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/EntityShipCollisionUtils.kt index eb5172f0a..89b3128f8 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/EntityShipCollisionUtils.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/EntityShipCollisionUtils.kt @@ -18,6 +18,7 @@ import org.valkyrienskies.core.util.extend import org.valkyrienskies.mod.common.getShipsIntersecting import org.valkyrienskies.mod.common.shipObjectWorld import org.valkyrienskies.mod.common.vsCore +import org.valkyrienskies.mod.util.BugFixUtil import kotlin.math.max object EntityShipCollisionUtils { @@ -116,6 +117,10 @@ object EntityShipCollisionUtils { shipTransform.worldToShip ) val entityBoundingBoxInShipCoordinates: AABBdc = entityPolyInShipCoordinates.getEnclosingAABB(AABBd()) + if (BugFixUtil.isCollisionBoxToBig(entityBoundingBoxInShipCoordinates.toMinecraft())) { + // Box too large, skip it + continue + } val shipBlockCollisionStream = world.getBlockCollisions(entity, entityBoundingBoxInShipCoordinates.toMinecraft()) shipBlockCollisionStream.forEach { voxelShape: VoxelShape -> diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/util/BugFixUtil.kt b/common/src/main/kotlin/org/valkyrienskies/mod/util/BugFixUtil.kt new file mode 100644 index 000000000..58e39edc2 --- /dev/null +++ b/common/src/main/kotlin/org/valkyrienskies/mod/util/BugFixUtil.kt @@ -0,0 +1,9 @@ +package org.valkyrienskies.mod.util + +import net.minecraft.world.phys.AABB + +object BugFixUtil { + fun isCollisionBoxToBig(aabb: AABB): Boolean { + return aabb.xsize > 1000 || aabb.ysize > 1000 || aabb.zsize > 1000 + } +} diff --git a/common/src/main/resources/valkyrienskies-common.mixins.json b/common/src/main/resources/valkyrienskies-common.mixins.json index 71d3397a0..7a900ea56 100644 --- a/common/src/main/resources/valkyrienskies-common.mixins.json +++ b/common/src/main/resources/valkyrienskies-common.mixins.json @@ -103,6 +103,7 @@ "world.chunk.MixinLevelChunk", "world.entity.MixinPlayer", "world.entity.projectile.ProjectileUtilMixin", + "world.level.MixinBlockCollisions", "world.level.MixinLevel", "world.level.chunk.MixinChunkGenerator", "world.level.levelgen.MixinFlatLevelSource",