Fixed double chests not rolling back correctly when each half is in a separate chunk

This commit is contained in:
Intelli 2021-07-25 21:08:14 -06:00
parent 5d6388fff7
commit e178ed91ca
2 changed files with 80 additions and 78 deletions

View File

@ -1041,8 +1041,11 @@ public class Rollback extends Queue {
else if (rowType != changeType && (BlockGroup.CONTAINERS.contains(rowType) || BlockGroup.CONTAINERS.contains(changeType))) {
block.setType(Material.AIR); // Clear existing container to prevent errors
boolean update = (blockData instanceof Chest);
Util.setTypeAndData(block, rowType, blockData, update);
boolean isChest = (blockData instanceof Chest);
Util.setTypeAndData(block, rowType, blockData, (isChest));
if (isChest) {
ChestTool.updateDoubleChest(block, blockData, false);
}
if (countBlock) {
blockCount1++;
@ -1050,7 +1053,7 @@ public class Rollback extends Queue {
}
else if (BlockGroup.UPDATE_STATE.contains(rowType) || rowType.name().contains("CANDLE")) {
Util.setTypeAndData(block, rowType, blockData, true);
ChestTool.updateDoubleChest(block, blockData);
ChestTool.updateDoubleChest(block, blockData, true);
if (countBlock) {
blockCount1++;
}

View File

@ -3,93 +3,92 @@ package net.coreprotect.utility;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Directional;
import org.bukkit.block.data.type.Chest;
import org.bukkit.inventory.DoubleChestInventory;
import org.bukkit.block.data.type.Chest.Type;
import net.coreprotect.CoreProtect;
public class ChestTool {
public static void updateDoubleChest(Block block, BlockData blockData) {
try {
// modifying existing container, trigger physics update on both sides of double chest
if (blockData != null && blockData instanceof Chest) {
int chestType = 0;
switch (((Chest) blockData).getType()) {
case LEFT:
chestType = 1;
break;
case RIGHT:
chestType = 2;
break;
default:
break;
}
private ChestTool() {
throw new IllegalStateException("Utility class");
}
if (chestType > 0) {
// check that not already a double chest
BlockState blockState = block.getState();
if (blockState instanceof org.bukkit.block.Chest) {
org.bukkit.block.Chest chest = (org.bukkit.block.Chest) blockState;
if (chest.getInventory() instanceof DoubleChestInventory) {
return;
}
}
public static void updateDoubleChest(Block block, BlockData blockData, boolean forceValidation) {
// modifying container, trigger physics update on both sides of double chest
if (!(blockData instanceof Chest) || ((Chest) blockData).getType() == Type.SINGLE) {
return;
}
Directional directional = (Directional) blockData;
BlockFace blockFace = directional.getFacing();
BlockFace newFace = null;
if (chestType == 1) {
switch (blockFace) {
case NORTH:
newFace = BlockFace.EAST;
break;
case WEST:
newFace = BlockFace.NORTH;
break;
case EAST:
newFace = BlockFace.SOUTH;
break;
case SOUTH:
newFace = BlockFace.WEST;
break;
default:
break;
}
}
else if (chestType == 2) {
switch (blockFace) {
case NORTH:
newFace = BlockFace.WEST;
break;
case WEST:
newFace = BlockFace.SOUTH;
break;
case EAST:
newFace = BlockFace.NORTH;
break;
case SOUTH:
newFace = BlockFace.EAST;
break;
default:
break;
}
}
Directional directional = (Directional) blockData;
BlockFace blockFace = directional.getFacing();
BlockFace newFace = null;
if (newFace != null) {
Block relativeBlock = block.getRelative(newFace);
String relativeBlockData = relativeBlock.getBlockData().getAsString();
String newChestType = (chestType == 1) ? "type=right" : "type=left";
relativeBlockData = relativeBlockData.replace("type=single", newChestType);
relativeBlock.setBlockData(Bukkit.createBlockData(relativeBlockData), true);
}
}
Type chestType = ((Chest) blockData).getType();
if (chestType == Type.LEFT) {
switch (blockFace) {
case NORTH:
newFace = BlockFace.EAST;
break;
case WEST:
newFace = BlockFace.NORTH;
break;
case EAST:
newFace = BlockFace.SOUTH;
break;
case SOUTH:
newFace = BlockFace.WEST;
break;
default:
break;
}
}
catch (Exception e) {
e.printStackTrace();
else if (chestType == Type.RIGHT) {
switch (blockFace) {
case NORTH:
newFace = BlockFace.WEST;
break;
case WEST:
newFace = BlockFace.SOUTH;
break;
case EAST:
newFace = BlockFace.NORTH;
break;
case SOUTH:
newFace = BlockFace.EAST;
break;
default:
break;
}
}
if (newFace == null) {
return;
}
Type newType = (chestType == Type.LEFT) ? Type.RIGHT : Type.LEFT;
Block relativeBlock = block.getRelative(newFace);
if (!forceValidation && (relativeBlock.getBlockData() instanceof Chest) && ((Chest) relativeBlock.getBlockData()).getType() == newType) {
return;
}
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> {
try {
BlockData relativeBlockData = relativeBlock.getBlockData();
if (!blockData.getAsString().equals(block.getBlockData().getAsString()) || !(relativeBlockData instanceof Chest) || ((Chest) relativeBlockData).getType() == newType) {
return;
}
Chest chestData = (Chest) blockData;
chestData.setType(newType);
relativeBlock.setBlockData(chestData, true);
}
catch (Exception e) {
e.printStackTrace();
}
}, 2);
}
}