From 512edae9c69390c21c62ab85495cc8ad1aa1f87e Mon Sep 17 00:00:00 2001 From: dfsek Date: Wed, 6 Jan 2021 10:57:34 -0700 Subject: [PATCH] Multi-version support for 1.13-1.16 --- .../script/functions/BlockFunction.java | 6 +- .../dfsek/terra/registry/FloraRegistry.java | 57 ++++++++++--------- .../dfsek/terra/bukkit/TerraBukkitPlugin.java | 44 ++++++++++++++ .../terra/bukkit/world/BukkitAdapter.java | 27 --------- .../world/block/data/BukkitBlockData.java | 5 +- .../bukkit/world/block/data/BukkitWall.java | 30 +++++++++- .../bukkit/src/main/resources/plugin.yml | 2 +- 7 files changed, 111 insertions(+), 60 deletions(-) diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/functions/BlockFunction.java b/common/src/main/java/com/dfsek/terra/api/structures/script/functions/BlockFunction.java index 5e0cf7543..d32e9e01f 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/script/functions/BlockFunction.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/functions/BlockFunction.java @@ -25,7 +25,11 @@ public class BlockFunction implements Function { this.position = position; if(!(data instanceof ConstantExpression)) throw new ParseException("Block data must be constant", data.getPosition()); - this.data = main.getWorldHandle().createBlockData(((ConstantExpression) data).getConstant()); + try { + this.data = main.getWorldHandle().createBlockData(((ConstantExpression) data).getConstant()); + } catch(IllegalArgumentException e) { + throw new ParseException("Could not parse block data", data.getPosition(), e); + } this.x = x; this.y = y; this.z = z; diff --git a/common/src/main/java/com/dfsek/terra/registry/FloraRegistry.java b/common/src/main/java/com/dfsek/terra/registry/FloraRegistry.java index e15e68fe1..194948b45 100644 --- a/common/src/main/java/com/dfsek/terra/registry/FloraRegistry.java +++ b/common/src/main/java/com/dfsek/terra/registry/FloraRegistry.java @@ -9,6 +9,7 @@ import com.dfsek.terra.util.MaterialSet; import java.util.Arrays; import java.util.Collections; +import java.util.concurrent.Callable; public class FloraRegistry extends TerraRegistry { private final TerraPlugin main; @@ -16,48 +17,48 @@ public class FloraRegistry extends TerraRegistry { public FloraRegistry(TerraPlugin main) { this.main = main; MaterialSet grassy = MaterialSet.get(create("minecraft:grass_block"), create("minecraft:podzol")); - addItem("TALL_GRASS", new ConstantFlora(grassy, Arrays.asList(data("minecraft:tall_grass[half=lower]"), data("minecraft:tall_grass[half=upper]")))); - addItem("TALL_FERN", new ConstantFlora(grassy, Arrays.asList(data("minecraft:large_fern[half=lower]"), data("minecraft:large_fern[half=upper]")))); - addItem("SUNFLOWER", new ConstantFlora(grassy, Arrays.asList(data("minecraft:sunflower[half=lower]"), data("minecraft:sunflower[half=upper]")))); - addItem("ROSE_BUSH", new ConstantFlora(grassy, Arrays.asList(data("minecraft:rose_bush[half=lower]"), data("minecraft:rose_bush[half=upper]")))); - addItem("LILAC", new ConstantFlora(grassy, Arrays.asList(data("minecraft:lilac[half=lower]"), data("minecraft:lilac[half=upper]")))); - addItem("PEONY", new ConstantFlora(grassy, Arrays.asList(data("minecraft:peony[half=lower]"), data("minecraft:peony[half=upper]")))); - addItem("GRASS", new ConstantFlora(grassy, Collections.singletonList(data("minecraft:grass")))); - addItem("FERN", new ConstantFlora(grassy, Collections.singletonList(data("minecraft:fern")))); - addItem("AZURE_BLUET", new ConstantFlora(grassy, Collections.singletonList(data("minecraft:azure_bluet")))); - addItem("LILY_OF_THE_VALLEY", new ConstantFlora(grassy, Collections.singletonList(data("minecraft:lily_of_the_valley")))); - addItem("BLUE_ORCHID", new ConstantFlora(grassy, Collections.singletonList(data("minecraft:blue_orchid")))); - addItem("POPPY", new ConstantFlora(grassy, Collections.singletonList(data("minecraft:poppy")))); - addItem("DANDELION", new ConstantFlora(grassy, Collections.singletonList(data("minecraft:dandelion")))); - addItem("WITHER_ROSE", new ConstantFlora(grassy, Collections.singletonList(data("minecraft:wither_rose")))); - addItem("DEAD_BUSH", new ConstantFlora(MaterialSet.get(create("minecraft:terracotta"), create("minecraft:black_terracotta"), + addItem("TALL_GRASS", () -> new ConstantFlora(grassy, Arrays.asList(data("minecraft:tall_grass[half=lower]"), data("minecraft:tall_grass[half=upper]")))); + addItem("TALL_FERN", () -> new ConstantFlora(grassy, Arrays.asList(data("minecraft:large_fern[half=lower]"), data("minecraft:large_fern[half=upper]")))); + addItem("SUNFLOWER", () -> new ConstantFlora(grassy, Arrays.asList(data("minecraft:sunflower[half=lower]"), data("minecraft:sunflower[half=upper]")))); + addItem("ROSE_BUSH", () -> new ConstantFlora(grassy, Arrays.asList(data("minecraft:rose_bush[half=lower]"), data("minecraft:rose_bush[half=upper]")))); + addItem("LILAC", () -> new ConstantFlora(grassy, Arrays.asList(data("minecraft:lilac[half=lower]"), data("minecraft:lilac[half=upper]")))); + addItem("PEONY", () -> new ConstantFlora(grassy, Arrays.asList(data("minecraft:peony[half=lower]"), data("minecraft:peony[half=upper]")))); + addItem("GRASS", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:grass")))); + addItem("FERN", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:fern")))); + addItem("AZURE_BLUET", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:azure_bluet")))); + addItem("LILY_OF_THE_VALLEY", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:lily_of_the_valley")))); + addItem("BLUE_ORCHID", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:blue_orchid")))); + addItem("POPPY", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:poppy")))); + addItem("DANDELION", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:dandelion")))); + addItem("WITHER_ROSE", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:wither_rose")))); + addItem("DEAD_BUSH", () -> new ConstantFlora(MaterialSet.get(create("minecraft:terracotta"), create("minecraft:black_terracotta"), create("minecraft:blue_terracotta"), create("minecraft:brown_terracotta"), create("minecraft:cyan_terracotta"), create("minecraft:gray_terracotta"), create("minecraft:green_terracotta"), create("minecraft:light_blue_terracotta"), create("minecraft:light_gray_terracotta"), create("minecraft:lime_terracotta"), create("minecraft:magenta_terracotta"), create("minecraft:orange_terracotta"), create("minecraft:pink_terracotta"), create("minecraft:purple_terracotta"), create("minecraft:red_terracotta"), create("minecraft:white_terracotta"), create("minecraft:yellow_terracotta"), create("minecraft:red_sand"), create("minecraft:sand")), Collections.singletonList(data("minecraft:dead_bush")))); - addItem("RED_TULIP", new ConstantFlora(grassy, Collections.singletonList(data("minecraft:red_tulip")))); - addItem("ORANGE_TULIP", new ConstantFlora(grassy, Collections.singletonList(data("minecraft:orange_tulip")))); - addItem("WHITE_TULIP", new ConstantFlora(grassy, Collections.singletonList(data("minecraft:white_tulip")))); - addItem("PINK_TULIP", new ConstantFlora(grassy, Collections.singletonList(data("minecraft:pink_tulip")))); - addItem("OXEYE_DAISY", new ConstantFlora(grassy, Collections.singletonList(data("minecraft:oxeye_daisy")))); - addItem("ALLIUM", new ConstantFlora(grassy, Collections.singletonList(data("minecraft:allium")))); - addItem("CORNFLOWER", new ConstantFlora(grassy, Collections.singletonList(data("minecraft:cornflower")))); - addItem("LILY_PAD", new ConstantFlora(MaterialSet.get(create("minecraft:water")), Collections.singletonList(data("minecraft:lily_pad")))); + addItem("RED_TULIP", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:red_tulip")))); + addItem("ORANGE_TULIP", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:orange_tulip")))); + addItem("WHITE_TULIP", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:white_tulip")))); + addItem("PINK_TULIP", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:pink_tulip")))); + addItem("OXEYE_DAISY", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:oxeye_daisy")))); + addItem("ALLIUM", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:allium")))); + addItem("CORNFLOWER", () -> new ConstantFlora(grassy, Collections.singletonList(data("minecraft:cornflower")))); + addItem("LILY_PAD", () -> new ConstantFlora(MaterialSet.get(create("minecraft:water")), Collections.singletonList(data("minecraft:lily_pad")))); MaterialSet mushroom = MaterialSet.get(create("minecraft:grass_block"), create("minecraft:stone"), create("minecraft:podzol"), create("minecraft:netherrack"), create("minecraft:mycelium")); - addItem("RED_MUSHROOM", new ConstantFlora(mushroom, Collections.singletonList(data("minecraft:red_mushroom")))); - addItem("BROWN_MUSHROOM", new ConstantFlora(mushroom, Collections.singletonList(data("minecraft:brown_mushroom")))); + addItem("RED_MUSHROOM", () -> new ConstantFlora(mushroom, Collections.singletonList(data("minecraft:red_mushroom")))); + addItem("BROWN_MUSHROOM", () -> new ConstantFlora(mushroom, Collections.singletonList(data("minecraft:brown_mushroom")))); } private MaterialData create(String s) { return main.getWorldHandle().createMaterialData(s); } - private void addItem(String id, ConstantFlora flora) { + private void addItem(String id, Callable flora) { try { - add(id, flora); - } catch(IllegalArgumentException e) { + add(id, flora.call()); + } catch(Exception e) { main.getLogger().warning("Failed to load Flora item: " + id + ": " + e.getMessage()); } } diff --git a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/TerraBukkitPlugin.java b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/TerraBukkitPlugin.java index 120c6dc59..d39ff661c 100644 --- a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/TerraBukkitPlugin.java +++ b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/TerraBukkitPlugin.java @@ -55,6 +55,17 @@ public class TerraBukkitPlugin extends JavaPlugin implements TerraPlugin { private WorldHandle handle = new BukkitWorldHandle(this); private final GenericLoaders genericLoaders = new GenericLoaders(this); + public static final Version BUKKIT_VERSION; + + static { + String ver = Bukkit.getServer().getClass().getPackage().getName(); + if(ver.contains("1_16")) BUKKIT_VERSION = Version.V1_16; + else if(ver.contains("1_15")) BUKKIT_VERSION = Version.V1_15; + else if(ver.contains("1_14")) BUKKIT_VERSION = Version.V1_14; + else if(ver.contains("1_13")) BUKKIT_VERSION = Version.V1_13; + else BUKKIT_VERSION = Version.UNKNOWN; + } + public void reload() { Map newMap = new HashMap<>(); @@ -96,6 +107,11 @@ public class TerraBukkitPlugin extends JavaPlugin implements TerraPlugin { public void onEnable() { Debug.setLogger(getLogger()); // Set debug logger. + getLogger().info("Running on version " + BUKKIT_VERSION); + if(BUKKIT_VERSION.equals(Version.UNKNOWN)) { + getLogger().warning("Terra is running on an unknown Bukkit version. Proceed with caution."); + } + ((BukkitWorldHandle) handle).setTreeTransformer(new Transformer.Builder() .addTransform(id -> new BukkitTree(TreeType.valueOf(id), this)) // First try getting directly from enum .addTransform(new MapTransform() // Then try map of less stupid names @@ -196,4 +212,32 @@ public class TerraBukkitPlugin extends JavaPlugin implements TerraPlugin { .registerLoader(EntityType.class, (t, o, l) -> EntityType.valueOf((String) o)); genericLoaders.register(registry); } + + public enum Version { + V1_13(13), + + V1_14(14), + + V1_15(15), + + V1_16(16), + + UNKNOWN(Integer.MAX_VALUE); // Assume unknown version is latest. + + private final int index; + + Version(int index) { + this.index = index; + } + + /** + * Gets if this version is above or equal to another. + * + * @param other Other version + * @return Whether this version is equal to or later than other. + */ + public boolean above(Version other) { + return this.index >= other.index; + } + } } diff --git a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/BukkitAdapter.java b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/BukkitAdapter.java index 7e522a62a..b7ba7da2f 100644 --- a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/BukkitAdapter.java +++ b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/BukkitAdapter.java @@ -14,7 +14,6 @@ import com.dfsek.terra.api.platform.world.Chunk; import com.dfsek.terra.api.platform.world.World; import com.dfsek.terra.bukkit.BukkitCommandSender; import org.bukkit.Location; -import org.bukkit.block.data.type.Wall; import org.bukkit.util.Vector; /** @@ -300,32 +299,6 @@ public final class BukkitAdapter { } } - public static Wall.Height adapt(com.dfsek.terra.api.platform.block.data.Wall.Height height) { - switch(height) { - case NONE: - return Wall.Height.NONE; - case LOW: - return Wall.Height.LOW; - case TALL: - return Wall.Height.TALL; - default: - throw new IllegalStateException(); - } - } - - public static com.dfsek.terra.api.platform.block.data.Wall.Height adapt(Wall.Height height) { - switch(height) { - case TALL: - return com.dfsek.terra.api.platform.block.data.Wall.Height.TALL; - case LOW: - return com.dfsek.terra.api.platform.block.data.Wall.Height.LOW; - case NONE: - return com.dfsek.terra.api.platform.block.data.Wall.Height.NONE; - default: - throw new IllegalStateException(); - } - } - public static Location adapt(com.dfsek.terra.api.math.vector.Location location) { return new Location(((BukkitWorld) location.getWorld()).getHandle(), location.getX(), location.getY(), location.getZ()); } diff --git a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/block/data/BukkitBlockData.java b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/block/data/BukkitBlockData.java index 0b8b2aa13..dc3295f73 100644 --- a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/block/data/BukkitBlockData.java +++ b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/block/data/BukkitBlockData.java @@ -2,6 +2,7 @@ package com.dfsek.terra.bukkit.world.block.data; import com.dfsek.terra.api.platform.block.BlockData; import com.dfsek.terra.api.platform.block.MaterialData; +import com.dfsek.terra.bukkit.TerraBukkitPlugin; import com.dfsek.terra.bukkit.world.block.BukkitMaterialData; import org.bukkit.block.data.AnaloguePowerable; import org.bukkit.block.data.Directional; @@ -27,7 +28,9 @@ public class BukkitBlockData implements BlockData { if(bukkitData instanceof Rail) return new BukkitRail((Rail) bukkitData); if(bukkitData instanceof Stairs) return new BukkitStairs((Stairs) bukkitData); if(bukkitData instanceof Slab) return new BukkitSlab((Slab) bukkitData); - if(bukkitData instanceof Wall) return new BukkitWall((Wall) bukkitData); + if(TerraBukkitPlugin.BUKKIT_VERSION.above(TerraBukkitPlugin.Version.V1_16) && bukkitData instanceof Wall) { // Wall only exists on 1.16 and up. + return new BukkitWall((Wall) bukkitData); + } if(bukkitData instanceof RedstoneWire) return new BukkitRedstoneWire((RedstoneWire) bukkitData); if(bukkitData instanceof AnaloguePowerable) return new BukkitAnaloguePowerable((AnaloguePowerable) bukkitData); diff --git a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/block/data/BukkitWall.java b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/block/data/BukkitWall.java index 5fffd7802..2addb83b7 100644 --- a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/block/data/BukkitWall.java +++ b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/block/data/BukkitWall.java @@ -19,13 +19,39 @@ public class BukkitWall extends BukkitWaterlogged implements Wall { ((org.bukkit.block.data.type.Wall) getHandle()).setUp(up); } + public static org.bukkit.block.data.type.Wall.Height adapt(com.dfsek.terra.api.platform.block.data.Wall.Height height) { + switch(height) { + case NONE: + return org.bukkit.block.data.type.Wall.Height.NONE; + case LOW: + return org.bukkit.block.data.type.Wall.Height.LOW; + case TALL: + return org.bukkit.block.data.type.Wall.Height.TALL; + default: + throw new IllegalStateException(); + } + } + + public static com.dfsek.terra.api.platform.block.data.Wall.Height adapt(org.bukkit.block.data.type.Wall.Height height) { + switch(height) { + case TALL: + return com.dfsek.terra.api.platform.block.data.Wall.Height.TALL; + case LOW: + return com.dfsek.terra.api.platform.block.data.Wall.Height.LOW; + case NONE: + return com.dfsek.terra.api.platform.block.data.Wall.Height.NONE; + default: + throw new IllegalStateException(); + } + } + @Override public void setHeight(BlockFace face, Height height) { - ((org.bukkit.block.data.type.Wall) getHandle()).setHeight(BukkitAdapter.adapt(face), BukkitAdapter.adapt(height)); + ((org.bukkit.block.data.type.Wall) getHandle()).setHeight(BukkitAdapter.adapt(face), adapt(height)); } @Override public Height getHeight(BlockFace face) { - return BukkitAdapter.adapt(((org.bukkit.block.data.type.Wall) getHandle()).getHeight(BukkitAdapter.adapt(face))); + return adapt(((org.bukkit.block.data.type.Wall) getHandle()).getHeight(BukkitAdapter.adapt(face))); } } diff --git a/platforms/bukkit/src/main/resources/plugin.yml b/platforms/bukkit/src/main/resources/plugin.yml index 985ddc05f..0b0a1fafc 100644 --- a/platforms/bukkit/src/main/resources/plugin.yml +++ b/platforms/bukkit/src/main/resources/plugin.yml @@ -3,7 +3,7 @@ main: "com.dfsek.terra.bukkit.TerraBukkitPlugin" version: "@VERSION@" load: "STARTUP" author: dfsek -api-version: "1.16" +api-version: "1.13" description: "An insanely powerful free & open-source data-driven world generator." softdepend: [ "WorldEdit" ] commands: