From f253f8163b12971d2fa1e63081c4e5472ab6f680 Mon Sep 17 00:00:00 2001 From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> Date: Mon, 26 May 2025 14:12:49 +0800 Subject: [PATCH] Add back Rail Optimization: optimized PoweredRailBlock logic --- build-data/leaf.at | 1 + ...ion-optimized-PoweredRailBlock-logic.patch | 405 ------------------ ...0007-Purpur-Server-Minecraft-Changes.patch | 4 +- ...ion-optimized-PoweredRailBlock-logic.patch | 30 ++ .../modules/opt/OptimizedPoweredRails.java | 18 + .../leaf/optimize/OptimizedPoweredRails.java | 333 ++++++++++++++ 6 files changed, 384 insertions(+), 407 deletions(-) delete mode 100644 leaf-archived-patches/work/server/0024-Rail-Optimization-optimized-PoweredRailBlock-logic.patch create mode 100644 leaf-server/minecraft-patches/features/0183-Rail-Optimization-optimized-PoweredRailBlock-logic.patch create mode 100644 leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizedPoweredRails.java create mode 100644 leaf-server/src/main/java/org/dreeam/leaf/optimize/OptimizedPoweredRails.java diff --git a/build-data/leaf.at b/build-data/leaf.at index b04d590a..5889428b 100644 --- a/build-data/leaf.at +++ b/build-data/leaf.at @@ -14,6 +14,7 @@ public net.minecraft.world.entity.decoration.ArmorStand noTickEquipmentDirty public net.minecraft.world.entity.monster.Shulker MAX_SCALE public net.minecraft.world.entity.player.Player canGlide()Z public net.minecraft.world.item.CrossbowItem getShotPitch(Lnet/minecraft/util/RandomSource;I)F +public net.minecraft.world.level.block.PoweredRailBlock findPoweredRailSignal(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;ZI)Z public net.minecraft.world.level.block.entity.FuelValues values public net.minecraft.world.level.chunk.storage.RegionFile getOversizedData(II)Lnet/minecraft/nbt/CompoundTag; public net.minecraft.world.level.chunk.storage.RegionFile isOversized(II)Z diff --git a/leaf-archived-patches/work/server/0024-Rail-Optimization-optimized-PoweredRailBlock-logic.patch b/leaf-archived-patches/work/server/0024-Rail-Optimization-optimized-PoweredRailBlock-logic.patch deleted file mode 100644 index e0f434ec..00000000 --- a/leaf-archived-patches/work/server/0024-Rail-Optimization-optimized-PoweredRailBlock-logic.patch +++ /dev/null @@ -1,405 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> -Date: Sat, 17 Feb 2024 17:57:08 -0500 -Subject: [PATCH] Rail Optimization: optimized PoweredRailBlock logic - -Original project: https://github.com/FxMorin/RailOptimization - -Full Rewrite of the powered rail iteration logic -that makes powered/activator rails turning on/off up to 4x faster. -This rewrite brings a massive performance boost while keeping the vanilla order. This is achieved by running all the -powered rail logic from a single rail instead of each block iterating separately. Which was not only very -expensive but also completely unnecessary and with a lot of massive overhead - -diff --git a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java -index bd14c08defe8afc5ceca59d16a5b1dbad178f594..b37ab12d4c51aca1576a14147a959188031d0fd7 100644 ---- a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java -@@ -29,7 +29,7 @@ public class PoweredRailBlock extends BaseRailBlock { - this.registerDefaultState((BlockState) ((BlockState) ((BlockState) ((BlockState) this.stateDefinition.any()).setValue(PoweredRailBlock.SHAPE, RailShape.NORTH_SOUTH)).setValue(PoweredRailBlock.POWERED, false)).setValue(PoweredRailBlock.WATERLOGGED, false)); - } - -- protected boolean findPoweredRailSignal(Level world, BlockPos pos, BlockState state, boolean flag, int distance) { -+ public boolean findPoweredRailSignal(Level world, BlockPos pos, BlockState state, boolean flag, int distance) { // Leaf - Rail Optimization - protected -> public - if (distance >= world.purpurConfig.railActivationRange) { // Purpur - return false; - } else { -@@ -117,6 +117,12 @@ public class PoweredRailBlock extends BaseRailBlock { - - @Override - protected void updateState(BlockState state, Level world, BlockPos pos, Block neighbor) { -+ // Leaf start - Rail Optimization -+ if (org.dreeam.leaf.config.modules.opt.OptimizedPoweredRails.enabled) { -+ org.dreeam.leaf.optimize.OptimizedPoweredRails.customUpdateState(this, state, world, pos); -+ return; -+ } -+ // Leaf end - Rail Optimization - boolean flag = (Boolean) state.getValue(PoweredRailBlock.POWERED); - boolean flag1 = world.hasNeighborSignal(pos) || this.findPoweredRailSignal(world, pos, state, true, 0) || this.findPoweredRailSignal(world, pos, state, false, 0); - -diff --git a/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizedPoweredRails.java b/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizedPoweredRails.java -new file mode 100644 -index 0000000000000000000000000000000000000000..ded3c385fcfc6c35086f76bed1b2223a6a29a43e ---- /dev/null -+++ b/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizedPoweredRails.java -@@ -0,0 +1,18 @@ -+package org.dreeam.leaf.config.modules.opt; -+ -+import org.dreeam.leaf.config.ConfigModules; -+import org.dreeam.leaf.config.EnumConfigCategory; -+ -+public class OptimizedPoweredRails extends ConfigModules { -+ -+ public String getBasePath() { -+ return EnumConfigCategory.PERF.getBaseKeyName() + ".optimized-powered-rails"; -+ } -+ -+ public static boolean enabled = true; -+ -+ @Override -+ public void onLoaded() { -+ enabled = config().getBoolean(getBasePath(), enabled); -+ } -+} -diff --git a/src/main/java/org/dreeam/leaf/optimize/OptimizedPoweredRails.java b/src/main/java/org/dreeam/leaf/optimize/OptimizedPoweredRails.java -new file mode 100644 -index 0000000000000000000000000000000000000000..9e8bc27585e204aa2df77a90418bbe9e00bcd040 ---- /dev/null -+++ b/src/main/java/org/dreeam/leaf/optimize/OptimizedPoweredRails.java -@@ -0,0 +1,335 @@ -+package org.dreeam.leaf.optimize; -+ -+import net.minecraft.core.BlockPos; -+import net.minecraft.core.Direction; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.block.Block; -+import net.minecraft.world.level.block.PoweredRailBlock; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.level.block.state.properties.RailShape; -+ -+import java.util.HashMap; -+ -+import static net.minecraft.world.level.block.Block.*; -+import static net.minecraft.world.level.block.PoweredRailBlock.POWERED; -+import static net.minecraft.world.level.block.PoweredRailBlock.SHAPE; -+ -+public class OptimizedPoweredRails { -+ -+ private static final Direction[] EAST_WEST_DIR = new Direction[]{Direction.WEST, Direction.EAST}; -+ private static final Direction[] NORTH_SOUTH_DIR = new Direction[]{Direction.SOUTH, Direction.NORTH}; -+ -+ private static final int UPDATE_FORCE_PLACE = UPDATE_MOVE_BY_PISTON | UPDATE_KNOWN_SHAPE | UPDATE_CLIENTS; -+ -+ public static int RAIL_POWER_LIMIT = 8; -+ -+ public static void giveShapeUpdate(Level level, BlockState state, BlockPos pos, BlockPos fromPos, Direction direction) { -+ BlockState oldState = level.getBlockState(pos); -+ Block.updateOrDestroy( -+ oldState, -+ oldState.updateShape(direction.getOpposite(), state, level, pos, fromPos), -+ level, -+ pos, -+ UPDATE_CLIENTS & -34, -+ 0 -+ ); -+ } -+ -+ public static void setRailPowerLimit(int powerLimit) { -+ RAIL_POWER_LIMIT = powerLimit; -+ } -+ -+ public static void customUpdateState(PoweredRailBlock self, BlockState state, Level level, BlockPos pos) { -+ boolean shouldBePowered = level.hasNeighborSignal(pos) || -+ self.findPoweredRailSignal(level, pos, state, true, 0) || -+ self.findPoweredRailSignal(level, pos, state, false, 0); -+ if (shouldBePowered != state.getValue(POWERED)) { -+ RailShape railShape = state.getValue(SHAPE); -+ if (railShape.isAscending()) { -+ level.setBlock(pos, state.setValue(POWERED, shouldBePowered), 3); -+ level.updateNeighborsAtExceptFromFacing(pos.below(), self, Direction.UP); -+ level.updateNeighborsAtExceptFromFacing(pos.above(), self, Direction.DOWN); //isAscending -+ } else if (shouldBePowered) { -+ powerLane(self, level, pos, state, railShape); -+ } else { -+ dePowerLane(self, level, pos, state, railShape); -+ } -+ } -+ } -+ -+ public static boolean findPoweredRailSignalFaster(PoweredRailBlock self, Level world, BlockPos pos, -+ boolean bl, int distance, RailShape shape, -+ HashMap checkedPos) { -+ BlockState blockState = world.getBlockState(pos); -+ boolean speedCheck = checkedPos.containsKey(pos) && checkedPos.get(pos); -+ if (speedCheck) { -+ return world.hasNeighborSignal(pos) || -+ findPoweredRailSignalFaster(self, world, pos, blockState, bl, distance + 1, checkedPos); -+ } else { -+ if (blockState.is(self)) { -+ RailShape railShape = blockState.getValue(SHAPE); -+ if (shape == RailShape.EAST_WEST && ( -+ railShape == RailShape.NORTH_SOUTH || -+ railShape == RailShape.ASCENDING_NORTH || -+ railShape == RailShape.ASCENDING_SOUTH -+ ) || shape == RailShape.NORTH_SOUTH && ( -+ railShape == RailShape.EAST_WEST || -+ railShape == RailShape.ASCENDING_EAST || -+ railShape == RailShape.ASCENDING_WEST -+ )) { -+ return false; -+ } else if (blockState.getValue(POWERED)) { -+ return world.hasNeighborSignal(pos) || -+ findPoweredRailSignalFaster(self, world, pos, blockState, bl, distance + 1, checkedPos); -+ } else { -+ return false; -+ } -+ } -+ return false; -+ } -+ } -+ -+ public static boolean findPoweredRailSignalFaster(PoweredRailBlock self, Level level, -+ BlockPos pos, BlockState state, boolean bl, int distance, -+ HashMap checkedPos) { -+ if (distance >= RAIL_POWER_LIMIT - 1) return false; -+ int i = pos.getX(); -+ int j = pos.getY(); -+ int k = pos.getZ(); -+ boolean bl2 = true; -+ RailShape railShape = state.getValue(SHAPE); -+ switch (railShape.ordinal()) { -+ case 0 -> { -+ if (bl) ++k; -+ else --k; -+ } -+ case 1 -> { -+ if (bl) --i; -+ else ++i; -+ } -+ case 2 -> { -+ if (bl) { -+ --i; -+ } else { -+ ++i; -+ ++j; -+ bl2 = false; -+ } -+ railShape = RailShape.EAST_WEST; -+ } -+ case 3 -> { -+ if (bl) { -+ --i; -+ ++j; -+ bl2 = false; -+ } else { -+ ++i; -+ } -+ railShape = RailShape.EAST_WEST; -+ } -+ case 4 -> { -+ if (bl) { -+ ++k; -+ } else { -+ --k; -+ ++j; -+ bl2 = false; -+ } -+ railShape = RailShape.NORTH_SOUTH; -+ } -+ case 5 -> { -+ if (bl) { -+ ++k; -+ ++j; -+ bl2 = false; -+ } else { -+ --k; -+ } -+ railShape = RailShape.NORTH_SOUTH; -+ } -+ } -+ return findPoweredRailSignalFaster( -+ self, level, new BlockPos(i, j, k), -+ bl, distance, railShape, checkedPos -+ ) || -+ (bl2 && findPoweredRailSignalFaster( -+ self, level, new BlockPos(i, j - 1, k), -+ bl, distance, railShape, checkedPos -+ )); -+ } -+ -+ public static void powerLane(PoweredRailBlock self, Level world, BlockPos pos, -+ BlockState mainState, RailShape railShape) { -+ world.setBlock(pos, mainState.setValue(POWERED, true), UPDATE_FORCE_PLACE); -+ HashMap checkedPos = new HashMap<>(); -+ checkedPos.put(pos, true); -+ int[] count = new int[2]; -+ if (railShape == RailShape.NORTH_SOUTH) { //Order: +z, -z -+ for (int i = 0; i < NORTH_SOUTH_DIR.length; ++i) { -+ setRailPositionsPower(self, world, pos, checkedPos, count, i, NORTH_SOUTH_DIR[i]); -+ } -+ updateRails(self, false, world, pos, mainState, count); -+ } else if (railShape == RailShape.EAST_WEST) { //Order: -x, +x -+ for (int i = 0; i < EAST_WEST_DIR.length; ++i) { -+ setRailPositionsPower(self, world, pos, checkedPos, count, i, EAST_WEST_DIR[i]); -+ } -+ updateRails(self, true, world, pos, mainState, count); -+ } -+ } -+ -+ public static void dePowerLane(PoweredRailBlock self, Level world, BlockPos pos, -+ BlockState mainState, RailShape railShape) { -+ world.setBlock(pos, mainState.setValue(POWERED, false), UPDATE_FORCE_PLACE); -+ int[] count = new int[2]; -+ if (railShape == RailShape.NORTH_SOUTH) { //Order: +z, -z -+ for (int i = 0; i < NORTH_SOUTH_DIR.length; ++i) { -+ setRailPositionsDePower(self, world, pos, count, i, NORTH_SOUTH_DIR[i]); -+ } -+ updateRails(self, false, world, pos, mainState, count); -+ } else if (railShape == RailShape.EAST_WEST) { //Order: -x, +x -+ for (int i = 0; i < EAST_WEST_DIR.length; ++i) { -+ setRailPositionsDePower(self, world, pos, count, i, EAST_WEST_DIR[i]); -+ } -+ updateRails(self, true, world, pos, mainState, count); -+ } -+ } -+ -+ private static void setRailPositionsPower(PoweredRailBlock self, Level world, BlockPos pos, -+ HashMap checkedPos, int[] count, int i, Direction dir) { -+ for (int z = 1; z < RAIL_POWER_LIMIT; z++) { -+ BlockPos newPos = pos.relative(dir, z); -+ BlockState state = world.getBlockState(newPos); -+ if (checkedPos.containsKey(newPos)) { -+ if (!checkedPos.get(newPos)) break; -+ count[i]++; -+ } else if (!state.is(self) || state.getValue(POWERED) || !( -+ world.hasNeighborSignal(newPos) || -+ findPoweredRailSignalFaster(self, world, newPos, state, true, 0, checkedPos) || -+ findPoweredRailSignalFaster(self, world, newPos, state, false, 0, checkedPos) -+ )) { -+ checkedPos.put(newPos, false); -+ break; -+ } else { -+ checkedPos.put(newPos, true); -+ world.setBlock(newPos, state.setValue(POWERED, true), UPDATE_FORCE_PLACE); -+ count[i]++; -+ } -+ } -+ } -+ -+ private static void setRailPositionsDePower(PoweredRailBlock self, Level world, BlockPos pos, -+ int[] count, int i, Direction dir) { -+ for (int z = 1; z < RAIL_POWER_LIMIT; z++) { -+ BlockPos newPos = pos.relative(dir, z); -+ BlockState state = world.getBlockState(newPos); -+ if (!state.is(self) || !state.getValue(POWERED) || world.hasNeighborSignal(newPos) || -+ self.findPoweredRailSignal(world, newPos, state, true, 0) || -+ self.findPoweredRailSignal(world, newPos, state, false, 0)) break; -+ world.setBlock(newPos, state.setValue(POWERED, false), UPDATE_FORCE_PLACE); -+ count[i]++; -+ } -+ } -+ -+ private static void shapeUpdateEnd(PoweredRailBlock self, Level world, BlockPos pos, BlockState mainState, -+ int endPos, Direction direction, int currentPos, BlockPos blockPos) { -+ if (currentPos == endPos) { -+ BlockPos newPos = pos.relative(direction, currentPos + 1); -+ OptimizedPoweredRails.giveShapeUpdate(world, mainState, newPos, pos, direction); -+ BlockState state = world.getBlockState(blockPos); -+ if (state.is(self) && state.getValue(SHAPE).isAscending()) -+ OptimizedPoweredRails.giveShapeUpdate(world, mainState, newPos.above(), pos, direction); -+ } -+ } -+ -+ private static void neighborUpdateEnd(PoweredRailBlock self, Level world, BlockPos pos, int endPos, -+ Direction direction, Block block, int currentPos, BlockPos blockPos) { -+ if (currentPos == endPos) { -+ BlockPos newPos = pos.relative(direction, currentPos + 1); -+ world.neighborChanged(newPos, block, pos); -+ BlockState state = world.getBlockState(blockPos); -+ if (state.is(self) && state.getValue(SHAPE).isAscending()) -+ world.neighborChanged(newPos.above(), block, blockPos); -+ } -+ } -+ -+ private static void updateRailsSectionEastWestShape(PoweredRailBlock self, Level world, BlockPos pos, -+ int c, BlockState mainState, Direction dir, -+ int[] count, int countAmt) { -+ BlockPos pos1 = pos.relative(dir, c); -+ if (c == 0 && count[1] == 0) -+ giveShapeUpdate(world, mainState, pos1.relative(dir.getOpposite()), pos, dir.getOpposite()); -+ shapeUpdateEnd(self, world, pos, mainState, countAmt, dir, c, pos1); -+ giveShapeUpdate(world, mainState, pos1.below(), pos, Direction.DOWN); -+ giveShapeUpdate(world, mainState, pos1.above(), pos, Direction.UP); -+ giveShapeUpdate(world, mainState, pos1.north(), pos, Direction.NORTH); -+ giveShapeUpdate(world, mainState, pos1.south(), pos, Direction.SOUTH); -+ } -+ -+ private static void updateRailsSectionNorthSouthShape(PoweredRailBlock self, Level world, BlockPos pos, -+ int c, BlockState mainState, Direction dir, -+ int[] count, int countAmt) { -+ BlockPos pos1 = pos.relative(dir, c); -+ giveShapeUpdate(world, mainState, pos1.west(), pos, Direction.WEST); -+ giveShapeUpdate(world, mainState, pos1.east(), pos, Direction.EAST); -+ giveShapeUpdate(world, mainState, pos1.below(), pos, Direction.DOWN); -+ giveShapeUpdate(world, mainState, pos1.above(), pos, Direction.UP); -+ shapeUpdateEnd(self, world, pos, mainState, countAmt, dir, c, pos1); -+ if (c == 0 && count[1] == 0) -+ giveShapeUpdate(world, mainState, pos1.relative(dir.getOpposite()), pos, dir.getOpposite()); -+ } -+ -+ private static void updateRails(PoweredRailBlock self, boolean eastWest, Level world, -+ BlockPos pos, BlockState mainState, int[] count) { -+ if (eastWest) { -+ for (int i = 0; i < EAST_WEST_DIR.length; ++i) { -+ int countAmt = count[i]; -+ if (i == 1 && countAmt == 0) continue; -+ Direction dir = EAST_WEST_DIR[i]; -+ Block block = mainState.getBlock(); -+ for (int c = countAmt; c >= i; c--) { -+ BlockPos p = pos.relative(dir, c); -+ if (c == 0 && count[1] == 0) world.neighborChanged(p.relative(dir.getOpposite()), block, pos); -+ neighborUpdateEnd(self, world, pos, countAmt, dir, block, c, p); -+ world.neighborChanged(p.below(), block, pos); -+ world.neighborChanged(p.above(), block, pos); -+ world.neighborChanged(p.north(), block, pos); -+ world.neighborChanged(p.south(), block, pos); -+ BlockPos pos2 = pos.relative(dir, c).below(); -+ world.neighborChanged(pos2.below(), block, pos); -+ world.neighborChanged(pos2.north(), block, pos); -+ world.neighborChanged(pos2.south(), block, pos); -+ if (c == countAmt) world.neighborChanged(pos.relative(dir, c + 1).below(), block, pos); -+ if (c == 0 && count[1] == 0) -+ world.neighborChanged(p.relative(dir.getOpposite()).below(), block, pos); -+ } -+ for (int c = countAmt; c >= i; c--) -+ updateRailsSectionEastWestShape(self, world, pos, c, mainState, dir, count, countAmt); -+ } -+ } else { -+ for (int i = 0; i < NORTH_SOUTH_DIR.length; ++i) { -+ int countAmt = count[i]; -+ if (i == 1 && countAmt == 0) continue; -+ Direction dir = NORTH_SOUTH_DIR[i]; -+ Block block = mainState.getBlock(); -+ for (int c = countAmt; c >= i; c--) { -+ BlockPos p = pos.relative(dir, c); -+ world.neighborChanged(p.west(), block, pos); -+ world.neighborChanged(p.east(), block, pos); -+ world.neighborChanged(p.below(), block, pos); -+ world.neighborChanged(p.above(), block, pos); -+ neighborUpdateEnd(self, world, pos, countAmt, dir, block, c, p); -+ if (c == 0 && count[1] == 0) world.neighborChanged(p.relative(dir.getOpposite()), block, pos); -+ BlockPos pos2 = pos.relative(dir, c).below(); -+ world.neighborChanged(pos2.west(), block, pos); -+ world.neighborChanged(pos2.east(), block, pos); -+ world.neighborChanged(pos2.below(), block, pos); -+ if (c == countAmt) world.neighborChanged(pos.relative(dir, c + 1).below(), block, pos); -+ if (c == 0 && count[1] == 0) -+ world.neighborChanged(p.relative(dir.getOpposite()).below(), block, pos); -+ } -+ for (int c = countAmt; c >= i; c--) -+ updateRailsSectionNorthSouthShape(self, world, pos, c, mainState, dir, count, countAmt); -+ } -+ } -+ } -+} -\ No newline at end of file diff --git a/leaf-server/minecraft-patches/features/0007-Purpur-Server-Minecraft-Changes.patch b/leaf-server/minecraft-patches/features/0007-Purpur-Server-Minecraft-Changes.patch index c4764b6e..86de64ae 100644 --- a/leaf-server/minecraft-patches/features/0007-Purpur-Server-Minecraft-Changes.patch +++ b/leaf-server/minecraft-patches/features/0007-Purpur-Server-Minecraft-Changes.patch @@ -15798,13 +15798,13 @@ index 9c0ded7ae7e3a520704033a866f80743ae85d772..4f3646961beb877520e257e11224c304 } // CraftBukkit end diff --git a/net/minecraft/world/level/block/PoweredRailBlock.java b/net/minecraft/world/level/block/PoweredRailBlock.java -index f33b53257a231dccf16740f1e78a3cdfa6e70726..4b3d00b085ea5d345b418815c9869f5f8c9fe558 100644 +index be3b5531cab74df8770ffa04ec4a4bae28cc57e6..e6674c37e09fe0ad2e971bd957666929492ba57e 100644 --- a/net/minecraft/world/level/block/PoweredRailBlock.java +++ b/net/minecraft/world/level/block/PoweredRailBlock.java @@ -34,7 +34,7 @@ public class PoweredRailBlock extends BaseRailBlock { } - protected boolean findPoweredRailSignal(Level level, BlockPos pos, BlockState state, boolean searchForward, int recursionCount) { + public boolean findPoweredRailSignal(Level level, BlockPos pos, BlockState state, boolean searchForward, int recursionCount) { - if (recursionCount >= 8) { + if (recursionCount >= level.purpurConfig.railActivationRange) { // Purpur - Config for powered rail activation distance return false; diff --git a/leaf-server/minecraft-patches/features/0183-Rail-Optimization-optimized-PoweredRailBlock-logic.patch b/leaf-server/minecraft-patches/features/0183-Rail-Optimization-optimized-PoweredRailBlock-logic.patch new file mode 100644 index 00000000..086df508 --- /dev/null +++ b/leaf-server/minecraft-patches/features/0183-Rail-Optimization-optimized-PoweredRailBlock-logic.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> +Date: Sat, 17 Feb 2024 17:57:08 -0500 +Subject: [PATCH] Rail Optimization: optimized PoweredRailBlock logic + +Original project: https://github.com/FxMorin/RailOptimization + +Full Rewrite of the powered rail iteration logic +that makes powered/activator rails turning on/off up to 4x faster. +This rewrite brings a massive performance boost while keeping the vanilla order. This is achieved by running all the +powered rail logic from a single rail instead of each block iterating separately. Which was not only very +expensive but also completely unnecessary and with a lot of massive overhead + +diff --git a/net/minecraft/world/level/block/PoweredRailBlock.java b/net/minecraft/world/level/block/PoweredRailBlock.java +index e6674c37e09fe0ad2e971bd957666929492ba57e..c93a7d166ac97bac981d906c6894606237107fe8 100644 +--- a/net/minecraft/world/level/block/PoweredRailBlock.java ++++ b/net/minecraft/world/level/block/PoweredRailBlock.java +@@ -128,6 +128,12 @@ public class PoweredRailBlock extends BaseRailBlock { + + @Override + protected void updateState(BlockState state, Level level, BlockPos pos, Block block) { ++ // Leaf start - Rail Optimization ++ if (org.dreeam.leaf.config.modules.opt.OptimizedPoweredRails.enabled) { ++ org.dreeam.leaf.optimize.OptimizedPoweredRails.updateState(this, state, level, pos); ++ return; ++ } ++ // Leaf end - Rail Optimization + boolean poweredValue = state.getValue(POWERED); + boolean flag = level.hasNeighborSignal(pos) + || this.findPoweredRailSignal(level, pos, state, true, 0) diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizedPoweredRails.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizedPoweredRails.java new file mode 100644 index 00000000..b71f3702 --- /dev/null +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizedPoweredRails.java @@ -0,0 +1,18 @@ +package org.dreeam.leaf.config.modules.opt; + +import org.dreeam.leaf.config.ConfigModules; +import org.dreeam.leaf.config.EnumConfigCategory; + +public class OptimizedPoweredRails extends ConfigModules { + + public String getBasePath() { + return EnumConfigCategory.PERF.getBaseKeyName() + ".optimized-powered-rails"; + } + + public static boolean enabled = false; + + @Override + public void onLoaded() { + enabled = config().getBoolean(getBasePath(), enabled); + } +} diff --git a/leaf-server/src/main/java/org/dreeam/leaf/optimize/OptimizedPoweredRails.java b/leaf-server/src/main/java/org/dreeam/leaf/optimize/OptimizedPoweredRails.java new file mode 100644 index 00000000..87b9a745 --- /dev/null +++ b/leaf-server/src/main/java/org/dreeam/leaf/optimize/OptimizedPoweredRails.java @@ -0,0 +1,333 @@ +package org.dreeam.leaf.optimize; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.PoweredRailBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.RailShape; + +import java.util.HashMap; + +import static net.minecraft.world.level.block.Block.*; +import static net.minecraft.world.level.block.PoweredRailBlock.POWERED; +import static net.minecraft.world.level.block.PoweredRailBlock.SHAPE; + +public class OptimizedPoweredRails { + + private static final Direction[] EAST_WEST_DIR = new Direction[]{Direction.WEST, Direction.EAST}; + private static final Direction[] NORTH_SOUTH_DIR = new Direction[]{Direction.SOUTH, Direction.NORTH}; + + private static final int UPDATE_FORCE_PLACE = UPDATE_MOVE_BY_PISTON | UPDATE_KNOWN_SHAPE | UPDATE_CLIENTS; + + private static int RAIL_POWER_LIMIT = 8; + + private static void giveShapeUpdate(Level level, BlockState state, BlockPos pos, BlockPos fromPos, Direction direction) { + BlockState oldState = level.getBlockState(pos); + Block.updateOrDestroy( + oldState, + oldState.updateShape(level, level, pos, direction.getOpposite(), fromPos, state, level.random), + level, + pos, + UPDATE_CLIENTS & -34, + 0 + ); + } + + public static int getRailPowerLimit() { + return RAIL_POWER_LIMIT; + } + + public static void setRailPowerLimit(int powerLimit) { + RAIL_POWER_LIMIT = powerLimit; + } + + public static void updateState(PoweredRailBlock self, BlockState state, Level level, BlockPos pos) { + boolean shouldBePowered = level.hasNeighborSignal(pos) || + self.findPoweredRailSignal(level, pos, state, true, 0) || + self.findPoweredRailSignal(level, pos, state, false, 0); + if (shouldBePowered != state.getValue(POWERED)) { + RailShape railShape = state.getValue(SHAPE); + if (railShape.isSlope()) { + level.setBlock(pos, state.setValue(POWERED, shouldBePowered), 3); + level.updateNeighborsAtExceptFromFacing(pos.below(), self, Direction.UP, null); + level.updateNeighborsAtExceptFromFacing(pos.above(), self, Direction.DOWN, null); // isSlope + } else if (shouldBePowered) { + powerLane(self, level, pos, state, railShape); + } else { + dePowerLane(self, level, pos, state, railShape); + } + } + } + + private static boolean findPoweredRailSignalFaster(PoweredRailBlock self, Level world, BlockPos pos, + boolean bl, int distance, RailShape shape, + HashMap checkedPos) { + BlockState blockState = world.getBlockState(pos); + boolean speedCheck = checkedPos.containsKey(pos) && checkedPos.get(pos); + if (speedCheck) { + return world.hasNeighborSignal(pos) || + findPoweredRailSignalFaster(self, world, pos, blockState, bl, distance + 1, checkedPos); + } else { + if (blockState.is(self)) { + RailShape railShape = blockState.getValue(SHAPE); + if (shape == RailShape.EAST_WEST && ( + railShape == RailShape.NORTH_SOUTH || + railShape == RailShape.ASCENDING_NORTH || + railShape == RailShape.ASCENDING_SOUTH + ) || shape == RailShape.NORTH_SOUTH && ( + railShape == RailShape.EAST_WEST || + railShape == RailShape.ASCENDING_EAST || + railShape == RailShape.ASCENDING_WEST + )) { + return false; + } else if (blockState.getValue(POWERED)) { + return world.hasNeighborSignal(pos) || + findPoweredRailSignalFaster(self, world, pos, blockState, bl, distance + 1, checkedPos); + } else { + return false; + } + } + return false; + } + } + + private static boolean findPoweredRailSignalFaster(PoweredRailBlock self, Level level, + BlockPos pos, BlockState state, boolean bl, int distance, + HashMap checkedPos) { + if (distance >= RAIL_POWER_LIMIT - 1) return false; + int i = pos.getX(); + int j = pos.getY(); + int k = pos.getZ(); + boolean bl2 = true; + RailShape railShape = state.getValue(SHAPE); + switch (railShape.ordinal()) { + case 0 -> { + if (bl) ++k; + else --k; + } + case 1 -> { + if (bl) --i; + else ++i; + } + case 2 -> { + if (bl) { + --i; + } else { + ++i; + ++j; + bl2 = false; + } + railShape = RailShape.EAST_WEST; + } + case 3 -> { + if (bl) { + --i; + ++j; + bl2 = false; + } else { + ++i; + } + railShape = RailShape.EAST_WEST; + } + case 4 -> { + if (bl) { + ++k; + } else { + --k; + ++j; + bl2 = false; + } + railShape = RailShape.NORTH_SOUTH; + } + case 5 -> { + if (bl) { + ++k; + ++j; + bl2 = false; + } else { + --k; + } + railShape = RailShape.NORTH_SOUTH; + } + } + return findPoweredRailSignalFaster( + self, level, new BlockPos(i, j, k), + bl, distance, railShape, checkedPos + ) || + (bl2 && findPoweredRailSignalFaster( + self, level, new BlockPos(i, j - 1, k), + bl, distance, railShape, checkedPos + )); + } + + private static void powerLane(PoweredRailBlock self, Level world, BlockPos pos, + BlockState mainState, RailShape railShape) { + world.setBlock(pos, mainState.setValue(POWERED, true), UPDATE_FORCE_PLACE); + HashMap checkedPos = new HashMap<>(); + checkedPos.put(pos, true); + int[] count = new int[2]; + if (railShape == RailShape.NORTH_SOUTH) { // Order: +z, -z + for (int i = 0; i < NORTH_SOUTH_DIR.length; ++i) { + setRailPositionsPower(self, world, pos, checkedPos, count, i, NORTH_SOUTH_DIR[i]); + } + updateRails(self, false, world, pos, mainState, count); + } else if (railShape == RailShape.EAST_WEST) { // Order: -x, +x + for (int i = 0; i < EAST_WEST_DIR.length; ++i) { + setRailPositionsPower(self, world, pos, checkedPos, count, i, EAST_WEST_DIR[i]); + } + updateRails(self, true, world, pos, mainState, count); + } + } + + private static void dePowerLane(PoweredRailBlock self, Level world, BlockPos pos, + BlockState mainState, RailShape railShape) { + world.setBlock(pos, mainState.setValue(POWERED, false), UPDATE_FORCE_PLACE); + int[] count = new int[2]; + if (railShape == RailShape.NORTH_SOUTH) { // Order: +z, -z + for (int i = 0; i < NORTH_SOUTH_DIR.length; ++i) { + setRailPositionsDePower(self, world, pos, count, i, NORTH_SOUTH_DIR[i]); + } + updateRails(self, false, world, pos, mainState, count); + } else if (railShape == RailShape.EAST_WEST) { // Order: -x, +x + for (int i = 0; i < EAST_WEST_DIR.length; ++i) { + setRailPositionsDePower(self, world, pos, count, i, EAST_WEST_DIR[i]); + } + updateRails(self, true, world, pos, mainState, count); + } + } + + private static void setRailPositionsPower(PoweredRailBlock self, Level world, BlockPos pos, + HashMap checkedPos, int[] count, int i, Direction dir) { + for (int z = 1; z < RAIL_POWER_LIMIT; z++) { + BlockPos newPos = pos.relative(dir, z); + BlockState state = world.getBlockState(newPos); + if (checkedPos.containsKey(newPos)) { + if (!checkedPos.get(newPos)) break; + count[i]++; + } else if (!state.is(self) || state.getValue(POWERED) || !( + world.hasNeighborSignal(newPos) || + findPoweredRailSignalFaster(self, world, newPos, state, true, 0, checkedPos) || + findPoweredRailSignalFaster(self, world, newPos, state, false, 0, checkedPos) + )) { + checkedPos.put(newPos, false); + break; + } else { + checkedPos.put(newPos, true); + world.setBlock(newPos, state.setValue(POWERED, true), UPDATE_FORCE_PLACE); + count[i]++; + } + } + } + + private static void setRailPositionsDePower(PoweredRailBlock self, Level world, BlockPos pos, + int[] count, int i, Direction dir) { + for (int z = 1; z < RAIL_POWER_LIMIT; z++) { + BlockPos newPos = pos.relative(dir, z); + BlockState state = world.getBlockState(newPos); + if (!state.is(self) || !state.getValue(POWERED) || world.hasNeighborSignal(newPos) || + self.findPoweredRailSignal(world, newPos, state, true, 0) || + self.findPoweredRailSignal(world, newPos, state, false, 0)) break; + world.setBlock(newPos, state.setValue(POWERED, false), UPDATE_FORCE_PLACE); + count[i]++; + } + } + + private static void shapeUpdateEnd(PoweredRailBlock self, Level world, BlockPos pos, BlockState mainState, + int endPos, Direction direction, int currentPos, BlockPos blockPos) { + if (currentPos == endPos) { + BlockPos newPos = pos.relative(direction, currentPos + 1); + giveShapeUpdate(world, mainState, newPos, pos, direction); + BlockState state = world.getBlockState(blockPos); + if (state.is(self) && state.getValue(SHAPE).isSlope()) giveShapeUpdate(world, mainState, newPos.above(), pos, direction); + } + } + + private static void neighborUpdateEnd(PoweredRailBlock self, Level world, BlockPos pos, int endPos, + Direction direction, Block block, int currentPos, BlockPos blockPos) { + if (currentPos == endPos) { + BlockPos newPos = pos.relative(direction, currentPos + 1); + world.neighborChanged(newPos, block, null); + BlockState state = world.getBlockState(blockPos); + if (state.is(self) && state.getValue(SHAPE).isSlope()) world.neighborChanged(newPos.above(), block, null); + } + } + + private static void updateRailsSectionEastWestShape(PoweredRailBlock self, Level world, BlockPos pos, + int c, BlockState mainState, Direction dir, + int[] count, int countAmt) { + BlockPos pos1 = pos.relative(dir, c); + if (c == 0 && count[1] == 0) giveShapeUpdate(world, mainState, pos1.relative(dir.getOpposite()), pos, dir.getOpposite()); + shapeUpdateEnd(self, world, pos, mainState, countAmt, dir, c, pos1); + giveShapeUpdate(world, mainState, pos1.below(), pos, Direction.DOWN); + giveShapeUpdate(world, mainState, pos1.above(), pos, Direction.UP); + giveShapeUpdate(world, mainState, pos1.north(), pos, Direction.NORTH); + giveShapeUpdate(world, mainState, pos1.south(), pos, Direction.SOUTH); + } + + private static void updateRailsSectionNorthSouthShape(PoweredRailBlock self, Level world, BlockPos pos, + int c, BlockState mainState, Direction dir, + int[] count, int countAmt) { + BlockPos pos1 = pos.relative(dir, c); + giveShapeUpdate(world, mainState, pos1.west(), pos, Direction.WEST); + giveShapeUpdate(world, mainState, pos1.east(), pos, Direction.EAST); + giveShapeUpdate(world, mainState, pos1.below(), pos, Direction.DOWN); + giveShapeUpdate(world, mainState, pos1.above(), pos, Direction.UP); + shapeUpdateEnd(self, world, pos, mainState, countAmt, dir, c, pos1); + if (c == 0 && count[1] == 0) giveShapeUpdate(world, mainState, pos1.relative(dir.getOpposite()), pos, dir.getOpposite()); + } + + private static void updateRails(PoweredRailBlock self, boolean eastWest, Level world, + BlockPos pos, BlockState mainState, int[] count) { + if (eastWest) { + for (int i = 0; i < EAST_WEST_DIR.length; ++i) { + int countAmt = count[i]; + if (i == 1 && countAmt == 0) continue; + Direction dir = EAST_WEST_DIR[i]; + Block block = mainState.getBlock(); + for (int c = countAmt; c >= i; c--) { + BlockPos p = pos.relative(dir, c); + if (c == 0 && count[1] == 0) world.neighborChanged(p.relative(dir.getOpposite()), block, null); + neighborUpdateEnd(self, world, pos, countAmt, dir, block, c, p); + world.neighborChanged(p.below(), block, null); + world.neighborChanged(p.above(), block, null); + world.neighborChanged(p.north(), block, null); + world.neighborChanged(p.south(), block, null); + BlockPos pos2 = pos.relative(dir, c).below(); + world.neighborChanged(pos2.below(), block, null); + world.neighborChanged(pos2.north(), block, null); + world.neighborChanged(pos2.south(), block, null); + if (c == countAmt) world.neighborChanged(pos.relative(dir, c + 1).below(), block, null); + if (c == 0 && count[1] == 0) world.neighborChanged(p.relative(dir.getOpposite()).below(), block, null); + } + for (int c = countAmt; c >= i; c--) + updateRailsSectionEastWestShape(self, world, pos, c, mainState, dir, count, countAmt); + } + } else { + for (int i = 0; i < NORTH_SOUTH_DIR.length; ++i) { + int countAmt = count[i]; + if (i == 1 && countAmt == 0) continue; + Direction dir = NORTH_SOUTH_DIR[i]; + Block block = mainState.getBlock(); + for (int c = countAmt; c >= i; c--) { + BlockPos p = pos.relative(dir, c); + world.neighborChanged(p.west(), block, null); + world.neighborChanged(p.east(), block, null); + world.neighborChanged(p.below(), block, null); + world.neighborChanged(p.above(), block, null); + neighborUpdateEnd(self, world, pos, countAmt, dir, block, c, p); + if (c == 0 && count[1] == 0) world.neighborChanged(p.relative(dir.getOpposite()), block, null); + BlockPos pos2 = pos.relative(dir, c).below(); + world.neighborChanged(pos2.west(), block, null); + world.neighborChanged(pos2.east(), block, null); + world.neighborChanged(pos2.below(), block, null); + if (c == countAmt) world.neighborChanged(pos.relative(dir, c + 1).below(), block, null); + if (c == 0 && count[1] == 0) world.neighborChanged(p.relative(dir.getOpposite()).below(), block, null); + } + for (int c = countAmt; c >= i; c--) + updateRailsSectionNorthSouthShape(self, world, pos, c, mainState, dir, count, countAmt); + } + } + } +}