From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martijn Muijsers Date: Thu, 24 Nov 2022 23:03:52 +0100 Subject: [PATCH] Reduce hopper item checks License: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html) Gale - https://galemc.org This patch is based on the following patch: "Improve Hopper Performance" By: Aikar As part of: EmpireCraft (https://github.com/starlis/empirecraft) Licensed under: MIT (https://opensource.org/licenses/MIT) * EmpireCraft description * Only do an item "suck in" action once per second diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java index 6c0ebfb2be4e8b884456a2aa3d5fdc87e45a0e3c..bf2f81232ac40218c6d0241b7a0a26cb2272e06b 100644 --- a/net/minecraft/world/entity/item/ItemEntity.java +++ b/net/minecraft/world/entity/item/ItemEntity.java @@ -150,7 +150,13 @@ public class ItemEntity extends Entity implements TraceableEntity { } // CraftBukkit end this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + return; // Gale - EMC - reduce hopper item checks } + // Gale start - EMC - reduce hopper item checks + if (level().galeConfig().smallOptimizations.reducedIntervals.checkNearbyItem.hopper.minecart.temporaryImmunity.checkForMinecartNearItemWhileInactive) { + this.markNearbyHopperCartsAsImmune(); + } + // Gale end - EMC - reduce hopper item checks } // Paper end - EAR 2 @@ -234,9 +240,31 @@ public class ItemEntity extends Entity implements TraceableEntity { } // CraftBukkit end this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + return; // Gale - EMC - reduce hopper item checks + } + this.markNearbyHopperCartsAsImmune(); // Gale - EMC - reduce hopper item checks + } + } + + // Gale start - EMC - reduce hopper item checks + private void markNearbyHopperCartsAsImmune() { + var config = this.level().galeConfig().smallOptimizations.reducedIntervals.checkNearbyItem.hopper.minecart; + + // No need to mark hopper minecarts as immune if they can pull every tick anyway + if (config.interval <= 1) { + return; + } + + if (config.temporaryImmunity.duration > 0 && this.isAlive() && this.onGround && !this.isRemoved() && (config.temporaryImmunity.nearbyItemMaxAge == -1 || this.age <= config.temporaryImmunity.nearbyItemMaxAge) && this.age % Math.max(1, config.temporaryImmunity.checkForMinecartNearItemInterval) == 0 && config.temporaryImmunity.maxItemHorizontalDistance >= 0 && config.temporaryImmunity.maxItemVerticalDistance >= 0) { + net.minecraft.world.phys.AABB aabb = this.getBoundingBox().inflate(config.temporaryImmunity.maxItemHorizontalDistance, config.temporaryImmunity.maxItemVerticalDistance, config.temporaryImmunity.maxItemHorizontalDistance); + for (Entity entity : this.level().getEntities(this, aabb)) { + if (entity instanceof net.minecraft.world.entity.vehicle.MinecartHopper hopper) { + hopper.pickupImmunity = net.minecraft.server.MinecraftServer.currentTick + config.temporaryImmunity.duration; + } } } } + // Gale end - EMC - reduce hopper item checks @Override public BlockPos getBlockPosBelowThatAffectsMyMovement() { diff --git a/net/minecraft/world/entity/vehicle/MinecartHopper.java b/net/minecraft/world/entity/vehicle/MinecartHopper.java index a56d9cdeb6589a053ffaaf2cd599a98ae0a0989a..df5eda70d1d2eafcd32606fb93bb62409e5a8943 100644 --- a/net/minecraft/world/entity/vehicle/MinecartHopper.java +++ b/net/minecraft/world/entity/vehicle/MinecartHopper.java @@ -22,6 +22,7 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper private static final boolean DEFAULT_ENABLED = true; private boolean enabled = true; private boolean consumedItemThisFrame = false; + public int pickupImmunity = 0; // Gale - EMC - reduce hopper item checks public MinecartHopper(EntityType entityType, Level level) { super(entityType, level); @@ -150,4 +151,12 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper } // Paper end + // Gale start - EMC - reduce hopper item checks + private long tickAttempts = 0; + @Override + public long getAndIncrementAttemptCounter() { + return tickAttempts++; + } + // Gale end EMC - - reduce hopper item checks + } diff --git a/net/minecraft/world/level/block/entity/Hopper.java b/net/minecraft/world/level/block/entity/Hopper.java index 484c2ba2752fbf3ad929e46c2f078e906f6f0637..6ced5a7e27703a7cf5a7495dc3a1a290ce0d18eb 100644 --- a/net/minecraft/world/level/block/entity/Hopper.java +++ b/net/minecraft/world/level/block/entity/Hopper.java @@ -11,6 +11,8 @@ public interface Hopper extends Container { return SUCK_AABB; } + long getAndIncrementAttemptCounter(); // Gale - EMC - reduce hopper item checks + double getLevelX(); double getLevelY(); diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java index 15d4f60942c0cc612c1468b4c0fda886867a67cb..c2c7832fbb207ecfd23c7a086ef72db9648f48f9 100644 --- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java @@ -544,7 +544,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen return false; } else { boolean flag = hopper.isGridAligned() && blockState.isCollisionShapeFullBlock(level, blockPos) && !blockState.is(BlockTags.DOES_NOT_BLOCK_HOPPERS); - if (!flag) { + if (!flag && shouldSuckIn(level, hopper)) { // Gale - EMC - reduce hopper item checks for (ItemEntity itemEntity : getItemsAtAndAbove(level, hopper)) { if (addItem(hopper, itemEntity)) { return true; @@ -820,6 +820,34 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen return stack1.getCount() < stack1.getMaxStackSize() && ItemStack.isSameItemSameComponents(stack1, stack2); // Paper - Perf: Optimize Hoppers; used to return true for full itemstacks?! } + // Gale start - EMC - reduce hopper item checks + private long tickAttempts = 0; + @Override + public long getAndIncrementAttemptCounter() { + return tickAttempts++; + } + private static boolean shouldSuckIn(Level level, Hopper hopper) { + int suckInterval; + if (hopper instanceof net.minecraft.world.entity.vehicle.MinecartHopper minecartHopper) { + if (minecartHopper.pickupImmunity > net.minecraft.server.MinecraftServer.currentTick) { + return true; + } + + suckInterval = level.galeConfig().smallOptimizations.reducedIntervals.checkNearbyItem.hopper.minecart.interval; + } else { + suckInterval = level.galeConfig().smallOptimizations.reducedIntervals.checkNearbyItem.hopper.interval; + } + + if (suckInterval <= 1) { + return true; + } + + final int hopperId = (int) hopper.getLevelX() + (int) hopper.getLevelY() + (int) hopper.getLevelZ(); + + return (hopper.getAndIncrementAttemptCounter() + hopperId) % suckInterval == 0; + } + // Gale end - EMC - reduce hopper item checks + @Override public double getLevelX() { return this.worldPosition.getX() + 0.5;