diff --git a/pom.xml b/pom.xml
index e7c9d2d..3194a15 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
de.diddiz
logblock
- 1.16.5.2-SNAPSHOT
+ 1.17.0.0-SNAPSHOT
jar
LogBlock
@@ -42,13 +42,13 @@
org.spigotmc
spigot-api
- 1.16.5-R0.1-SNAPSHOT
+ 1.17-R0.1-SNAPSHOT
provided
com.sk89q.worldedit
worldedit-bukkit
- 7.1.0-SNAPSHOT
+ 7.2.0-SNAPSHOT
provided
diff --git a/src/main/java/de/diddiz/LogBlock/Consumer.java b/src/main/java/de/diddiz/LogBlock/Consumer.java
index 572fcb5..0e696b9 100644
--- a/src/main/java/de/diddiz/LogBlock/Consumer.java
+++ b/src/main/java/de/diddiz/LogBlock/Consumer.java
@@ -35,6 +35,7 @@ import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
+import org.bukkit.block.data.Waterlogged;
import org.bukkit.block.data.type.Sign;
import org.bukkit.block.data.type.WallSign;
import org.bukkit.configuration.file.YamlConfiguration;
@@ -52,6 +53,7 @@ import de.diddiz.LogBlock.blockstate.BlockStateCodecSign;
import de.diddiz.LogBlock.blockstate.BlockStateCodecs;
import de.diddiz.LogBlock.config.Config;
import de.diddiz.LogBlock.events.BlockChangePreLogEvent;
+import de.diddiz.util.BukkitUtils;
import de.diddiz.util.Utils;
public class Consumer extends Thread {
@@ -693,6 +695,9 @@ public class Consumer extends Thread {
if (typeBefore == null || typeBefore.getMaterial() == Material.CAVE_AIR || typeBefore.getMaterial() == Material.VOID_AIR) {
typeBefore = Bukkit.createBlockData(Material.AIR);
}
+ if (typeAfter == null && ((typeBefore instanceof Waterlogged && ((Waterlogged) typeBefore).isWaterlogged()) || BukkitUtils.isAlwaysWaterlogged(typeBefore.getMaterial()))) {
+ typeAfter = Bukkit.createBlockData(Material.WATER);
+ }
if (typeAfter == null || typeAfter.getMaterial() == Material.CAVE_AIR || typeAfter.getMaterial() == Material.VOID_AIR) {
typeAfter = Bukkit.createBlockData(Material.AIR);
}
diff --git a/src/main/java/de/diddiz/LogBlock/LogBlock.java b/src/main/java/de/diddiz/LogBlock/LogBlock.java
index e45b204..38e9d42 100644
--- a/src/main/java/de/diddiz/LogBlock/LogBlock.java
+++ b/src/main/java/de/diddiz/LogBlock/LogBlock.java
@@ -192,7 +192,7 @@ public class LogBlock extends JavaPlugin {
if (isLogging(Logging.NATURALSTRUCTUREGROW) || isLogging(Logging.BONEMEALSTRUCTUREGROW)) {
pm.registerEvents(new StructureGrowLogging(this), this);
}
- if (isLogging(Logging.GRASSGROWTH) || isLogging(Logging.MYCELIUMSPREAD) || isLogging(Logging.VINEGROWTH) || isLogging(Logging.MUSHROOMSPREAD)) {
+ if (isLogging(Logging.GRASSGROWTH) || isLogging(Logging.MYCELIUMSPREAD) || isLogging(Logging.VINEGROWTH) || isLogging(Logging.MUSHROOMSPREAD) || isLogging(Logging.BAMBOOGROWTH) || isLogging(Logging.DRIPSTONEGROWTH)) {
pm.registerEvents(new BlockSpreadLogging(this), this);
}
if (isLogging(Logging.DRAGONEGGTELEPORT)) {
@@ -201,6 +201,9 @@ public class LogBlock extends JavaPlugin {
if (isLogging(Logging.LECTERNBOOKCHANGE)) {
pm.registerEvents(new LecternLogging(this), this);
}
+ if (isLogging(Logging.OXIDIZATION)) {
+ pm.registerEvents(new OxidizationLogging(this), this);
+ }
if (Config.isLoggingAnyEntities()) {
if (!WorldEditHelper.hasFullWorldEdit()) {
getLogger().severe("No compatible WorldEdit found, entity logging will not work!");
diff --git a/src/main/java/de/diddiz/LogBlock/Logging.java b/src/main/java/de/diddiz/LogBlock/Logging.java
index ba6d7c0..62eef5e 100644
--- a/src/main/java/de/diddiz/LogBlock/Logging.java
+++ b/src/main/java/de/diddiz/LogBlock/Logging.java
@@ -33,6 +33,7 @@ public enum Logging {
GRASSGROWTH,
MYCELIUMSPREAD,
VINEGROWTH,
+ DRIPSTONEGROWTH,
MUSHROOMSPREAD,
BAMBOOGROWTH,
WITHER(true),
@@ -46,6 +47,7 @@ public enum Logging {
DAYLIGHTDETECTORINTERACT,
LECTERNBOOKCHANGE(true),
SCAFFOLDING(true),
+ OXIDIZATION,
SHULKER_BOX_CONTENT,
PLAYER_COMMANDS,
COMMANDBLOCK_COMMANDS,
diff --git a/src/main/java/de/diddiz/LogBlock/Updater.java b/src/main/java/de/diddiz/LogBlock/Updater.java
index 294de53..e547e87 100644
--- a/src/main/java/de/diddiz/LogBlock/Updater.java
+++ b/src/main/java/de/diddiz/LogBlock/Updater.java
@@ -885,6 +885,11 @@ class Updater {
renameMaterial("minecraft:cactus_green", Material.GREEN_DYE);
}
+ if (comparablePreviousMinecraftVersion.compareTo("1.17") < 0 && comparableCurrentMinecraftVersion.compareTo("1.17") >= 0) {
+ logblock.getLogger().info("[Updater] Upgrading Materials to 1.17");
+ renameMaterial("minecraft:grass_path", Material.DIRT_PATH);
+ }
+
config.set("previousMinecraftVersion", currentMinecraftVersion);
logblock.saveConfig();
}
diff --git a/src/main/java/de/diddiz/LogBlock/listeners/BlockSpreadLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/BlockSpreadLogging.java
index 22f29a5..22b077f 100644
--- a/src/main/java/de/diddiz/LogBlock/listeners/BlockSpreadLogging.java
+++ b/src/main/java/de/diddiz/LogBlock/listeners/BlockSpreadLogging.java
@@ -5,6 +5,10 @@ import de.diddiz.LogBlock.LogBlock;
import de.diddiz.LogBlock.Logging;
import org.bukkit.Material;
import org.bukkit.World;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
+import org.bukkit.block.data.type.PointedDripstone;
+import org.bukkit.block.data.type.PointedDripstone.Thickness;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockSpreadEvent;
@@ -22,8 +26,8 @@ public class BlockSpreadLogging extends LoggingListener {
String name;
- World world = event.getBlock().getWorld();
- Material type = event.getSource().getType();
+ World world = event.getNewState().getWorld();
+ Material type = event.getNewState().getType();
switch (type) {
case GRASS:
@@ -39,6 +43,12 @@ public class BlockSpreadLogging extends LoggingListener {
name = "MyceliumSpread";
break;
case VINE:
+ case CAVE_VINES:
+ case CAVE_VINES_PLANT:
+ case WEEPING_VINES:
+ case WEEPING_VINES_PLANT:
+ case TWISTING_VINES:
+ case TWISTING_VINES_PLANT:
if (!isLogging(world, Logging.VINEGROWTH)) {
return;
}
@@ -52,7 +62,7 @@ public class BlockSpreadLogging extends LoggingListener {
name = "MushroomSpread";
break;
case BAMBOO:
- case BAMBOO_SAPLING: {
+ case BAMBOO_SAPLING:
if (!isLogging(world, Logging.BAMBOOGROWTH)) {
return;
}
@@ -62,7 +72,36 @@ public class BlockSpreadLogging extends LoggingListener {
consumer.queueBlockReplace(new Actor(name), event.getSource().getState(), Material.BAMBOO.createBlockData());
}
break;
- }
+ case POINTED_DRIPSTONE:
+ if (!isLogging(world, Logging.DRIPSTONEGROWTH)) {
+ return;
+ }
+ name = "DripstoneGrowth";
+ PointedDripstone pointed = (PointedDripstone) event.getNewState().getBlockData();
+ if (pointed.getThickness() != Thickness.TIP_MERGE) {
+ BlockFace direction = pointed.getVerticalDirection();
+ Block previousPart = event.getBlock().getRelative(direction.getOppositeFace());
+ if (previousPart.getType() == Material.POINTED_DRIPSTONE) {
+ PointedDripstone newBelow = (PointedDripstone) previousPart.getBlockData();
+ newBelow.setThickness(Thickness.FRUSTUM);
+ consumer.queueBlockReplace(new Actor(name), previousPart.getState(), newBelow);
+
+ previousPart = previousPart.getRelative(direction.getOppositeFace());
+ if (previousPart.getType() == Material.POINTED_DRIPSTONE) {
+ Block evenMorePrevious = previousPart.getRelative(direction.getOppositeFace());
+ newBelow = (PointedDripstone) previousPart.getBlockData();
+ newBelow.setThickness(evenMorePrevious.getType() == Material.POINTED_DRIPSTONE ? Thickness.MIDDLE : Thickness.BASE);
+ consumer.queueBlockReplace(new Actor(name), previousPart.getState(), newBelow);
+ }
+ }
+ } else {
+ // special case because the old state is already changed (for one half)
+ PointedDripstone oldState = (PointedDripstone) event.getNewState().getBlockData();
+ oldState.setThickness(Thickness.TIP);
+ consumer.queueBlockReplace(new Actor(name), oldState, event.getNewState());
+ return;
+ }
+ break;
default:
return;
}
diff --git a/src/main/java/de/diddiz/LogBlock/listeners/OxidizationLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/OxidizationLogging.java
new file mode 100644
index 0000000..fcdfd67
--- /dev/null
+++ b/src/main/java/de/diddiz/LogBlock/listeners/OxidizationLogging.java
@@ -0,0 +1,28 @@
+package de.diddiz.LogBlock.listeners;
+
+import static de.diddiz.LogBlock.config.Config.isLogging;
+
+import de.diddiz.LogBlock.Actor;
+import de.diddiz.LogBlock.LogBlock;
+import de.diddiz.LogBlock.Logging;
+import org.bukkit.Material;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.block.BlockFormEvent;
+
+public class OxidizationLogging extends LoggingListener {
+ public OxidizationLogging(LogBlock lb) {
+ super(lb);
+ }
+
+ @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
+ public void onBlockPhysics(BlockFormEvent event) {
+ if (isLogging(event.getBlock().getWorld(), Logging.OXIDIZATION)) {
+ final Material type = event.getNewState().getType();
+ if (type.name().contains("COPPER")) {
+ consumer.queueBlockReplace(new Actor("NaturalOxidization"), event.getBlock().getState(), event.getNewState());
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/de/diddiz/util/BukkitUtils.java b/src/main/java/de/diddiz/util/BukkitUtils.java
index 848e5ed..eb0e7e3 100644
--- a/src/main/java/de/diddiz/util/BukkitUtils.java
+++ b/src/main/java/de/diddiz/util/BukkitUtils.java
@@ -78,6 +78,7 @@ public class BukkitUtils {
private static final EnumSet slabs;
private static final EnumSet concreteBlocks;
private static final EnumMap dyes;
+ private static final EnumSet alwaysWaterlogged;
static {
pressurePlates = EnumSet.noneOf(Material.class);
@@ -155,6 +156,10 @@ public class BukkitUtils {
slabs.add(Material.PRISMARINE_BRICK_SLAB);
slabs.add(Material.BLACKSTONE_SLAB);
slabs.add(Material.POLISHED_BLACKSTONE_SLAB);
+ slabs.add(Material.DEEPSLATE_BRICK_SLAB);
+ slabs.add(Material.DEEPSLATE_TILE_SLAB);
+ slabs.add(Material.COBBLED_DEEPSLATE_SLAB);
+ slabs.add(Material.POLISHED_DEEPSLATE_SLAB);
buttons = EnumSet.noneOf(Material.class);
buttons.add(Material.STONE_BUTTON);
@@ -216,6 +221,8 @@ public class BukkitUtils {
singleBlockPlants.add(Material.CRIMSON_ROOTS);
singleBlockPlants.add(Material.WARPED_ROOTS);
singleBlockPlants.add(Material.NETHER_SPROUTS);
+ singleBlockPlants.add(Material.AZALEA);
+ singleBlockPlants.add(Material.FLOWERING_AZALEA);
doublePlants = EnumSet.noneOf(Material.class);
doublePlants.add(Material.TALL_GRASS);
@@ -225,6 +232,7 @@ public class BukkitUtils {
doublePlants.add(Material.LILAC);
doublePlants.add(Material.SUNFLOWER);
doublePlants.add(Material.PEONY);
+ doublePlants.add(Material.SMALL_DRIPLEAF);
blockEquivalents = new HashSet<>(7);
blockEquivalents.add(new HashSet<>(Arrays.asList(2, 3, 60)));
@@ -246,6 +254,10 @@ public class BukkitUtils {
relativeBreakable.add(Material.TRIPWIRE_HOOK);
relativeBreakable.add(Material.COCOA);
relativeBreakable.add(Material.BELL);
+ relativeBreakable.add(Material.AMETHYST_CLUSTER);
+ relativeBreakable.add(Material.SMALL_AMETHYST_BUD);
+ relativeBreakable.add(Material.MEDIUM_AMETHYST_BUD);
+ relativeBreakable.add(Material.LARGE_AMETHYST_BUD);
// Blocks that break when they are on top of a block
relativeTopBreakable = EnumSet.noneOf(Material.class);
@@ -279,10 +291,15 @@ public class BukkitUtils {
relativeTopBreakable.add(Material.BAMBOO_SAPLING);
relativeTopBreakable.add(Material.TWISTING_VINES);
relativeTopBreakable.add(Material.TWISTING_VINES_PLANT);
+ relativeTopBreakable.add(Material.BIG_DRIPLEAF);
+ relativeTopBreakable.add(Material.BIG_DRIPLEAF_STEM);
for (Material m : Material.values()) {
if (m.name().startsWith("POTTED_")) {
relativeTopBreakable.add(m);
}
+ if (m.name().endsWith("CANDLE_CAKE")) {
+ relativeTopBreakable.add(m);
+ }
}
// Blocks that break falling entities
@@ -331,6 +348,11 @@ public class BukkitUtils {
fallingEntityKillers.add(Material.SKELETON_WALL_SKULL);
fallingEntityKillers.add(Material.WITHER_SKELETON_SKULL);
fallingEntityKillers.add(Material.WITHER_SKELETON_WALL_SKULL);
+ for (Material m : Material.values()) {
+ if (m.name().contains("CANDLE")) {
+ fallingEntityKillers.add(m);
+ }
+ }
// Crop Blocks
cropBlocks = EnumSet.noneOf(Material.class);
@@ -410,10 +432,10 @@ public class BukkitUtils {
nonFluidProofBlocks.add(Material.TORCH);
nonFluidProofBlocks.add(Material.SOUL_TORCH);
nonFluidProofBlocks.add(Material.FLOWER_POT);
- nonFluidProofBlocks.add(Material.POWERED_RAIL);
- nonFluidProofBlocks.add(Material.DETECTOR_RAIL);
- nonFluidProofBlocks.add(Material.ACTIVATOR_RAIL);
- nonFluidProofBlocks.add(Material.RAIL);
+ // nonFluidProofBlocks.add(Material.POWERED_RAIL);
+ // nonFluidProofBlocks.add(Material.DETECTOR_RAIL);
+ // nonFluidProofBlocks.add(Material.ACTIVATOR_RAIL);
+ // nonFluidProofBlocks.add(Material.RAIL);
nonFluidProofBlocks.add(Material.LEVER);
nonFluidProofBlocks.add(Material.REDSTONE_WIRE);
nonFluidProofBlocks.add(Material.REDSTONE_TORCH);
@@ -422,6 +444,12 @@ public class BukkitUtils {
nonFluidProofBlocks.add(Material.DAYLIGHT_DETECTOR);
nonFluidProofBlocks.addAll(carpets);
+ alwaysWaterlogged = EnumSet.noneOf(Material.class);
+ alwaysWaterlogged.add(Material.SEAGRASS);
+ alwaysWaterlogged.add(Material.TALL_SEAGRASS);
+ alwaysWaterlogged.add(Material.KELP);
+ alwaysWaterlogged.add(Material.KELP_PLANT);
+
bedBlocks = EnumSet.noneOf(Material.class);
bedBlocks.add(Material.BLACK_BED);
bedBlocks.add(Material.BLUE_BED);
@@ -1018,8 +1046,8 @@ public class BukkitUtils {
case FARMLAND:
case GRASS_BLOCK:
case PODZOL:
- case GRASS_PATH:
- return found == Material.DIRT || found == Material.MYCELIUM || found == Material.FARMLAND || found == Material.GRASS_BLOCK || found == Material.PODZOL || found == Material.GRASS_PATH;
+ case DIRT_PATH:
+ return found == Material.DIRT || found == Material.MYCELIUM || found == Material.FARMLAND || found == Material.GRASS_BLOCK || found == Material.PODZOL || found == Material.DIRT_PATH;
case BAMBOO:
case BAMBOO_SAPLING:
return found == Material.BAMBOO || found == Material.BAMBOO_SAPLING;
@@ -1038,6 +1066,32 @@ public class BukkitUtils {
case WEEPING_VINES:
case WEEPING_VINES_PLANT:
return found == Material.WEEPING_VINES || found == Material.WEEPING_VINES_PLANT;
+ case CAVE_VINES:
+ case CAVE_VINES_PLANT:
+ return found == Material.CAVE_VINES || found == Material.CAVE_VINES_PLANT;
+ case BIG_DRIPLEAF:
+ case BIG_DRIPLEAF_STEM:
+ return found == Material.BIG_DRIPLEAF || found == Material.BIG_DRIPLEAF_STEM;
+ case COPPER_BLOCK:
+ case EXPOSED_COPPER:
+ case WEATHERED_COPPER:
+ case OXIDIZED_COPPER:
+ return found == Material.COPPER_BLOCK || found == Material.EXPOSED_COPPER || found == Material.WEATHERED_COPPER || found == Material.OXIDIZED_COPPER;
+ case CUT_COPPER:
+ case EXPOSED_CUT_COPPER:
+ case WEATHERED_CUT_COPPER:
+ case OXIDIZED_CUT_COPPER:
+ return found == Material.CUT_COPPER || found == Material.EXPOSED_CUT_COPPER || found == Material.WEATHERED_CUT_COPPER || found == Material.OXIDIZED_CUT_COPPER;
+ case CUT_COPPER_STAIRS:
+ case EXPOSED_CUT_COPPER_STAIRS:
+ case WEATHERED_CUT_COPPER_STAIRS:
+ case OXIDIZED_CUT_COPPER_STAIRS:
+ return found == Material.CUT_COPPER_STAIRS || found == Material.EXPOSED_CUT_COPPER_STAIRS || found == Material.WEATHERED_CUT_COPPER_STAIRS || found == Material.OXIDIZED_CUT_COPPER_STAIRS;
+ case CUT_COPPER_SLAB:
+ case EXPOSED_CUT_COPPER_SLAB:
+ case WEATHERED_CUT_COPPER_SLAB:
+ case OXIDIZED_CUT_COPPER_SLAB:
+ return found == Material.CUT_COPPER_SLAB || found == Material.EXPOSED_CUT_COPPER_SLAB || found == Material.WEATHERED_CUT_COPPER_SLAB || found == Material.OXIDIZED_CUT_COPPER_SLAB;
}
return false;
}
@@ -1045,4 +1099,8 @@ public class BukkitUtils {
public static Material[] getAllSignsArray() {
return allSigns.toArray(new Material[allSigns.size()]);
}
+
+ public static boolean isAlwaysWaterlogged(Material m) {
+ return alwaysWaterlogged.contains(m);
+ }
}
diff --git a/src/main/java/de/diddiz/util/LoggingUtil.java b/src/main/java/de/diddiz/util/LoggingUtil.java
index 8764c67..afdf0ba 100644
--- a/src/main/java/de/diddiz/util/LoggingUtil.java
+++ b/src/main/java/de/diddiz/util/LoggingUtil.java
@@ -144,6 +144,12 @@ public class LoggingUtil {
consumer.queueBlockReplace(actor, above.getState(), Material.WEEPING_VINES.createBlockData());
}
}
+ if (replacedType == Material.CAVE_VINES || replacedType == Material.CAVE_VINES_PLANT) {
+ Block above = origin.getRelative(BlockFace.UP);
+ if (above.getType() == Material.CAVE_VINES_PLANT) {
+ consumer.queueBlockReplace(actor, above.getState(), Material.CAVE_VINES.createBlockData());
+ }
+ }
Block checkBlock = origin.getRelative(BlockFace.UP);
Material typeAbove = checkBlock.getType();
@@ -207,12 +213,22 @@ public class LoggingUtil {
if (bell.getAttachment() == Attachment.CEILING) {
consumer.queueBlockBreak(actor, checkBlock.getState());
}
- } else if (typeBelow == Material.WEEPING_VINES || typeBelow == Material.WEEPING_VINES_PLANT) {
+ } else if (typeBelow == Material.WEEPING_VINES || typeBelow == Material.WEEPING_VINES_PLANT || typeBelow == Material.CAVE_VINES || typeBelow == Material.CAVE_VINES_PLANT) {
consumer.queueBlockBreak(actor, checkBlock.getState());
- // check next blocks above
+ // check next blocks below
checkBlock = checkBlock.getRelative(BlockFace.DOWN);
typeBelow = checkBlock.getType();
- while (typeBelow == Material.WEEPING_VINES || typeBelow == Material.WEEPING_VINES_PLANT) {
+ while (typeBelow == Material.WEEPING_VINES || typeBelow == Material.WEEPING_VINES_PLANT || typeBelow == Material.CAVE_VINES || typeBelow == Material.CAVE_VINES_PLANT) {
+ consumer.queueBlockBreak(actor, checkBlock.getState());
+ checkBlock = checkBlock.getRelative(BlockFace.DOWN);
+ typeBelow = checkBlock.getType();
+ }
+ } else if ((replacedType == Material.BIG_DRIPLEAF || replacedType == Material.BIG_DRIPLEAF_STEM) && (typeBelow == Material.BIG_DRIPLEAF || typeBelow == Material.BIG_DRIPLEAF_STEM)) {
+ consumer.queueBlockBreak(actor, checkBlock.getState());
+ // check next blocks below
+ checkBlock = checkBlock.getRelative(BlockFace.DOWN);
+ typeBelow = checkBlock.getType();
+ while (typeBelow == Material.BIG_DRIPLEAF || typeBelow == Material.BIG_DRIPLEAF_STEM) {
consumer.queueBlockBreak(actor, checkBlock.getState());
checkBlock = checkBlock.getRelative(BlockFace.DOWN);
typeBelow = checkBlock.getType();
diff --git a/src/main/resources/blockdata.txt b/src/main/resources/blockdata.txt
index 8859bb3..3f2b841 100644
--- a/src/main/resources/blockdata.txt
+++ b/src/main/resources/blockdata.txt
@@ -1813,7 +1813,7 @@
207:13,minecraft:air
207:14,minecraft:air
207:15,minecraft:air
-208:0,minecraft:grass_path
+208:0,minecraft:dirt_path
209:0,minecraft:end_gateway
210:0,minecraft:repeating_command_block[conditional=false,facing=down]
210:1,minecraft:repeating_command_block[conditional=false,facing=up]
diff --git a/src/main/resources/itemdata.txt b/src/main/resources/itemdata.txt
index 01764f2..25223ce 100644
--- a/src/main/resources/itemdata.txt
+++ b/src/main/resources/itemdata.txt
@@ -454,7 +454,7 @@
205:0,minecraft:purpur_slab
206:0,minecraft:end_stone_bricks
207:0,minecraft:beetroots
-208:0,minecraft:grass_path
+208:0,minecraft:dirt_path
209:0,minecraft:end_gateway
210:0,minecraft:repeating_command_block
211:0,minecraft:chain_command_block