From 08fd796fe2f32f5abc7ee6a7c0aa61255dfe1a11 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Sun, 2 Dec 2018 01:36:41 +0100 Subject: [PATCH] made an API change to enforce the right aura methods, also add over- and underflow protection --- .../de/ellpeck/naturesaura/InternalHooks.java | 14 ++++----- .../naturesaura/api/NaturesAuraAPI.java | 5 ++-- .../api/aura/chunk/IAuraChunk.java | 7 ++--- .../api/aura/chunk/IDrainSpotEffect.java | 3 +- .../naturesaura/api/internal/StubHooks.java | 3 +- .../ellpeck/naturesaura/chunk/AuraChunk.java | 29 ++++++++++++------- .../chunk/effect/BalanceEffect.java | 7 ++--- .../chunk/effect/BreathlessEffect.java | 5 ++-- .../chunk/effect/ExplosionEffect.java | 5 ++-- .../chunk/effect/GrassDieEffect.java | 5 ++-- .../chunk/effect/PlantBoostEffect.java | 5 ++-- .../chunk/effect/ReplenishingEffect.java | 12 ++++---- .../naturesaura/events/ClientEvents.java | 4 +-- 13 files changed, 50 insertions(+), 54 deletions(-) diff --git a/src/main/java/de/ellpeck/naturesaura/InternalHooks.java b/src/main/java/de/ellpeck/naturesaura/InternalHooks.java index 04dcdc08..181f38db 100644 --- a/src/main/java/de/ellpeck/naturesaura/InternalHooks.java +++ b/src/main/java/de/ellpeck/naturesaura/InternalHooks.java @@ -73,7 +73,7 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks { } @Override - public void getAuraSpotsInArea(World world, BlockPos pos, int radius, BiConsumer consumer) { + public void getAuraSpotsInArea(World world, BlockPos pos, int radius, BiConsumer consumer) { world.profiler.func_194340_a(() -> NaturesAura.MOD_ID + ":getSpotsInArea"); for (int x = (pos.getX() - radius) >> 4; x <= (pos.getX() + radius) >> 4; x++) { for (int z = (pos.getZ() - radius) >> 4; z <= (pos.getZ() + radius) >> 4; z++) { @@ -92,7 +92,7 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks { @Override public int getAuraInArea(World world, BlockPos pos, int radius) { MutableInt result = new MutableInt(IAuraChunk.DEFAULT_AURA); - this.getAuraSpotsInArea(world, pos, radius, (blockPos, drainSpot) -> result.add(drainSpot.intValue())); + this.getAuraSpotsInArea(world, pos, radius, (blockPos, drainSpot) -> result.add(drainSpot)); return result.intValue(); } @@ -101,9 +101,8 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks { MutableInt lowestAmount = new MutableInt(Integer.MAX_VALUE); MutableObject lowestSpot = new MutableObject<>(); this.getAuraSpotsInArea(world, pos, radius, (blockPos, drainSpot) -> { - int amount = drainSpot.intValue(); - if (amount < lowestAmount.intValue()) { - lowestAmount.setValue(amount); + if (drainSpot < lowestAmount.intValue()) { + lowestAmount.setValue(drainSpot); lowestSpot.setValue(blockPos); } }); @@ -118,9 +117,8 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks { MutableInt highestAmount = new MutableInt(Integer.MIN_VALUE); MutableObject highestSpot = new MutableObject<>(); this.getAuraSpotsInArea(world, pos, radius, (blockPos, drainSpot) -> { - int amount = drainSpot.intValue(); - if (amount > highestAmount.intValue()) { - highestAmount.setValue(amount); + if (drainSpot > highestAmount.intValue()) { + highestAmount.setValue(drainSpot); highestSpot.setValue(blockPos); } }); diff --git a/src/main/java/de/ellpeck/naturesaura/api/NaturesAuraAPI.java b/src/main/java/de/ellpeck/naturesaura/api/NaturesAuraAPI.java index df12891f..76215f29 100644 --- a/src/main/java/de/ellpeck/naturesaura/api/NaturesAuraAPI.java +++ b/src/main/java/de/ellpeck/naturesaura/api/NaturesAuraAPI.java @@ -21,7 +21,6 @@ import net.minecraft.world.DimensionType; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.CapabilityInject; -import org.apache.commons.lang3.mutable.MutableInt; import java.util.ArrayList; import java.util.HashMap; @@ -40,7 +39,7 @@ public final class NaturesAuraAPI { public static final String MOD_ID = "naturesaura"; public static final String API_ID = MOD_ID + "api"; - public static final String VERSION = "4"; + public static final String VERSION = "5"; /** * The list of all {@link AltarRecipe} instances which are the recipes used @@ -226,7 +225,7 @@ public final class NaturesAuraAPI { /** * @see IAuraChunk#getSpotsInArea(World, BlockPos, int, BiConsumer) */ - void getAuraSpotsInArea(World world, BlockPos pos, int radius, BiConsumer consumer); + void getAuraSpotsInArea(World world, BlockPos pos, int radius, BiConsumer consumer); /** * @see IAuraChunk#getAuraInArea(World, BlockPos, int) diff --git a/src/main/java/de/ellpeck/naturesaura/api/aura/chunk/IAuraChunk.java b/src/main/java/de/ellpeck/naturesaura/api/aura/chunk/IAuraChunk.java index 9439c452..180be65d 100644 --- a/src/main/java/de/ellpeck/naturesaura/api/aura/chunk/IAuraChunk.java +++ b/src/main/java/de/ellpeck/naturesaura/api/aura/chunk/IAuraChunk.java @@ -8,7 +8,6 @@ import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.util.INBTSerializable; -import org.apache.commons.lang3.mutable.MutableInt; import java.util.function.BiConsumer; @@ -59,7 +58,7 @@ public interface IAuraChunk extends ICapabilityProvider, INBTSerializable consumer) { + static void getSpotsInArea(World world, BlockPos pos, int radius, BiConsumer consumer) { NaturesAuraAPI.instance().getAuraSpotsInArea(world, pos, radius, consumer); } @@ -117,7 +116,7 @@ public interface IAuraChunk extends ICapabilityProvider, INBTSerializable consumer); + void getSpotsInArea(BlockPos pos, int radius, BiConsumer consumer); /** * Drains the given amount of Aura from the given position. Returns the @@ -165,7 +164,7 @@ public interface IAuraChunk extends ICapabilityProvider, INBTSerializable consumer) { + public void getAuraSpotsInArea(World world, BlockPos pos, int radius, BiConsumer consumer) { } diff --git a/src/main/java/de/ellpeck/naturesaura/chunk/AuraChunk.java b/src/main/java/de/ellpeck/naturesaura/chunk/AuraChunk.java index 8bf95d6f..64c20ed0 100644 --- a/src/main/java/de/ellpeck/naturesaura/chunk/AuraChunk.java +++ b/src/main/java/de/ellpeck/naturesaura/chunk/AuraChunk.java @@ -43,11 +43,11 @@ public class AuraChunk implements IAuraChunk { } @Override - public void getSpotsInArea(BlockPos pos, int radius, BiConsumer consumer) { + public void getSpotsInArea(BlockPos pos, int radius, BiConsumer consumer) { for (Map.Entry entry : this.drainSpots.entrySet()) { BlockPos drainPos = entry.getKey(); if (drainPos.distanceSq(pos) <= radius * radius) { - consumer.accept(drainPos, entry.getValue()); + consumer.accept(drainPos, entry.getValue().intValue()); } } } @@ -56,9 +56,11 @@ public class AuraChunk implements IAuraChunk { public int drainAura(BlockPos pos, int amount, boolean aimForZero, boolean simulate) { if (amount <= 0) return 0; - MutableInt spot = this.getDrainSpot(pos); + MutableInt spot = this.getActualDrainSpot(pos, true); + int curr = spot.intValue(); + if (curr < 0 && curr - amount > 0) // Underflow protection + return 0; if (aimForZero) { - int curr = spot.intValue(); if (curr > 0 && curr - amount < 0) amount = curr; } @@ -78,9 +80,11 @@ public class AuraChunk implements IAuraChunk { public int storeAura(BlockPos pos, int amount, boolean aimForZero, boolean simulate) { if (amount <= 0) return 0; - MutableInt spot = this.getDrainSpot(pos); + MutableInt spot = this.getActualDrainSpot(pos, true); + int curr = spot.intValue(); + if (curr > 0 && curr + amount < 0) // Overflow protection + return 0; if (aimForZero) { - int curr = spot.intValue(); if (curr < 0 && curr + amount > 0) { amount = -curr; } @@ -97,16 +101,21 @@ public class AuraChunk implements IAuraChunk { return this.storeAura(pos, amount, true, false); } - @Override - public MutableInt getDrainSpot(BlockPos pos) { + private MutableInt getActualDrainSpot(BlockPos pos, boolean make) { MutableInt spot = this.drainSpots.get(pos); - if (spot == null) { + if (spot == null && make) { spot = new MutableInt(); this.addDrainSpot(pos, spot); } return spot; } + @Override + public int getDrainSpot(BlockPos pos) { + MutableInt spot = this.getActualDrainSpot(pos, false); + return spot == null ? 0 : spot.intValue(); + } + private void addDrainSpot(BlockPos pos, MutableInt spot) { int expX = pos.getX() >> 4; int expZ = pos.getZ() >> 4; @@ -141,7 +150,7 @@ public class AuraChunk implements IAuraChunk { MutableInt amount = entry.getValue(); for (IDrainSpotEffect effect : this.effects) { world.profiler.func_194340_a(() -> effect.getName().toString()); - effect.update(world, this.chunk, this, pos, amount); + effect.update(world, this.chunk, this, pos, amount.intValue()); world.profiler.endSection(); } if (amount.intValue() == 0) { diff --git a/src/main/java/de/ellpeck/naturesaura/chunk/effect/BalanceEffect.java b/src/main/java/de/ellpeck/naturesaura/chunk/effect/BalanceEffect.java index 382616ae..748d3de6 100644 --- a/src/main/java/de/ellpeck/naturesaura/chunk/effect/BalanceEffect.java +++ b/src/main/java/de/ellpeck/naturesaura/chunk/effect/BalanceEffect.java @@ -8,15 +8,14 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; -import org.apache.commons.lang3.mutable.MutableInt; public class BalanceEffect implements IDrainSpotEffect { public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "balance"); @Override - public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, MutableInt spot) { - if (spot.intValue() >= 0) + public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) { + if (spot >= 0) return; int aura = IAuraChunk.getAuraInArea(world, pos, 25); if (aura >= 0) @@ -28,7 +27,7 @@ public class BalanceEffect implements IDrainSpotEffect { if (highestPos == null) return; IAuraChunk highestChunk = IAuraChunk.getAuraChunk(world, highestPos); - int toTransfer = Math.min(25, highestChunk.getDrainSpot(highestPos).intValue()); + int toTransfer = Math.min(25, highestChunk.getDrainSpot(highestPos)); int stored = auraChunk.storeAura(pos, toTransfer); highestChunk.drainAura(highestPos, stored); } diff --git a/src/main/java/de/ellpeck/naturesaura/chunk/effect/BreathlessEffect.java b/src/main/java/de/ellpeck/naturesaura/chunk/effect/BreathlessEffect.java index 408c1bc2..df44f62e 100644 --- a/src/main/java/de/ellpeck/naturesaura/chunk/effect/BreathlessEffect.java +++ b/src/main/java/de/ellpeck/naturesaura/chunk/effect/BreathlessEffect.java @@ -14,7 +14,6 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; -import org.apache.commons.lang3.mutable.MutableInt; import java.util.List; @@ -23,8 +22,8 @@ public class BreathlessEffect implements IDrainSpotEffect { public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "breathless"); @Override - public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, MutableInt spot) { - if (spot.intValue() >= 0 || world.getTotalWorldTime() % 100 != 0) + public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) { + if (spot >= 0 || world.getTotalWorldTime() % 100 != 0) return; int aura = IAuraChunk.getAuraInArea(world, pos, 50); if (aura > 0) diff --git a/src/main/java/de/ellpeck/naturesaura/chunk/effect/ExplosionEffect.java b/src/main/java/de/ellpeck/naturesaura/chunk/effect/ExplosionEffect.java index 7515861d..13660c14 100644 --- a/src/main/java/de/ellpeck/naturesaura/chunk/effect/ExplosionEffect.java +++ b/src/main/java/de/ellpeck/naturesaura/chunk/effect/ExplosionEffect.java @@ -10,15 +10,14 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; -import org.apache.commons.lang3.mutable.MutableInt; public class ExplosionEffect implements IDrainSpotEffect { public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "explosions"); @Override - public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, MutableInt spot) { - if (spot.intValue() >= 0 || world.getTotalWorldTime() % 40 != 0) + public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) { + if (spot >= 0 || world.getTotalWorldTime() % 40 != 0) return; int aura = IAuraChunk.getAuraInArea(world, pos, 85); if (aura > -50000) diff --git a/src/main/java/de/ellpeck/naturesaura/chunk/effect/GrassDieEffect.java b/src/main/java/de/ellpeck/naturesaura/chunk/effect/GrassDieEffect.java index 708081ed..3c43fca5 100644 --- a/src/main/java/de/ellpeck/naturesaura/chunk/effect/GrassDieEffect.java +++ b/src/main/java/de/ellpeck/naturesaura/chunk/effect/GrassDieEffect.java @@ -15,15 +15,14 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; -import org.apache.commons.lang3.mutable.MutableInt; public class GrassDieEffect implements IDrainSpotEffect { public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "grass_die"); @Override - public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, MutableInt spot) { - if (spot.intValue() < 0) { + public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) { + if (spot < 0) { int aura = IAuraChunk.getAuraInArea(world, pos, 50); if (aura < 0) { int amount = Math.min(300, Math.abs(aura) / 1000); diff --git a/src/main/java/de/ellpeck/naturesaura/chunk/effect/PlantBoostEffect.java b/src/main/java/de/ellpeck/naturesaura/chunk/effect/PlantBoostEffect.java index a8404637..41680179 100644 --- a/src/main/java/de/ellpeck/naturesaura/chunk/effect/PlantBoostEffect.java +++ b/src/main/java/de/ellpeck/naturesaura/chunk/effect/PlantBoostEffect.java @@ -17,15 +17,14 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; -import org.apache.commons.lang3.mutable.MutableInt; public class PlantBoostEffect implements IDrainSpotEffect { public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "plant_boost"); @Override - public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, MutableInt spot) { - if (spot.intValue() <= 0) + public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) { + if (spot <= 0) return; int aura = IAuraChunk.getAuraInArea(world, pos, 30); if (aura < 15000) diff --git a/src/main/java/de/ellpeck/naturesaura/chunk/effect/ReplenishingEffect.java b/src/main/java/de/ellpeck/naturesaura/chunk/effect/ReplenishingEffect.java index 7b25fc77..239561d6 100644 --- a/src/main/java/de/ellpeck/naturesaura/chunk/effect/ReplenishingEffect.java +++ b/src/main/java/de/ellpeck/naturesaura/chunk/effect/ReplenishingEffect.java @@ -12,7 +12,6 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; -import org.apache.commons.lang3.mutable.MutableInt; import java.util.ArrayList; import java.util.List; @@ -22,9 +21,8 @@ public class ReplenishingEffect implements IDrainSpotEffect { public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "replenishing"); @Override - public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, MutableInt spot) { - int amount = spot.intValue(); - if (amount < 0) { + public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) { + if (spot < 0) { List tiles = new ArrayList<>(); Helper.getTileEntitiesInArea(world, pos, 25, tile -> { if (tile.hasCapability(NaturesAuraAPI.capAuraContainer, null)) { @@ -41,12 +39,12 @@ public class ReplenishingEffect implements IDrainSpotEffect { ISpotDrainable tile = tiles.get(world.rand.nextInt(tiles.size())); if (!tile.isAcceptableType(type)) continue; - int drained = tile.drainAuraPassively(-amount, false); + int drained = tile.drainAuraPassively(-spot, false); if (drained <= 0) continue; auraChunk.storeAura(pos, drained); - amount += drained; - if (amount >= drained) { + spot += drained; + if (spot >= drained) { break; } } diff --git a/src/main/java/de/ellpeck/naturesaura/events/ClientEvents.java b/src/main/java/de/ellpeck/naturesaura/events/ClientEvents.java index 319f6267..1dce422d 100644 --- a/src/main/java/de/ellpeck/naturesaura/events/ClientEvents.java +++ b/src/main/java/de/ellpeck/naturesaura/events/ClientEvents.java @@ -57,9 +57,9 @@ public class ClientEvents { MutableInt spots = new MutableInt(); IAuraChunk.getSpotsInArea(mc.world, mc.player.getPosition(), 15, ((blockPos, drainSpot) -> { spots.increment(); - amount.add(drainSpot.intValue()); + amount.add(drainSpot); if (mc.player.isSneaking()) - left.add(prefix + drainSpot.intValue() + " @ " + blockPos.getX() + " " + blockPos.getY() + " " + blockPos.getZ()); + left.add(prefix + drainSpot + " @ " + blockPos.getX() + " " + blockPos.getY() + " " + blockPos.getZ()); })); left.add(prefix + "Total: " + amount.intValue() + " in " + spots.intValue() + " spots"); left.add(prefix + "Type: " + IAuraType.forWorld(mc.world).getName());