From 771a5504555d6fe364f95d00231f205899ecf0e0 Mon Sep 17 00:00:00 2001 From: noone-075 Date: Sat, 5 Sep 2026 08:23:33 +0200 Subject: [PATCH 01/12] feat: possible second implementation of the new structure system - the old API is fully usable in api.structure.* but deprecated and mark for removal - the new API is located in api.structures.* and it would be the new way to create structures - the new API works with 2 types of structures: LocatedStructure and RelativeStructure - LocatedStructure is a structure that is generated at a specific location and it can be placed without specifying a location, it is already located - RelativeStructure is a structure that is generated relative to a location and it can be placed to any location, it is not located - each of them uses a PlacebleStructure (either LocatedPlacebleStructure or RelativePlacebleStructure) to build the structure and place it. - to make a new Structure, you need to extend either of them, and implement the build() method to return the correct type of PlacebleStructure - they use custom placeble blocks (LocatedBlock, RelativeBlock), they can also override the place function for custom behavior - then implementing the GenerableStructure interface is optional, it allows the structure to have the function needed to be generated in the world, if used by a chunk generator. THIS IS NOT A FINAL IMPLEMENTATION, IT IS STILL IN DEVELOPMENT AND MAY CHANGE IN THE FUTURE. --- pom.xml | 2 +- .../wlib/api/misc/SchemLoadingError.java | 20 ++++ .../api/structure/AbstractBaseStructure.java | 23 ++++- .../wlib/api/structure/BlockRelative.java | 35 ++++++- .../wlib/api/structure/WeightedStructure.java | 6 ++ .../api/structure/WeightedStructureTable.java | 14 +++ .../api/structures/GenerableStructure.java | 69 +++++++++++++ .../wlib/api/structures/LocatedStructure.java | 33 +++++++ .../api/structures/RelativeStructure.java | 33 +++++++ .../webmc/wlib/api/structures/Structure.java | 42 ++++++++ .../wlib/api/structures/blocks/Block.java | 65 +++++++++++++ .../api/structures/blocks/LocatedBlock.java | 81 ++++++++++++++++ .../api/structures/blocks/RelativeBlock.java | 80 ++++++++++++++++ .../placeble/LocatedPlacebleStructure.java | 96 +++++++++++++++++++ .../placeble/PlacebleStructure.java | 64 +++++++++++++ .../placeble/RelativePlacebleStructure.java | 91 ++++++++++++++++++ .../wlib/internal/command/WLIBCommand.java | 70 +++++++------- .../HerobrineShrineTestStructure.java | 7 ++ .../RickQRCodeTestSchemStructure.java | 8 ++ .../HerobrineShrineTestStructure.java | 70 ++++++++++++++ .../structures/RickQRCodeTestStructure.java | 39 ++++++++ 21 files changed, 907 insertions(+), 41 deletions(-) create mode 100644 src/main/java/xyz/webmc/wlib/api/misc/SchemLoadingError.java create mode 100644 src/main/java/xyz/webmc/wlib/api/structures/GenerableStructure.java create mode 100644 src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java create mode 100644 src/main/java/xyz/webmc/wlib/api/structures/RelativeStructure.java create mode 100644 src/main/java/xyz/webmc/wlib/api/structures/Structure.java create mode 100644 src/main/java/xyz/webmc/wlib/api/structures/blocks/Block.java create mode 100644 src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java create mode 100644 src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java create mode 100644 src/main/java/xyz/webmc/wlib/api/structures/placeble/LocatedPlacebleStructure.java create mode 100644 src/main/java/xyz/webmc/wlib/api/structures/placeble/PlacebleStructure.java create mode 100644 src/main/java/xyz/webmc/wlib/api/structures/placeble/RelativePlacebleStructure.java create mode 100644 src/main/java/xyz/webmc/wlib/internal/structures/HerobrineShrineTestStructure.java create mode 100644 src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java diff --git a/pom.xml b/pom.xml index 3ca78f8..bf70763 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 xyz.webmc wlib - 1.2.9-SNAPSHOT + 1.3.1-SNAPSHOT github diff --git a/src/main/java/xyz/webmc/wlib/api/misc/SchemLoadingError.java b/src/main/java/xyz/webmc/wlib/api/misc/SchemLoadingError.java new file mode 100644 index 0000000..850b834 --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/misc/SchemLoadingError.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.api.misc; + +public class SchemLoadingError extends RuntimeException { + public SchemLoadingError(String message) { + super(message); + } +} diff --git a/src/main/java/xyz/webmc/wlib/api/structure/AbstractBaseStructure.java b/src/main/java/xyz/webmc/wlib/api/structure/AbstractBaseStructure.java index d84fd41..5f0b0cd 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/AbstractBaseStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structure/AbstractBaseStructure.java @@ -13,6 +13,7 @@ package xyz.webmc.wlib.api.structure; +import xyz.webmc.wlib.api.WLIB; import xyz.webmc.wlib.api.util.SchemUtil; import java.io.File; @@ -32,46 +33,61 @@ import net.sandrohc.schematic4j.schematic.types.SchematicBlockPos; import org.bukkit.Location; - -@SuppressWarnings({ "unchecked" }) +@SuppressWarnings({ "unchecked", "removal" }) +@Deprecated(forRemoval = true) public abstract class AbstractBaseStructure { private static final Map, AbstractBaseStructure> INSTANCES = new HashMap<>(); private final List blocks = new ArrayList<>(); private final String name; + @Deprecated(forRemoval = true) protected AbstractBaseStructure(final String name) { this.name = name; } + @Deprecated(forRemoval = true) public final void place(final Location loc) { + WLIB.warnDeprecatedUsage(); final Location offset = loc.clone().add(this.getOffsetX(), this.getOffsetY(), this.getOffsetZ()); for (final BlockRelative blk : blocks) { blk.place(offset); } } + @Deprecated(forRemoval = true) public final String getName() { + WLIB.warnDeprecatedUsage(); return this.name; } + @Deprecated(forRemoval = true) public int getOffsetX() { + WLIB.warnDeprecatedUsage(); return 0; } + @Deprecated(forRemoval = true) public int getOffsetY() { + WLIB.warnDeprecatedUsage(); return 0; } + @Deprecated(forRemoval = true) public int getOffsetZ() { + WLIB.warnDeprecatedUsage(); return 0; } + @Deprecated(forRemoval = true) protected final void addBlock(final BlockRelative blk) { + WLIB.warnDeprecatedUsage(); this.blocks.add(blk); } + @Deprecated(forRemoval = true) protected final void loadSchematic(final InputStream is) throws IOException, ParsingException { + WLIB.warnDeprecatedUsage(); try (is) { final Schematic schematic = SchemUtil.readSchematic(is); @@ -109,11 +125,14 @@ protected final void loadSchematic(final InputStream is) throws IOException, Par } } + @Deprecated(forRemoval = true) protected final void loadSchematic(final File file) throws IOException, ParsingException { loadSchematic(new FileInputStream(file)); } + @Deprecated(forRemoval = true) public static final T getInstance(final Class clazz, final Object... params) { + WLIB.warnDeprecatedUsage(); AbstractBaseStructure structure = INSTANCES.get(clazz); if (structure == null) { diff --git a/src/main/java/xyz/webmc/wlib/api/structure/BlockRelative.java b/src/main/java/xyz/webmc/wlib/api/structure/BlockRelative.java index d6880eb..36448ee 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/BlockRelative.java +++ b/src/main/java/xyz/webmc/wlib/api/structure/BlockRelative.java @@ -22,7 +22,7 @@ import org.bukkit.Material; import org.bukkit.block.Block; -@SuppressWarnings({ "deprecation" }) +@Deprecated(forRemoval = true) public class BlockRelative { private final int x; private final int y; @@ -32,6 +32,7 @@ public class BlockRelative { private final String dataModern; private final byte dataLegacy; + @Deprecated(forRemoval = true) private BlockRelative(final int x, final int y, final int z, final XMaterial mat, final String dataModern, final byte dataLegacy) { this.x = x; this.y = y; @@ -41,37 +42,51 @@ private BlockRelative(final int x, final int y, final int z, final XMaterial mat this.dataLegacy = dataLegacy; } + @Deprecated(forRemoval = true) public BlockRelative(final int x, final int y, final int z, final XMaterial mat) { this(x, y, z, mat, null, (byte) 0); + WLIB.warnDeprecatedUsage(); } + @Deprecated(forRemoval = true) public BlockRelative(final int x, final int y, final int z, final Material mat) { this(x, y, z, XMaterial.matchXMaterial(mat)); + WLIB.warnDeprecatedUsage(); } + @Deprecated(forRemoval = true) public BlockRelative(final int x, final int y, final int z, final XMaterial mat, final String dataModern) { this(x, y, z, mat, dataModern, (byte) 0); + WLIB.warnDeprecatedUsage(); } + @Deprecated(forRemoval = true) public BlockRelative(final int x, final int y, final int z, final Material mat, final String dataModern) { this(x, y, z, XMaterial.matchXMaterial(mat), dataModern); + WLIB.warnDeprecatedUsage(); } + @Deprecated(forRemoval = true) public BlockRelative(final int x, final int y, final int z, final XMaterial mat, final byte dataLegacy) { this(x, y, z, mat, null, dataLegacy); + WLIB.warnDeprecatedUsage(); } + @Deprecated(forRemoval = true) public BlockRelative(final int x, final int y, final int z, final Material mat, final byte dataLegacy) { this(x, y, z, XMaterial.matchXMaterial(mat), dataLegacy); + WLIB.warnDeprecatedUsage(); } + @Deprecated(forRemoval = true) public void place(final Location loc) { + WLIB.warnDeprecatedUsage(); final Location rel = loc.clone().add(this.x, this.y, this.z); final Block blk = rel.getBlock(); final Material _mat = this.mat.parseMaterial(); - if (mat != null) { - if (WLIB.getIsModernServer() && this.dataModern != null) { + if (mat != null && blk != null) { + if (WLIB.getIsModernServer() && this.dataModern != null && _mat != null) { final Object data = MirrorSafe.invokeMethod(Bukkit.class, "createBlockData", new Object[] { "minecraft:" + _mat.name().toLowerCase() + this.dataModern }); MirrorSafe.invokeMethod(Block.class, blk, "setBlockData", data, false); } else { @@ -83,31 +98,45 @@ public void place(final Location loc) { } } + @Deprecated(forRemoval = true) public final int getX() { + WLIB.warnDeprecatedUsage(); return x; } + @Deprecated(forRemoval = true) public final int getY() { + WLIB.warnDeprecatedUsage(); return y; } + @Deprecated(forRemoval = true) public final int getZ() { + WLIB.warnDeprecatedUsage(); return z; } + @Deprecated(forRemoval = true) public final XMaterial getMaterial() { + WLIB.warnDeprecatedUsage(); return mat; } + @Deprecated(forRemoval = true) public final Material getBukkitMaterial() { + WLIB.warnDeprecatedUsage(); return mat.parseMaterial(); } + @Deprecated(forRemoval = true) public final String getDataModern() { + WLIB.warnDeprecatedUsage(); return dataModern; } + @Deprecated(forRemoval = true) public final byte getDataLegacy() { + WLIB.warnDeprecatedUsage(); return dataLegacy; } } diff --git a/src/main/java/xyz/webmc/wlib/api/structure/WeightedStructure.java b/src/main/java/xyz/webmc/wlib/api/structure/WeightedStructure.java index 66f8159..8ca0560 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/WeightedStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structure/WeightedStructure.java @@ -13,10 +13,16 @@ package xyz.webmc.wlib.api.structure; +import xyz.webmc.wlib.api.WLIB; + import dev.colbster937.util.WeightedObject; +@SuppressWarnings({ "removal" }) +@Deprecated(forRemoval = true) public final class WeightedStructure extends WeightedObject { + @Deprecated(forRemoval = true) public WeightedStructure(final AbstractBaseStructure structure, final int weight) { super(structure, weight); + WLIB.warnDeprecatedUsage(); } } diff --git a/src/main/java/xyz/webmc/wlib/api/structure/WeightedStructureTable.java b/src/main/java/xyz/webmc/wlib/api/structure/WeightedStructureTable.java index 5e777cc..98587d2 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/WeightedStructureTable.java +++ b/src/main/java/xyz/webmc/wlib/api/structure/WeightedStructureTable.java @@ -13,6 +13,7 @@ package xyz.webmc.wlib.api.structure; +import xyz.webmc.wlib.api.WLIB; import xyz.webmc.wlib.api.util.RNGUtil; import java.util.ArrayList; @@ -22,30 +23,43 @@ import dev.colbster937.util.WeightedObjectTable; import org.bukkit.Location; +@SuppressWarnings({ "removal" }) +@Deprecated(forRemoval = true) public final class WeightedStructureTable extends WeightedObjectTable { + @Deprecated(forRemoval = true) public WeightedStructureTable(final long seed, final WeightedStructure... structures) { super(seed, structures); + WLIB.warnDeprecatedUsage(); } + @Deprecated(forRemoval = true) public WeightedStructureTable(final WeightedStructure... structures) { this(RNGUtil.getRandomSeed(), structures); + WLIB.warnDeprecatedUsage(); } @SafeVarargs + @Deprecated(forRemoval = true) public WeightedStructureTable(final long seed, final Class... structures) { this(seed, weigh(structures)); + WLIB.warnDeprecatedUsage(); } @SafeVarargs + @Deprecated(forRemoval = true) public WeightedStructureTable(final Class... structures) { this(weigh(structures)); + WLIB.warnDeprecatedUsage(); } + @Deprecated(forRemoval = true) public void place(final Location loc) { + WLIB.warnDeprecatedUsage(); this.computeRandomObject().place(loc); } @SafeVarargs + @Deprecated(forRemoval = true) private static WeightedStructure[] weigh(final Class... structures) { final List lst = new ArrayList<>(); final int chance = 100 / structures.length; diff --git a/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructure.java new file mode 100644 index 0000000..bd1e8b3 --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructure.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.api.structures; + +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; + +public interface GenerableStructure { + int SEARCH_RADIUS = 64; + + boolean canGenerate(Location loc); + boolean canGenerate(Chunk chunk); + + default Location createLocation(final World world, final int chunkX, final int chunkZ) { + return new Location(world, chunkX << 4, 65, chunkZ << 4); + } + + default Location locateNearest(final Location pos) { + Location ret = null; + + if (pos != null && pos.getWorld() != null) { + final int centerChunkX = pos.getChunk().getX(); + final int centerChunkZ = pos.getChunk().getZ(); + final World world = pos.getWorld(); + + search: + for (int radius = 0; radius <= SEARCH_RADIUS; radius++) { + final int minX = centerChunkX - radius; + final int maxX = centerChunkX + radius; + final int minZ = centerChunkZ - radius; + final int maxZ = centerChunkZ + radius; + + for (int chunkX = minX; chunkX <= maxX; chunkX++) { + for (final int chunkZ : new int[] { minZ, maxZ }) { + final Location candidate = createLocation(world, chunkX, chunkZ); + if (canGenerate(candidate)) { + ret = candidate; + break search; + } + } + } + + for (int chunkZ = minZ + 1; chunkZ < maxZ; chunkZ++) { + for (final int chunkX : new int[] { minX, maxX }) { + final Location candidate = createLocation(world, chunkX, chunkZ); + if (canGenerate(candidate)) { + ret = candidate; + break search; + } + } + } + } + } + + return ret; + } +} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java new file mode 100644 index 0000000..bd8e6d3 --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.api.structures; + +import xyz.webmc.wlib.api.structures.placeble.LocatedPlacebleStructure; + +import org.bukkit.Chunk; +import org.bukkit.Location; + +public abstract class LocatedStructure extends Structure { + public abstract LocatedPlacebleStructure build(Location loc); + + @Override + public final void place(Location loc) { + build(loc).place(); + } + + @Override + public final void place(Location loc, Chunk chunk) { + build(loc).place(chunk); + } +} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/RelativeStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/RelativeStructure.java new file mode 100644 index 0000000..5bdb11d --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structures/RelativeStructure.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.api.structures; + +import xyz.webmc.wlib.api.structures.placeble.RelativePlacebleStructure; + +import org.bukkit.Chunk; +import org.bukkit.Location; + +public abstract class RelativeStructure extends Structure { + public abstract RelativePlacebleStructure build(); + + @Override + public final void place(Location loc) { + build().place(loc); + } + + @Override + public final void place(Location loc, Chunk chunk) { + build().place(loc, chunk); + } +} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/Structure.java b/src/main/java/xyz/webmc/wlib/api/structures/Structure.java new file mode 100644 index 0000000..c379a70 --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structures/Structure.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.api.structures; + +import java.util.HashMap; +import java.util.Map; + +import dev.colbster937.reflect.MirrorSafe; +import org.bukkit.Chunk; +import org.bukkit.Location; + +public abstract class Structure { + private static final Map, Structure> INSTANCES = new HashMap<>(); + + public abstract String getName(); + + public abstract void place(Location loc); + + public abstract void place(Location loc, Chunk chunk); + + public static final T getInstance(final Class clazz, final Object... params) { + Structure structure = INSTANCES.get(clazz); + + if (structure == null) { + structure = MirrorSafe.invokeConstructor(clazz, params); + INSTANCES.put(clazz, structure); + } + + return (T) structure; + } +} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/blocks/Block.java b/src/main/java/xyz/webmc/wlib/api/structures/blocks/Block.java new file mode 100644 index 0000000..6dbc3fc --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structures/blocks/Block.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.api.structures.blocks; + +import xyz.webmc.wlib.api.WLIB; + +import com.cryptomorin.xseries.XMaterial; +import dev.colbster937.reflect.MirrorSafe; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; + +public class Block { + protected final XMaterial mat; + protected final String dataModern; + protected final byte dataLegacy; + + protected Block(final XMaterial mat, final String dataModern, final byte dataLegacy) { + this.mat = mat; + this.dataModern = dataModern; + this.dataLegacy = dataLegacy; + } + + protected void place(final Location loc) { + final org.bukkit.block.Block blk = loc.getBlock(); + final Material _mat = this.mat.get(); + + if (mat != null) { + if (WLIB.getIsModernServer() && this.dataModern != null && _mat != null) { + final Object data = MirrorSafe.invokeMethod(Bukkit.class, "createBlockData", + new Object[] { "minecraft:" + _mat.name().toLowerCase() + this.dataModern }); + MirrorSafe.invokeMethod(org.bukkit.block.Block.class, blk, "setBlockData", data, false); + } else { + blk.setType(_mat, false); + } + } + } + + public final XMaterial getMaterial() { + return mat; + } + + public final Material getBukkitMaterial() { + return mat.get(); + } + + public final String getDataModern() { + return dataModern; + } + + public final byte getDataLegacy() { + return dataLegacy; + } +} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java b/src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java new file mode 100644 index 0000000..fff9856 --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.api.structures.blocks; + +import com.cryptomorin.xseries.XMaterial; +import org.bukkit.Location; +import org.bukkit.Material; + +public class LocatedBlock extends Block { + private final Location loc; + + LocatedBlock(final Location loc, final XMaterial mat, final String dataModern, final byte dataLegacy) { + super(mat, dataModern, dataLegacy); + this.loc = loc; + } + + public LocatedBlock(final int x, final int y, final int z, final XMaterial mat) { + this(new Location(null, x, y, z), mat, null, (byte) 0); + } + + public LocatedBlock(final int x, final int y, final int z, final Material mat) { + this(x, y, z, XMaterial.matchXMaterial(mat)); + } + + public LocatedBlock(final int x, final int y, final int z, final XMaterial mat, final String dataModern) { + this(new Location(null, x, y, z), mat, dataModern, (byte) 0); + } + + public LocatedBlock(final int x, final int y, final int z, final Material mat, final String dataModern) { + this(x, y, z, XMaterial.matchXMaterial(mat), dataModern); + } + + public LocatedBlock(final int x, final int y, final int z, final XMaterial mat, final byte dataLegacy) { + this(new Location(null, x, y, z), mat, null, dataLegacy); + } + + public LocatedBlock(final int x, final int y, final int z, final Material mat, final byte dataLegacy) { + this(x, y, z, XMaterial.matchXMaterial(mat), dataLegacy); + } + + public final int getX() { + return this.loc.getBlockX(); + } + + public final int getY() { + return this.loc.getBlockY(); + } + + public final int getZ() { + return this.loc.getBlockZ(); + } + + public final Location getLocation() { + return this.loc; + } + + public void place() { + super.place(this.loc); + } + + public final RelativeBlock toRelative(final Location newRelativeOrigin) { + return new RelativeBlock( + this.loc.getBlockX() - newRelativeOrigin.getBlockX(), + this.loc.getBlockY() - newRelativeOrigin.getBlockY(), + this.loc.getBlockZ() - newRelativeOrigin.getBlockZ(), + this.mat, + this.dataModern, + this.dataLegacy); + } +} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java b/src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java new file mode 100644 index 0000000..b787daf --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.api.structures.blocks; + +import com.cryptomorin.xseries.XMaterial; +import org.bukkit.Material; + +public class RelativeBlock extends Block { + private final int x; + private final int y; + private final int z; + + RelativeBlock(final int x, final int y, final int z, final XMaterial mat, final String dataModern, + final byte dataLegacy) { + super(mat, dataModern, dataLegacy); + this.x = x; + this.y = y; + this.z = z; + } + + public RelativeBlock(final int x, final int y, final int z, final XMaterial mat) { + this(x, y, z, mat, null, (byte) 0); + } + + public RelativeBlock(final int x, final int y, final int z, final Material mat) { + this(x, y, z, XMaterial.matchXMaterial(mat)); + } + + public RelativeBlock(final int x, final int y, final int z, final XMaterial mat, final String dataModern) { + this(x, y, z, mat, dataModern, (byte) 0); + } + + public RelativeBlock(final int x, final int y, final int z, final Material mat, final String dataModern) { + this(x, y, z, XMaterial.matchXMaterial(mat), dataModern); + } + + public RelativeBlock(final int x, final int y, final int z, final XMaterial mat, final byte dataLegacy) { + this(x, y, z, mat, null, dataLegacy); + } + + public RelativeBlock(final int x, final int y, final int z, final Material mat, final byte dataLegacy) { + this(x, y, z, XMaterial.matchXMaterial(mat), dataLegacy); + } + + public final int getX() { + return x; + } + + public final int getY() { + return y; + } + + public final int getZ() { + return z; + } + + @Override + public void place(final org.bukkit.Location loc) { + super.place(loc.clone().add(x, y, z)); + } + + public final LocatedBlock toLocated(final org.bukkit.Location relativeOrigin) { + return new LocatedBlock( + relativeOrigin.clone().add(x, y, z), + this.mat, + this.dataModern, + this.dataLegacy); + } +} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/placeble/LocatedPlacebleStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/placeble/LocatedPlacebleStructure.java new file mode 100644 index 0000000..f06f709 --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structures/placeble/LocatedPlacebleStructure.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.api.structures.placeble; + +import xyz.webmc.wlib.api.misc.SchemLoadingError; +import xyz.webmc.wlib.api.structures.blocks.LocatedBlock; +import xyz.webmc.wlib.api.structures.blocks.RelativeBlock; +import xyz.webmc.wlib.api.util.SchemUtil; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Map; + +import com.cryptomorin.xseries.XMaterial; +import net.sandrohc.schematic4j.exception.ParsingException; +import net.sandrohc.schematic4j.schematic.Schematic; +import net.sandrohc.schematic4j.schematic.types.SchematicBlock; +import net.sandrohc.schematic4j.schematic.types.SchematicBlockPos; +import org.bukkit.Chunk; +import org.bukkit.Location; + +public class LocatedPlacebleStructure extends PlacebleStructure { + private final Location location; + + public LocatedPlacebleStructure(Location location) { + super(new ArrayList<>()); + this.location = location; + } + + public void place() { + for (final LocatedBlock block : this.blocks) { + block.place(); + } + } + + public void place(Chunk chunk) { + for (final LocatedBlock block : this.blocks) { + final Location blockLocation = block.getLocation(); + if (blockLocation.getWorld() == chunk.getWorld() + && block.getX() >> 4 == chunk.getX() + && block.getZ() >> 4 == chunk.getZ()) { + block.place(); + } + } + } + + @Override + public void loadSchematic(InputStream stream, int offsetx, int offsety, int offsetz) throws SchemLoadingError { + try (stream) { + final Schematic schematic = SchemUtil.readSchematic(stream); + final SchematicBlockPos offset = schematic.offset(); + + for (int y = 0; y < schematic.height(); y++) { + for (int z = 0; z < schematic.length(); z++) { + for (int x = 0; x < schematic.width(); x++) { + final SchematicBlock block = schematic.block(x, y, z); + if (block != SchematicBlock.AIR) { + final XMaterial material = XMaterial.matchXMaterial(block.block().replace("minecraft:", "")) + .orElse(XMaterial.AIR); + final StringBuilder data = new StringBuilder(); + + for (final Map.Entry entry : block.states().entrySet()) { + if (data.length() > 0) { + data.append(","); + } + data.append(entry.getKey()).append("=").append(entry.getValue()); + } + + final RelativeBlock relativeBlock = new RelativeBlock( + x - offset.x + offsetx, + y - offset.y + offsety, + z - offset.z + offsetz, + material, + "[" + data + "]"); + this.blocks.add(relativeBlock.toLocated(this.location)); + } + } + } + } + } catch (IOException | ParsingException exception) { + throw new SchemLoadingError("Failed to load schematic"); + } + } +} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/placeble/PlacebleStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/placeble/PlacebleStructure.java new file mode 100644 index 0000000..39807fe --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structures/placeble/PlacebleStructure.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.api.structures.placeble; + +import xyz.webmc.wlib.api.misc.SchemLoadingError; +import xyz.webmc.wlib.api.structures.blocks.Block; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@SuppressWarnings({ "unchecked" }) +public abstract class PlacebleStructure { + protected List blocks = new ArrayList<>(); + + protected PlacebleStructure(List blocks) { + this.blocks = blocks; + } + + public void addBlock(B blk) { + this.blocks.add(blk); + } + + public void addBlocks(Collection blks) { + this.blocks.addAll(blks); + } + + public void addBlocks(B... blks) { + this.blocks.addAll(List.of(blks)); + } + + public abstract void loadSchematic(InputStream stream, int offsetx, int offsety, int offsetz) + throws SchemLoadingError; + + public void loadSchematic(File file, int offsetx, int offsety, int offsetz) throws SchemLoadingError { + try (final FileInputStream fis = new FileInputStream(file)) { + this.loadSchematic(fis, offsetx, offsety, offsetz); + } catch (Exception e) { + throw new SchemLoadingError("Failed to load schematic from file: " + file.getAbsolutePath()); + } + } + + public void loadSchematic(InputStream stream) throws SchemLoadingError { + this.loadSchematic(stream, 0, 0, 0); + } + + public void loadSchematic(File file) throws SchemLoadingError { + this.loadSchematic(file, 0, 0, 0); + } +} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/placeble/RelativePlacebleStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/placeble/RelativePlacebleStructure.java new file mode 100644 index 0000000..32be274 --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structures/placeble/RelativePlacebleStructure.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.api.structures.placeble; + +import xyz.webmc.wlib.api.misc.SchemLoadingError; +import xyz.webmc.wlib.api.structures.blocks.RelativeBlock; +import xyz.webmc.wlib.api.util.SchemUtil; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Map; + +import com.cryptomorin.xseries.XMaterial; +import net.sandrohc.schematic4j.exception.ParsingException; +import net.sandrohc.schematic4j.schematic.Schematic; +import net.sandrohc.schematic4j.schematic.types.SchematicBlock; +import net.sandrohc.schematic4j.schematic.types.SchematicBlockPos; +import org.bukkit.Chunk; +import org.bukkit.Location; + +public class RelativePlacebleStructure extends PlacebleStructure { + public RelativePlacebleStructure() { + super(new ArrayList<>()); + } + + public void place(Location loc) { + for (final RelativeBlock block : this.blocks) { + block.place(loc); + } + } + + public void place(Location loc, Chunk chunk) { + for (final RelativeBlock block : this.blocks) { + final Location blockLocation = loc.clone().add(block.getX(), block.getY(), block.getZ()); + if (blockLocation.getWorld() == chunk.getWorld() + && blockLocation.getBlockX() >> 4 == chunk.getX() + && blockLocation.getBlockZ() >> 4 == chunk.getZ()) { + block.place(loc); + } + } + } + + @Override + public void loadSchematic(InputStream stream, int offsetx, int offsety, int offsetz) throws SchemLoadingError { + try (stream) { + final Schematic schematic = SchemUtil.readSchematic(stream); + final SchematicBlockPos offset = schematic.offset(); + + for (int y = 0; y < schematic.height(); y++) { + for (int z = 0; z < schematic.length(); z++) { + for (int x = 0; x < schematic.width(); x++) { + final SchematicBlock block = schematic.block(x, y, z); + if (block != SchematicBlock.AIR) { + final XMaterial material = XMaterial.matchXMaterial(block.block().replace("minecraft:", "")) + .orElse(XMaterial.AIR); + final StringBuilder data = new StringBuilder(); + + for (final Map.Entry entry : block.states().entrySet()) { + if (data.length() > 0) { + data.append(","); + } + data.append(entry.getKey()).append("=").append(entry.getValue()); + } + + this.blocks.add(new RelativeBlock( + x - offset.x + offsetx, + y - offset.y + offsety, + z - offset.z + offsetz, + material, + "[" + data + "]")); + } + } + } + } + } catch (IOException | ParsingException exception) { + throw new SchemLoadingError("Failed to load schematic"); + } + } +} diff --git a/src/main/java/xyz/webmc/wlib/internal/command/WLIBCommand.java b/src/main/java/xyz/webmc/wlib/internal/command/WLIBCommand.java index 1aa962e..b2f5108 100644 --- a/src/main/java/xyz/webmc/wlib/internal/command/WLIBCommand.java +++ b/src/main/java/xyz/webmc/wlib/internal/command/WLIBCommand.java @@ -15,12 +15,12 @@ import xyz.webmc.wlib.api.WLIB; import xyz.webmc.wlib.api.command.WCommand; -import xyz.webmc.wlib.api.structure.AbstractBaseStructure; +import xyz.webmc.wlib.api.structures.Structure; import xyz.webmc.wlib.api.util.PermissionUtil; import xyz.webmc.wlib.api.util.SchedulerUtil; import xyz.webmc.wlib.api.util.TextUtil; -import xyz.webmc.wlib.internal.structure.HerobrineShrineTestStructure; -import xyz.webmc.wlib.internal.structure.RickQRCodeTestSchemStructure; +import xyz.webmc.wlib.internal.structures.HerobrineShrineTestStructure; +import xyz.webmc.wlib.internal.structures.RickQRCodeTestStructure; import java.util.ArrayList; import java.util.List; @@ -76,19 +76,19 @@ public final boolean run(final CommandSender sender, final String label, final S bool1 = false; if (sender instanceof Player plr) { final String struct = args[2].trim(); - Class clazz = null; + Structure structure = null; if (struct.equals("shrine")) { - clazz = HerobrineShrineTestStructure.class; + structure = HerobrineShrineTestStructure.getInstance(); } else if (struct.equals("rick")) { - clazz = RickQRCodeTestSchemStructure.class; + structure = RickQRCodeTestStructure.getInstance(); } - if (clazz != null) { - final AbstractBaseStructure structure = AbstractBaseStructure.getInstance(clazz); + if (structure != null) { final Location loc = plr.getLocation(); structure.place(loc.clone()); - SchedulerUtil.teleportAsync(plr, loc.clone().add(1, 1, 0).getBlock().getLocation().clone().add(0.5D, 0, 0.5D)); + SchedulerUtil.teleportAsync(plr, + loc.clone().add(1, 1, 0).getBlock().getLocation().clone().add(0.5D, 0, 0.5D)); sender.sendMessage(ChatColor.GREEN + "Placed structure " + structure.getName()); } else { bool1 = true; @@ -118,32 +118,32 @@ public final List tab(final CommandSender sender, final String label, fi if (args.length > 0) { final List ret = new ArrayList<>(); - if (args.length == 1) { - if (sender.hasPermission("wlib.plugins")) { - ret.add("plugins"); - } - - if (sender.hasPermission("wlib.version")) { - ret.add("version"); - } - - if (sender.hasPermission("wlib.alerts.dev")) { - ret.add("alerts"); - } - - if (sender.hasPermission("wlib.debug")) { - ret.add("debug"); - } - } else if (args.length == 2) { - if (args[0].equals("debug") && sender.hasPermission("wlib.debug")) { - ret.add("throw"); - ret.add("place"); - } - } else if (args.length == 3) { - if (args[0].equals("debug") && args[1].equals("place") && sender.hasPermission("wlib.debug")) { - ret.add("shrine"); - ret.add("rick"); - } + switch (args.length) { + case 1 -> { + if (sender.hasPermission("wlib.plugins")) { + ret.add("plugins"); + } + if (sender.hasPermission("wlib.version")) { + ret.add("version"); + } + if (sender.hasPermission("wlib.alerts.dev")) { + ret.add("alerts"); + } + if (sender.hasPermission("wlib.debug")) { + ret.add("debug"); + } } + case 2 -> { + if (args[0].equals("debug") && sender.hasPermission("wlib.debug")) { + ret.add("throw"); + ret.add("place"); + } } + case 3 -> { + if (args[0].equals("debug") && args[1].equals("place") && sender.hasPermission("wlib.debug")) { + ret.add("shrine"); + ret.add("rick"); + } } + default -> { + } } return ret; diff --git a/src/main/java/xyz/webmc/wlib/internal/structure/HerobrineShrineTestStructure.java b/src/main/java/xyz/webmc/wlib/internal/structure/HerobrineShrineTestStructure.java index 0c08197..4d6e3b2 100644 --- a/src/main/java/xyz/webmc/wlib/internal/structure/HerobrineShrineTestStructure.java +++ b/src/main/java/xyz/webmc/wlib/internal/structure/HerobrineShrineTestStructure.java @@ -13,14 +13,19 @@ package xyz.webmc.wlib.internal.structure; +import xyz.webmc.wlib.api.WLIB; import xyz.webmc.wlib.api.structure.AbstractBaseStructure; import xyz.webmc.wlib.api.structure.BlockRelative; import com.cryptomorin.xseries.XMaterial; +@Deprecated(forRemoval = true) +@SuppressWarnings({ "removal" }) public final class HerobrineShrineTestStructure extends AbstractBaseStructure { + @Deprecated(forRemoval = true) public HerobrineShrineTestStructure() { super("herobrine_shrine"); + WLIB.warnDeprecatedUsage(); for (int y = 0; y < 3; y++) { for (int x = -1; x < 2; x++) { @@ -41,7 +46,9 @@ public HerobrineShrineTestStructure() { } } + @Deprecated(forRemoval = true) public static HerobrineShrineTestStructure getInstance() { + WLIB.warnDeprecatedUsage(); return getInstance(HerobrineShrineTestStructure.class); } } diff --git a/src/main/java/xyz/webmc/wlib/internal/structure/RickQRCodeTestSchemStructure.java b/src/main/java/xyz/webmc/wlib/internal/structure/RickQRCodeTestSchemStructure.java index 21f7d24..4ec2a4d 100644 --- a/src/main/java/xyz/webmc/wlib/internal/structure/RickQRCodeTestSchemStructure.java +++ b/src/main/java/xyz/webmc/wlib/internal/structure/RickQRCodeTestSchemStructure.java @@ -13,6 +13,7 @@ package xyz.webmc.wlib.internal.structure; +import xyz.webmc.wlib.api.WLIB; import xyz.webmc.wlib.api.structure.AbstractBaseStructure; import java.io.IOException; @@ -20,15 +21,22 @@ import net.sandrohc.schematic4j.exception.ParsingException; +@Deprecated(forRemoval = true) +@SuppressWarnings({ "removal" }) public final class RickQRCodeTestSchemStructure extends AbstractBaseStructure { + @Deprecated(forRemoval = true) public RickQRCodeTestSchemStructure() throws IOException, ParsingException { super("rick_qr"); + WLIB.warnDeprecatedUsage(); + try (InputStream is = RickQRCodeTestSchemStructure.class.getResourceAsStream("/schematics/rick.schem")) { super.loadSchematic(is); } } + @Deprecated(forRemoval = true) public static RickQRCodeTestSchemStructure getInstance() { + WLIB.warnDeprecatedUsage(); return getInstance(RickQRCodeTestSchemStructure.class); } } diff --git a/src/main/java/xyz/webmc/wlib/internal/structures/HerobrineShrineTestStructure.java b/src/main/java/xyz/webmc/wlib/internal/structures/HerobrineShrineTestStructure.java new file mode 100644 index 0000000..38ca0ba --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/internal/structures/HerobrineShrineTestStructure.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.internal.structures; + +import xyz.webmc.wlib.api.structures.GenerableStructure; +import xyz.webmc.wlib.api.structures.RelativeStructure; +import xyz.webmc.wlib.api.structures.Structure; +import xyz.webmc.wlib.api.structures.blocks.RelativeBlock; +import xyz.webmc.wlib.api.structures.placeble.RelativePlacebleStructure; + +import com.cryptomorin.xseries.XMaterial; +import org.bukkit.Chunk; +import org.bukkit.Location; + +public final class HerobrineShrineTestStructure extends RelativeStructure implements GenerableStructure { + public static HerobrineShrineTestStructure getInstance() { + return Structure.getInstance(HerobrineShrineTestStructure.class); + } + + @Override + public boolean canGenerate(final Location loc) { + return true; + } + + @Override + public boolean canGenerate(final Chunk chunk) { + return true; + } + + @Override + public String getName() { + return "Herobrine Shrine Test Structure"; + } + + @Override + public RelativePlacebleStructure build(){ + final RelativePlacebleStructure structure = new RelativePlacebleStructure(); + + for (int y = 0; y < 3; y++) { + for (int x = -1; x < 2; x++) { + for (int z = -1; z < 2; z++) { + if (y == 0) { + structure.addBlock(new RelativeBlock(x, y, z, XMaterial.GOLD_BLOCK)); + } else if (y == 1) { + if (x != z && x + z != 0) { + structure.addBlock(new RelativeBlock(x, y, z, XMaterial.REDSTONE_TORCH)); + } else if (x == 0 && z == 0) { + structure.addBlock(new RelativeBlock(x, y, z, XMaterial.NETHERRACK)); + } + } else if (y == 2 && x == 0 && z == 0) { + structure.addBlock(new RelativeBlock(x, y, z, XMaterial.FIRE)); + } + } + } + } + + return structure; + } +} diff --git a/src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java b/src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java new file mode 100644 index 0000000..bf5db30 --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.internal.structures; + +import xyz.webmc.wlib.api.structures.RelativeStructure; +import xyz.webmc.wlib.api.structures.Structure; +import xyz.webmc.wlib.api.structures.placeble.RelativePlacebleStructure; + +import java.io.InputStream; + +public final class RickQRCodeTestStructure extends RelativeStructure { + public static RickQRCodeTestStructure getInstance() { + return Structure.getInstance(RickQRCodeTestStructure.class); + } + + @Override + public String getName() { + return "Rick QR Code Test Structure"; + } + + @Override + public RelativePlacebleStructure build() { + final RelativePlacebleStructure structure = new RelativePlacebleStructure(); + final InputStream stream = RickQRCodeTestStructure.class.getResourceAsStream("/schematics/rick.schem"); + structure.loadSchematic(stream); + return structure; + } +} From 5419c653765555d2e2f80b26871a420b02ab2e9c Mon Sep 17 00:00:00 2001 From: Colbster937 Date: Sat, 5 Sep 2026 14:49:24 -0500 Subject: [PATCH 02/12] chore: fix issues --- .../wlib/api/misc/SchemLoadingError.java | 20 ---- .../api/structures/GenerableStructure.java | 76 +++++++-------- .../wlib/api/structures/LocatedStructure.java | 4 +- .../api/structures/RelativeStructure.java | 20 ++-- .../webmc/wlib/api/structures/Structure.java | 7 +- .../wlib/api/structures/blocks/Block.java | 5 +- .../api/structures/blocks/LocatedBlock.java | 14 +-- .../api/structures/blocks/RelativeBlock.java | 17 ++-- .../placeable/LocatedPlaceableStructure.java | 93 ++++++++++++++++++ .../PlaceableStructure.java} | 20 ++-- .../placeable/RelativePlaceableStructure.java | 88 +++++++++++++++++ .../placeble/LocatedPlacebleStructure.java | 96 ------------------- .../placeble/RelativePlacebleStructure.java | 91 ------------------ .../HerobrineShrineTestStructure.java | 54 ----------- .../RickQRCodeTestSchemStructure.java | 42 -------- .../HerobrineShrineTestStructure.java | 11 +-- .../structures/RickQRCodeTestStructure.java | 11 +-- 17 files changed, 269 insertions(+), 400 deletions(-) delete mode 100644 src/main/java/xyz/webmc/wlib/api/misc/SchemLoadingError.java create mode 100644 src/main/java/xyz/webmc/wlib/api/structures/placeable/LocatedPlaceableStructure.java rename src/main/java/xyz/webmc/wlib/api/structures/{placeble/PlacebleStructure.java => placeable/PlaceableStructure.java} (69%) create mode 100644 src/main/java/xyz/webmc/wlib/api/structures/placeable/RelativePlaceableStructure.java delete mode 100644 src/main/java/xyz/webmc/wlib/api/structures/placeble/LocatedPlacebleStructure.java delete mode 100644 src/main/java/xyz/webmc/wlib/api/structures/placeble/RelativePlacebleStructure.java delete mode 100644 src/main/java/xyz/webmc/wlib/internal/structure/HerobrineShrineTestStructure.java delete mode 100644 src/main/java/xyz/webmc/wlib/internal/structure/RickQRCodeTestSchemStructure.java diff --git a/src/main/java/xyz/webmc/wlib/api/misc/SchemLoadingError.java b/src/main/java/xyz/webmc/wlib/api/misc/SchemLoadingError.java deleted file mode 100644 index 850b834..0000000 --- a/src/main/java/xyz/webmc/wlib/api/misc/SchemLoadingError.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2026 Colbster937 - * - * SPDX-License-Identifier: AGPL-3.0-or-later - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * See the LICENSE file for details. - */ - -package xyz.webmc.wlib.api.misc; - -public class SchemLoadingError extends RuntimeException { - public SchemLoadingError(String message) { - super(message); - } -} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructure.java index bd1e8b3..11fd44d 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructure.java @@ -18,52 +18,52 @@ import org.bukkit.World; public interface GenerableStructure { - int SEARCH_RADIUS = 64; + int SEARCH_RADIUS = 64; - boolean canGenerate(Location loc); - boolean canGenerate(Chunk chunk); + boolean canGenerate(Location loc); + boolean canGenerate(Chunk chunk); - default Location createLocation(final World world, final int chunkX, final int chunkZ) { - return new Location(world, chunkX << 4, 65, chunkZ << 4); - } - - default Location locateNearest(final Location pos) { - Location ret = null; + default Location createLocation(final World world, final int chunkX, final int chunkZ) { + return new Location(world, chunkX << 4, 65, chunkZ << 4); + } - if (pos != null && pos.getWorld() != null) { - final int centerChunkX = pos.getChunk().getX(); - final int centerChunkZ = pos.getChunk().getZ(); - final World world = pos.getWorld(); + default Location locateNearest(final Location pos) { + Location ret = null; - search: - for (int radius = 0; radius <= SEARCH_RADIUS; radius++) { - final int minX = centerChunkX - radius; - final int maxX = centerChunkX + radius; - final int minZ = centerChunkZ - radius; - final int maxZ = centerChunkZ + radius; + if (pos != null && pos.getWorld() != null) { + final int centerChunkX = pos.getChunk().getX(); + final int centerChunkZ = pos.getChunk().getZ(); + final World world = pos.getWorld(); - for (int chunkX = minX; chunkX <= maxX; chunkX++) { - for (final int chunkZ : new int[] { minZ, maxZ }) { - final Location candidate = createLocation(world, chunkX, chunkZ); - if (canGenerate(candidate)) { - ret = candidate; - break search; - } - } - } + search: + for (int radius = 0; radius <= SEARCH_RADIUS; radius++) { + final int minX = centerChunkX - radius; + final int maxX = centerChunkX + radius; + final int minZ = centerChunkZ - radius; + final int maxZ = centerChunkZ + radius; - for (int chunkZ = minZ + 1; chunkZ < maxZ; chunkZ++) { - for (final int chunkX : new int[] { minX, maxX }) { - final Location candidate = createLocation(world, chunkX, chunkZ); - if (canGenerate(candidate)) { - ret = candidate; - break search; - } - } - } + for (int chunkX = minX; chunkX <= maxX; chunkX++) { + for (final int chunkZ : new int[] { minZ, maxZ }) { + final Location loc = createLocation(world, chunkX, chunkZ); + if (canGenerate(loc)) { + ret = loc; + break search; } + } } - return ret; + for (int chunkZ = minZ + 1; chunkZ < maxZ; chunkZ++) { + for (final int chunkX : new int[] { minX, maxX }) { + final Location loc = createLocation(world, chunkX, chunkZ); + if (canGenerate(loc)) { + ret = loc; + break search; + } + } + } + } } + + return ret; + } } diff --git a/src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java index bd8e6d3..41af99b 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java @@ -13,13 +13,13 @@ package xyz.webmc.wlib.api.structures; -import xyz.webmc.wlib.api.structures.placeble.LocatedPlacebleStructure; +import xyz.webmc.wlib.api.structures.placeable.LocatedPlaceableStructure; import org.bukkit.Chunk; import org.bukkit.Location; public abstract class LocatedStructure extends Structure { - public abstract LocatedPlacebleStructure build(Location loc); + public abstract LocatedPlaceableStructure build(Location loc); @Override public final void place(Location loc) { diff --git a/src/main/java/xyz/webmc/wlib/api/structures/RelativeStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/RelativeStructure.java index 5bdb11d..c7f71bd 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/RelativeStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/RelativeStructure.java @@ -13,21 +13,21 @@ package xyz.webmc.wlib.api.structures; -import xyz.webmc.wlib.api.structures.placeble.RelativePlacebleStructure; +import xyz.webmc.wlib.api.structures.placeable.RelativePlaceableStructure; import org.bukkit.Chunk; import org.bukkit.Location; public abstract class RelativeStructure extends Structure { - public abstract RelativePlacebleStructure build(); + public abstract RelativePlaceableStructure build(); - @Override - public final void place(Location loc) { - build().place(loc); - } + @Override + public final void place(final Location loc) { + this.build().place(loc); + } - @Override - public final void place(Location loc, Chunk chunk) { - build().place(loc, chunk); - } + @Override + public final void place(final Location loc, final Chunk chunk) { + this.build().place(loc, chunk); + } } diff --git a/src/main/java/xyz/webmc/wlib/api/structures/Structure.java b/src/main/java/xyz/webmc/wlib/api/structures/Structure.java index c379a70..29cec19 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/Structure.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/Structure.java @@ -20,15 +20,18 @@ import org.bukkit.Chunk; import org.bukkit.Location; +@SuppressWarnings({ "unchecked" }) public abstract class Structure { private static final Map, Structure> INSTANCES = new HashMap<>(); - public abstract String getName(); - public abstract void place(Location loc); public abstract void place(Location loc, Chunk chunk); + public String getName() { + return this.getClass().getSimpleName(); + } + public static final T getInstance(final Class clazz, final Object... params) { Structure structure = INSTANCES.get(clazz); diff --git a/src/main/java/xyz/webmc/wlib/api/structures/blocks/Block.java b/src/main/java/xyz/webmc/wlib/api/structures/blocks/Block.java index 6dbc3fc..447d88e 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/blocks/Block.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/blocks/Block.java @@ -21,7 +21,7 @@ import org.bukkit.Location; import org.bukkit.Material; -public class Block { +public abstract class Block { protected final XMaterial mat; protected final String dataModern; protected final byte dataLegacy; @@ -38,8 +38,7 @@ protected void place(final Location loc) { if (mat != null) { if (WLIB.getIsModernServer() && this.dataModern != null && _mat != null) { - final Object data = MirrorSafe.invokeMethod(Bukkit.class, "createBlockData", - new Object[] { "minecraft:" + _mat.name().toLowerCase() + this.dataModern }); + final Object data = MirrorSafe.invokeMethod(Bukkit.class, "createBlockData", new Object[] { "minecraft:" + _mat.name().toLowerCase() + this.dataModern }); MirrorSafe.invokeMethod(org.bukkit.block.Block.class, blk, "setBlockData", data, false); } else { blk.setType(_mat, false); diff --git a/src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java b/src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java index fff9856..7839959 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java @@ -17,10 +17,10 @@ import org.bukkit.Location; import org.bukkit.Material; -public class LocatedBlock extends Block { +public final class LocatedBlock extends Block { private final Location loc; - LocatedBlock(final Location loc, final XMaterial mat, final String dataModern, final byte dataLegacy) { + public LocatedBlock(final Location loc, final XMaterial mat, final String dataModern, final byte dataLegacy) { super(mat, dataModern, dataLegacy); this.loc = loc; } @@ -49,19 +49,19 @@ public LocatedBlock(final int x, final int y, final int z, final Material mat, f this(x, y, z, XMaterial.matchXMaterial(mat), dataLegacy); } - public final int getX() { + public int getX() { return this.loc.getBlockX(); } - public final int getY() { + public int getY() { return this.loc.getBlockY(); } - public final int getZ() { + public int getZ() { return this.loc.getBlockZ(); } - public final Location getLocation() { + public Location getLocation() { return this.loc; } @@ -69,7 +69,7 @@ public void place() { super.place(this.loc); } - public final RelativeBlock toRelative(final Location newRelativeOrigin) { + public RelativeBlock toRelative(final Location newRelativeOrigin) { return new RelativeBlock( this.loc.getBlockX() - newRelativeOrigin.getBlockX(), this.loc.getBlockY() - newRelativeOrigin.getBlockY(), diff --git a/src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java b/src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java index b787daf..7ddb54d 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java @@ -14,15 +14,16 @@ package xyz.webmc.wlib.api.structures.blocks; import com.cryptomorin.xseries.XMaterial; + +import org.bukkit.Location; import org.bukkit.Material; -public class RelativeBlock extends Block { +public final class RelativeBlock extends Block { private final int x; private final int y; private final int z; - RelativeBlock(final int x, final int y, final int z, final XMaterial mat, final String dataModern, - final byte dataLegacy) { + public RelativeBlock(final int x, final int y, final int z, final XMaterial mat, final String dataModern, final byte dataLegacy) { super(mat, dataModern, dataLegacy); this.x = x; this.y = y; @@ -53,24 +54,24 @@ public RelativeBlock(final int x, final int y, final int z, final Material mat, this(x, y, z, XMaterial.matchXMaterial(mat), dataLegacy); } - public final int getX() { + public int getX() { return x; } - public final int getY() { + public int getY() { return y; } - public final int getZ() { + public int getZ() { return z; } @Override - public void place(final org.bukkit.Location loc) { + public void place(final Location loc) { super.place(loc.clone().add(x, y, z)); } - public final LocatedBlock toLocated(final org.bukkit.Location relativeOrigin) { + public LocatedBlock toLocated(final Location relativeOrigin) { return new LocatedBlock( relativeOrigin.clone().add(x, y, z), this.mat, diff --git a/src/main/java/xyz/webmc/wlib/api/structures/placeable/LocatedPlaceableStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/placeable/LocatedPlaceableStructure.java new file mode 100644 index 0000000..558d5f6 --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structures/placeable/LocatedPlaceableStructure.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.api.structures.placeable; + +import xyz.webmc.wlib.api.structures.blocks.LocatedBlock; +import xyz.webmc.wlib.api.structures.blocks.RelativeBlock; +import xyz.webmc.wlib.api.util.SchemUtil; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Map; + +import com.cryptomorin.xseries.XMaterial; +import net.sandrohc.schematic4j.exception.ParsingException; +import net.sandrohc.schematic4j.schematic.Schematic; +import net.sandrohc.schematic4j.schematic.types.SchematicBlock; +import net.sandrohc.schematic4j.schematic.types.SchematicBlockPos; +import org.bukkit.Chunk; +import org.bukkit.Location; + +public class LocatedPlaceableStructure extends PlaceableStructure { + private final Location location; + + public LocatedPlaceableStructure(Location location) { + super(new ArrayList<>()); + this.location = location; + } + + public void place() { + for (final LocatedBlock block : this.blocks) { + block.place(); + } + } + + public void place(Chunk chunk) { + for (final LocatedBlock block : this.blocks) { + final Location blockLocation = block.getLocation(); + if (blockLocation.getWorld() == chunk.getWorld() && block.getX() >> 4 == chunk.getX() && block.getZ() >> 4 == chunk.getZ()) { + block.place(); + } + } + } + + @Override + public void loadSchematic(InputStream stream, int offsetx, int offsety, int offsetz) { + try (stream) { + final Schematic schematic = SchemUtil.readSchematic(stream); + final SchematicBlockPos offset = schematic.offset(); + + for (int y = 0; y < schematic.height(); y++) { + for (int z = 0; z < schematic.length(); z++) { + for (int x = 0; x < schematic.width(); x++) { + final SchematicBlock block = schematic.block(x, y, z); + if (block != SchematicBlock.AIR) { + final XMaterial material = XMaterial.matchXMaterial(block.block().replace("minecraft:", "")).orElse(XMaterial.AIR); + final StringBuilder data = new StringBuilder(); + + for (final Map.Entry entry : block.states().entrySet()) { + if (data.length() > 0) { + data.append(","); + } + + data.append(entry.getKey()).append("=").append(entry.getValue()); + } + + final RelativeBlock relativeBlock = new RelativeBlock( + x - offset.x + offsetx, + y - offset.y + offsety, + z - offset.z + offsetz, + material, + "[" + data + "]"); + this.blocks.add(relativeBlock.toLocated(this.location)); + } + } + } + } + } catch (final IOException | ParsingException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/placeble/PlacebleStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/placeable/PlaceableStructure.java similarity index 69% rename from src/main/java/xyz/webmc/wlib/api/structures/placeble/PlacebleStructure.java rename to src/main/java/xyz/webmc/wlib/api/structures/placeable/PlaceableStructure.java index 39807fe..533276c 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/placeble/PlacebleStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/placeable/PlaceableStructure.java @@ -11,9 +11,8 @@ * See the LICENSE file for details. */ -package xyz.webmc.wlib.api.structures.placeble; +package xyz.webmc.wlib.api.structures.placeable; -import xyz.webmc.wlib.api.misc.SchemLoadingError; import xyz.webmc.wlib.api.structures.blocks.Block; import java.io.File; @@ -24,10 +23,10 @@ import java.util.List; @SuppressWarnings({ "unchecked" }) -public abstract class PlacebleStructure { +public abstract class PlaceableStructure { protected List blocks = new ArrayList<>(); - protected PlacebleStructure(List blocks) { + protected PlaceableStructure(List blocks) { this.blocks = blocks; } @@ -43,22 +42,21 @@ public void addBlocks(B... blks) { this.blocks.addAll(List.of(blks)); } - public abstract void loadSchematic(InputStream stream, int offsetx, int offsety, int offsetz) - throws SchemLoadingError; + public abstract void loadSchematic(InputStream stream, int offsetx, int offsety, int offsetz); - public void loadSchematic(File file, int offsetx, int offsety, int offsetz) throws SchemLoadingError { + public void loadSchematic(File file, int offsetx, int offsety, int offsetz) { try (final FileInputStream fis = new FileInputStream(file)) { this.loadSchematic(fis, offsetx, offsety, offsetz); - } catch (Exception e) { - throw new SchemLoadingError("Failed to load schematic from file: " + file.getAbsolutePath()); + } catch (final Exception ex) { + throw new RuntimeException(ex); } } - public void loadSchematic(InputStream stream) throws SchemLoadingError { + public void loadSchematic(InputStream stream) { this.loadSchematic(stream, 0, 0, 0); } - public void loadSchematic(File file) throws SchemLoadingError { + public void loadSchematic(File file) { this.loadSchematic(file, 0, 0, 0); } } diff --git a/src/main/java/xyz/webmc/wlib/api/structures/placeable/RelativePlaceableStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/placeable/RelativePlaceableStructure.java new file mode 100644 index 0000000..06785aa --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structures/placeable/RelativePlaceableStructure.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.api.structures.placeable; + +import xyz.webmc.wlib.api.structures.blocks.RelativeBlock; +import xyz.webmc.wlib.api.util.SchemUtil; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Map; + +import com.cryptomorin.xseries.XMaterial; +import net.sandrohc.schematic4j.exception.ParsingException; +import net.sandrohc.schematic4j.schematic.Schematic; +import net.sandrohc.schematic4j.schematic.types.SchematicBlock; +import net.sandrohc.schematic4j.schematic.types.SchematicBlockPos; +import org.bukkit.Chunk; +import org.bukkit.Location; + +public class RelativePlaceableStructure extends PlaceableStructure { + public RelativePlaceableStructure() { + super(new ArrayList<>()); + } + + public void place(Location loc) { + for (final RelativeBlock block : this.blocks) { + block.place(loc); + } + } + + public void place(Location loc, Chunk chunk) { + for (final RelativeBlock block : this.blocks) { + final Location blockLocation = loc.clone().add(block.getX(), block.getY(), block.getZ()); + if (blockLocation.getWorld() == chunk.getWorld() && blockLocation.getBlockX() >> 4 == chunk.getX() && blockLocation.getBlockZ() >> 4 == chunk.getZ()) { + block.place(loc); + } + } + } + + @Override + public void loadSchematic(InputStream stream, int offsetx, int offsety, int offsetz) { + try (stream) { + final Schematic schematic = SchemUtil.readSchematic(stream); + final SchematicBlockPos offset = schematic.offset(); + + for (int y = 0; y < schematic.height(); y++) { + for (int z = 0; z < schematic.length(); z++) { + for (int x = 0; x < schematic.width(); x++) { + final SchematicBlock block = schematic.block(x, y, z); + if (block != SchematicBlock.AIR) { + final XMaterial material = XMaterial.matchXMaterial(block.block().replace("minecraft:", "")).orElse(XMaterial.AIR); + final StringBuilder data = new StringBuilder(); + + for (final Map.Entry entry : block.states().entrySet()) { + if (data.length() > 0) { + data.append(","); + } + + data.append(entry.getKey()).append("=").append(entry.getValue()); + } + + this.blocks.add(new RelativeBlock( + x - offset.x + offsetx, + y - offset.y + offsety, + z - offset.z + offsetz, + material, + "[" + data + "]")); + } + } + } + } + } catch (final IOException | ParsingException ex) { + throw new RuntimeException(); + } + } +} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/placeble/LocatedPlacebleStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/placeble/LocatedPlacebleStructure.java deleted file mode 100644 index f06f709..0000000 --- a/src/main/java/xyz/webmc/wlib/api/structures/placeble/LocatedPlacebleStructure.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2026 Colbster937 - * - * SPDX-License-Identifier: AGPL-3.0-or-later - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * See the LICENSE file for details. - */ - -package xyz.webmc.wlib.api.structures.placeble; - -import xyz.webmc.wlib.api.misc.SchemLoadingError; -import xyz.webmc.wlib.api.structures.blocks.LocatedBlock; -import xyz.webmc.wlib.api.structures.blocks.RelativeBlock; -import xyz.webmc.wlib.api.util.SchemUtil; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Map; - -import com.cryptomorin.xseries.XMaterial; -import net.sandrohc.schematic4j.exception.ParsingException; -import net.sandrohc.schematic4j.schematic.Schematic; -import net.sandrohc.schematic4j.schematic.types.SchematicBlock; -import net.sandrohc.schematic4j.schematic.types.SchematicBlockPos; -import org.bukkit.Chunk; -import org.bukkit.Location; - -public class LocatedPlacebleStructure extends PlacebleStructure { - private final Location location; - - public LocatedPlacebleStructure(Location location) { - super(new ArrayList<>()); - this.location = location; - } - - public void place() { - for (final LocatedBlock block : this.blocks) { - block.place(); - } - } - - public void place(Chunk chunk) { - for (final LocatedBlock block : this.blocks) { - final Location blockLocation = block.getLocation(); - if (blockLocation.getWorld() == chunk.getWorld() - && block.getX() >> 4 == chunk.getX() - && block.getZ() >> 4 == chunk.getZ()) { - block.place(); - } - } - } - - @Override - public void loadSchematic(InputStream stream, int offsetx, int offsety, int offsetz) throws SchemLoadingError { - try (stream) { - final Schematic schematic = SchemUtil.readSchematic(stream); - final SchematicBlockPos offset = schematic.offset(); - - for (int y = 0; y < schematic.height(); y++) { - for (int z = 0; z < schematic.length(); z++) { - for (int x = 0; x < schematic.width(); x++) { - final SchematicBlock block = schematic.block(x, y, z); - if (block != SchematicBlock.AIR) { - final XMaterial material = XMaterial.matchXMaterial(block.block().replace("minecraft:", "")) - .orElse(XMaterial.AIR); - final StringBuilder data = new StringBuilder(); - - for (final Map.Entry entry : block.states().entrySet()) { - if (data.length() > 0) { - data.append(","); - } - data.append(entry.getKey()).append("=").append(entry.getValue()); - } - - final RelativeBlock relativeBlock = new RelativeBlock( - x - offset.x + offsetx, - y - offset.y + offsety, - z - offset.z + offsetz, - material, - "[" + data + "]"); - this.blocks.add(relativeBlock.toLocated(this.location)); - } - } - } - } - } catch (IOException | ParsingException exception) { - throw new SchemLoadingError("Failed to load schematic"); - } - } -} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/placeble/RelativePlacebleStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/placeble/RelativePlacebleStructure.java deleted file mode 100644 index 32be274..0000000 --- a/src/main/java/xyz/webmc/wlib/api/structures/placeble/RelativePlacebleStructure.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2026 Colbster937 - * - * SPDX-License-Identifier: AGPL-3.0-or-later - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * See the LICENSE file for details. - */ - -package xyz.webmc.wlib.api.structures.placeble; - -import xyz.webmc.wlib.api.misc.SchemLoadingError; -import xyz.webmc.wlib.api.structures.blocks.RelativeBlock; -import xyz.webmc.wlib.api.util.SchemUtil; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Map; - -import com.cryptomorin.xseries.XMaterial; -import net.sandrohc.schematic4j.exception.ParsingException; -import net.sandrohc.schematic4j.schematic.Schematic; -import net.sandrohc.schematic4j.schematic.types.SchematicBlock; -import net.sandrohc.schematic4j.schematic.types.SchematicBlockPos; -import org.bukkit.Chunk; -import org.bukkit.Location; - -public class RelativePlacebleStructure extends PlacebleStructure { - public RelativePlacebleStructure() { - super(new ArrayList<>()); - } - - public void place(Location loc) { - for (final RelativeBlock block : this.blocks) { - block.place(loc); - } - } - - public void place(Location loc, Chunk chunk) { - for (final RelativeBlock block : this.blocks) { - final Location blockLocation = loc.clone().add(block.getX(), block.getY(), block.getZ()); - if (blockLocation.getWorld() == chunk.getWorld() - && blockLocation.getBlockX() >> 4 == chunk.getX() - && blockLocation.getBlockZ() >> 4 == chunk.getZ()) { - block.place(loc); - } - } - } - - @Override - public void loadSchematic(InputStream stream, int offsetx, int offsety, int offsetz) throws SchemLoadingError { - try (stream) { - final Schematic schematic = SchemUtil.readSchematic(stream); - final SchematicBlockPos offset = schematic.offset(); - - for (int y = 0; y < schematic.height(); y++) { - for (int z = 0; z < schematic.length(); z++) { - for (int x = 0; x < schematic.width(); x++) { - final SchematicBlock block = schematic.block(x, y, z); - if (block != SchematicBlock.AIR) { - final XMaterial material = XMaterial.matchXMaterial(block.block().replace("minecraft:", "")) - .orElse(XMaterial.AIR); - final StringBuilder data = new StringBuilder(); - - for (final Map.Entry entry : block.states().entrySet()) { - if (data.length() > 0) { - data.append(","); - } - data.append(entry.getKey()).append("=").append(entry.getValue()); - } - - this.blocks.add(new RelativeBlock( - x - offset.x + offsetx, - y - offset.y + offsety, - z - offset.z + offsetz, - material, - "[" + data + "]")); - } - } - } - } - } catch (IOException | ParsingException exception) { - throw new SchemLoadingError("Failed to load schematic"); - } - } -} diff --git a/src/main/java/xyz/webmc/wlib/internal/structure/HerobrineShrineTestStructure.java b/src/main/java/xyz/webmc/wlib/internal/structure/HerobrineShrineTestStructure.java deleted file mode 100644 index 4d6e3b2..0000000 --- a/src/main/java/xyz/webmc/wlib/internal/structure/HerobrineShrineTestStructure.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2026 Colbster937 - * - * SPDX-License-Identifier: AGPL-3.0-or-later - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * See the LICENSE file for details. - */ - -package xyz.webmc.wlib.internal.structure; - -import xyz.webmc.wlib.api.WLIB; -import xyz.webmc.wlib.api.structure.AbstractBaseStructure; -import xyz.webmc.wlib.api.structure.BlockRelative; - -import com.cryptomorin.xseries.XMaterial; - -@Deprecated(forRemoval = true) -@SuppressWarnings({ "removal" }) -public final class HerobrineShrineTestStructure extends AbstractBaseStructure { - @Deprecated(forRemoval = true) - public HerobrineShrineTestStructure() { - super("herobrine_shrine"); - WLIB.warnDeprecatedUsage(); - - for (int y = 0; y < 3; y++) { - for (int x = -1; x < 2; x++) { - for (int z = -1; z < 2; z++) { - if (y == 0) { - super.addBlock(new BlockRelative(x, y, z, XMaterial.GOLD_BLOCK)); - } else if (y == 1) { - if (x != z && x + z != 0) { - super.addBlock(new BlockRelative(x, y, z, XMaterial.REDSTONE_TORCH)); - } else if (x == 0 && z == 0) { - super.addBlock(new BlockRelative(x, y, z, XMaterial.NETHERRACK)); - } - } else if (y == 2 && x == 0 && z == 0) { - super.addBlock(new BlockRelative(x, y, z, XMaterial.FIRE)); - } - } - } - } - } - - @Deprecated(forRemoval = true) - public static HerobrineShrineTestStructure getInstance() { - WLIB.warnDeprecatedUsage(); - return getInstance(HerobrineShrineTestStructure.class); - } -} diff --git a/src/main/java/xyz/webmc/wlib/internal/structure/RickQRCodeTestSchemStructure.java b/src/main/java/xyz/webmc/wlib/internal/structure/RickQRCodeTestSchemStructure.java deleted file mode 100644 index 4ec2a4d..0000000 --- a/src/main/java/xyz/webmc/wlib/internal/structure/RickQRCodeTestSchemStructure.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2026 Colbster937 - * - * SPDX-License-Identifier: AGPL-3.0-or-later - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * See the LICENSE file for details. - */ - -package xyz.webmc.wlib.internal.structure; - -import xyz.webmc.wlib.api.WLIB; -import xyz.webmc.wlib.api.structure.AbstractBaseStructure; - -import java.io.IOException; -import java.io.InputStream; - -import net.sandrohc.schematic4j.exception.ParsingException; - -@Deprecated(forRemoval = true) -@SuppressWarnings({ "removal" }) -public final class RickQRCodeTestSchemStructure extends AbstractBaseStructure { - @Deprecated(forRemoval = true) - public RickQRCodeTestSchemStructure() throws IOException, ParsingException { - super("rick_qr"); - WLIB.warnDeprecatedUsage(); - - try (InputStream is = RickQRCodeTestSchemStructure.class.getResourceAsStream("/schematics/rick.schem")) { - super.loadSchematic(is); - } - } - - @Deprecated(forRemoval = true) - public static RickQRCodeTestSchemStructure getInstance() { - WLIB.warnDeprecatedUsage(); - return getInstance(RickQRCodeTestSchemStructure.class); - } -} diff --git a/src/main/java/xyz/webmc/wlib/internal/structures/HerobrineShrineTestStructure.java b/src/main/java/xyz/webmc/wlib/internal/structures/HerobrineShrineTestStructure.java index 38ca0ba..cda7e06 100644 --- a/src/main/java/xyz/webmc/wlib/internal/structures/HerobrineShrineTestStructure.java +++ b/src/main/java/xyz/webmc/wlib/internal/structures/HerobrineShrineTestStructure.java @@ -17,7 +17,7 @@ import xyz.webmc.wlib.api.structures.RelativeStructure; import xyz.webmc.wlib.api.structures.Structure; import xyz.webmc.wlib.api.structures.blocks.RelativeBlock; -import xyz.webmc.wlib.api.structures.placeble.RelativePlacebleStructure; +import xyz.webmc.wlib.api.structures.placeable.RelativePlaceableStructure; import com.cryptomorin.xseries.XMaterial; import org.bukkit.Chunk; @@ -39,13 +39,8 @@ public boolean canGenerate(final Chunk chunk) { } @Override - public String getName() { - return "Herobrine Shrine Test Structure"; - } - - @Override - public RelativePlacebleStructure build(){ - final RelativePlacebleStructure structure = new RelativePlacebleStructure(); + public RelativePlaceableStructure build() { + final RelativePlaceableStructure structure = new RelativePlaceableStructure(); for (int y = 0; y < 3; y++) { for (int x = -1; x < 2; x++) { diff --git a/src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java b/src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java index bf5db30..a0d2184 100644 --- a/src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java +++ b/src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java @@ -15,7 +15,7 @@ import xyz.webmc.wlib.api.structures.RelativeStructure; import xyz.webmc.wlib.api.structures.Structure; -import xyz.webmc.wlib.api.structures.placeble.RelativePlacebleStructure; +import xyz.webmc.wlib.api.structures.placeable.RelativePlaceableStructure; import java.io.InputStream; @@ -25,13 +25,8 @@ public static RickQRCodeTestStructure getInstance() { } @Override - public String getName() { - return "Rick QR Code Test Structure"; - } - - @Override - public RelativePlacebleStructure build() { - final RelativePlacebleStructure structure = new RelativePlacebleStructure(); + public RelativePlaceableStructure build() { + final RelativePlaceableStructure structure = new RelativePlaceableStructure(); final InputStream stream = RickQRCodeTestStructure.class.getResourceAsStream("/schematics/rick.schem"); structure.loadSchematic(stream); return structure; From c58e3b6731b790d7ad8403ba5dfb1764b0c2c42b Mon Sep 17 00:00:00 2001 From: noone Date: Sun, 6 Sep 2026 15:50:29 +0200 Subject: [PATCH 03/12] feat: made blocks not final + rename Block to PlaceableBlock --- .../xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java | 2 +- .../structures/blocks/{Block.java => PlaceableBlock.java} | 4 ++-- .../xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java | 5 +++-- .../wlib/api/structures/placeable/PlaceableStructure.java | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) rename src/main/java/xyz/webmc/wlib/api/structures/blocks/{Block.java => PlaceableBlock.java} (92%) diff --git a/src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java b/src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java index 7839959..9a66366 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java @@ -17,7 +17,7 @@ import org.bukkit.Location; import org.bukkit.Material; -public final class LocatedBlock extends Block { +public class LocatedBlock extends PlaceableBlock { private final Location loc; public LocatedBlock(final Location loc, final XMaterial mat, final String dataModern, final byte dataLegacy) { diff --git a/src/main/java/xyz/webmc/wlib/api/structures/blocks/Block.java b/src/main/java/xyz/webmc/wlib/api/structures/blocks/PlaceableBlock.java similarity index 92% rename from src/main/java/xyz/webmc/wlib/api/structures/blocks/Block.java rename to src/main/java/xyz/webmc/wlib/api/structures/blocks/PlaceableBlock.java index 447d88e..fee4494 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/blocks/Block.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/blocks/PlaceableBlock.java @@ -21,12 +21,12 @@ import org.bukkit.Location; import org.bukkit.Material; -public abstract class Block { +public abstract class PlaceableBlock { protected final XMaterial mat; protected final String dataModern; protected final byte dataLegacy; - protected Block(final XMaterial mat, final String dataModern, final byte dataLegacy) { + protected PlaceableBlock(final XMaterial mat, final String dataModern, final byte dataLegacy) { this.mat = mat; this.dataModern = dataModern; this.dataLegacy = dataLegacy; diff --git a/src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java b/src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java index 7ddb54d..13662ab 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java @@ -18,12 +18,13 @@ import org.bukkit.Location; import org.bukkit.Material; -public final class RelativeBlock extends Block { +public class RelativeBlock extends PlaceableBlock { private final int x; private final int y; private final int z; - public RelativeBlock(final int x, final int y, final int z, final XMaterial mat, final String dataModern, final byte dataLegacy) { + public RelativeBlock(final int x, final int y, final int z, final XMaterial mat, final String dataModern, + final byte dataLegacy) { super(mat, dataModern, dataLegacy); this.x = x; this.y = y; diff --git a/src/main/java/xyz/webmc/wlib/api/structures/placeable/PlaceableStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/placeable/PlaceableStructure.java index 533276c..9acaef7 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/placeable/PlaceableStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/placeable/PlaceableStructure.java @@ -13,7 +13,7 @@ package xyz.webmc.wlib.api.structures.placeable; -import xyz.webmc.wlib.api.structures.blocks.Block; +import xyz.webmc.wlib.api.structures.blocks.PlaceableBlock; import java.io.File; import java.io.FileInputStream; @@ -23,7 +23,7 @@ import java.util.List; @SuppressWarnings({ "unchecked" }) -public abstract class PlaceableStructure { +public abstract class PlaceableStructure { protected List blocks = new ArrayList<>(); protected PlaceableStructure(List blocks) { From c885b6e0252f80a8e6b5f2583251b53ff90076c9 Mon Sep 17 00:00:00 2001 From: noone-075 Date: Sun, 6 Sep 2026 21:44:47 +0200 Subject: [PATCH 04/12] fix: fixed everything that wasnt fixed --- pom.xml | 2 +- .../wlib/api/structures/LocatedStructure.java | 18 +++---- .../wlib/internal/command/WLIBCommand.java | 52 +++++++++---------- .../HerobrineShrineTestStructure.java | 8 +-- .../structures/RickQRCodeTestStructure.java | 8 +-- 5 files changed, 44 insertions(+), 44 deletions(-) diff --git a/pom.xml b/pom.xml index bf70763..3ca78f8 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 xyz.webmc wlib - 1.3.1-SNAPSHOT + 1.2.9-SNAPSHOT github diff --git a/src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java index 41af99b..5cd032f 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java @@ -19,15 +19,15 @@ import org.bukkit.Location; public abstract class LocatedStructure extends Structure { - public abstract LocatedPlaceableStructure build(Location loc); + public abstract LocatedPlaceableStructure build(Location loc); - @Override - public final void place(Location loc) { - build(loc).place(); - } + @Override + public final void place(Location loc) { + build(loc).place(); + } - @Override - public final void place(Location loc, Chunk chunk) { - build(loc).place(chunk); - } + @Override + public final void place(Location loc, Chunk chunk) { + build(loc).place(chunk); + } } diff --git a/src/main/java/xyz/webmc/wlib/internal/command/WLIBCommand.java b/src/main/java/xyz/webmc/wlib/internal/command/WLIBCommand.java index b2f5108..98f63a6 100644 --- a/src/main/java/xyz/webmc/wlib/internal/command/WLIBCommand.java +++ b/src/main/java/xyz/webmc/wlib/internal/command/WLIBCommand.java @@ -118,32 +118,32 @@ public final List tab(final CommandSender sender, final String label, fi if (args.length > 0) { final List ret = new ArrayList<>(); - switch (args.length) { - case 1 -> { - if (sender.hasPermission("wlib.plugins")) { - ret.add("plugins"); - } - if (sender.hasPermission("wlib.version")) { - ret.add("version"); - } - if (sender.hasPermission("wlib.alerts.dev")) { - ret.add("alerts"); - } - if (sender.hasPermission("wlib.debug")) { - ret.add("debug"); - } } - case 2 -> { - if (args[0].equals("debug") && sender.hasPermission("wlib.debug")) { - ret.add("throw"); - ret.add("place"); - } } - case 3 -> { - if (args[0].equals("debug") && args[1].equals("place") && sender.hasPermission("wlib.debug")) { - ret.add("shrine"); - ret.add("rick"); - } } - default -> { - } + if (args.length == 1) { + if (sender.hasPermission("wlib.plugins")) { + ret.add("plugins"); + } + + if (sender.hasPermission("wlib.version")) { + ret.add("version"); + } + + if (sender.hasPermission("wlib.alerts.dev")) { + ret.add("alerts"); + } + + if (sender.hasPermission("wlib.debug")) { + ret.add("debug"); + } + } else if (args.length == 2) { + if (args[0].equals("debug") && sender.hasPermission("wlib.debug")) { + ret.add("throw"); + ret.add("place"); + } + } else if (args.length == 3) { + if (args[0].equals("debug") && args[1].equals("place") && sender.hasPermission("wlib.debug")) { + ret.add("shrine"); + ret.add("rick"); + } } return ret; diff --git a/src/main/java/xyz/webmc/wlib/internal/structures/HerobrineShrineTestStructure.java b/src/main/java/xyz/webmc/wlib/internal/structures/HerobrineShrineTestStructure.java index cda7e06..fce9691 100644 --- a/src/main/java/xyz/webmc/wlib/internal/structures/HerobrineShrineTestStructure.java +++ b/src/main/java/xyz/webmc/wlib/internal/structures/HerobrineShrineTestStructure.java @@ -24,10 +24,6 @@ import org.bukkit.Location; public final class HerobrineShrineTestStructure extends RelativeStructure implements GenerableStructure { - public static HerobrineShrineTestStructure getInstance() { - return Structure.getInstance(HerobrineShrineTestStructure.class); - } - @Override public boolean canGenerate(final Location loc) { return true; @@ -62,4 +58,8 @@ public RelativePlaceableStructure build() { return structure; } + + public static HerobrineShrineTestStructure getInstance() { + return Structure.getInstance(HerobrineShrineTestStructure.class); + } } diff --git a/src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java b/src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java index a0d2184..6de3a36 100644 --- a/src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java +++ b/src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java @@ -20,10 +20,6 @@ import java.io.InputStream; public final class RickQRCodeTestStructure extends RelativeStructure { - public static RickQRCodeTestStructure getInstance() { - return Structure.getInstance(RickQRCodeTestStructure.class); - } - @Override public RelativePlaceableStructure build() { final RelativePlaceableStructure structure = new RelativePlaceableStructure(); @@ -31,4 +27,8 @@ public RelativePlaceableStructure build() { structure.loadSchematic(stream); return structure; } + + public static RickQRCodeTestStructure getInstance() { + return Structure.getInstance(RickQRCodeTestStructure.class); + } } From 54aeaba3234dc41c80d9568cdfd0f5b24842c24f Mon Sep 17 00:00:00 2001 From: noone_75 Date: Tue, 8 Sep 2026 12:02:21 +0200 Subject: [PATCH 05/12] feat: redesign structure API and add instance management - introduce the new abstract structure base and instance registry - update located/relative/placeable structure types - remove legacy structure entry and align command/test usages - added new exemple of structure --- .../api/structures/AbstractBaseStructure.java | 25 +++++++++ .../api/structures/GenerableStructure.java | 6 +- .../wlib/api/structures/LocatedStructure.java | 20 ++++--- .../api/structures/RelativeStructure.java | 18 +++--- .../webmc/wlib/api/structures/Structure.java | 45 --------------- .../api/structures/StructuresInstances.java | 38 +++++++++++++ .../api/structures/blocks/LocatedBlock.java | 10 ++-- .../api/structures/blocks/PlaceableBlock.java | 13 +++-- .../api/structures/blocks/RelativeBlock.java | 14 ++--- .../placeable/LocatedPlaceableStructure.java | 10 ++-- .../placeable/PlaceableStructure.java | 34 ++++++------ .../placeable/RelativePlaceableStructure.java | 10 ++-- .../wlib/internal/command/WLIBCommand.java | 8 ++- .../structures/CoordinateStructure.java | 55 +++++++++++++++++++ .../HerobrineShrineTestStructure.java | 8 ++- .../structures/RickQRCodeTestStructure.java | 8 ++- 16 files changed, 204 insertions(+), 118 deletions(-) create mode 100644 src/main/java/xyz/webmc/wlib/api/structures/AbstractBaseStructure.java delete mode 100644 src/main/java/xyz/webmc/wlib/api/structures/Structure.java create mode 100644 src/main/java/xyz/webmc/wlib/api/structures/StructuresInstances.java create mode 100644 src/main/java/xyz/webmc/wlib/internal/structures/CoordinateStructure.java diff --git a/src/main/java/xyz/webmc/wlib/api/structures/AbstractBaseStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/AbstractBaseStructure.java new file mode 100644 index 0000000..6e5d41e --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structures/AbstractBaseStructure.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.api.structures; + +import org.bukkit.Chunk; +import org.bukkit.Location; + +public interface AbstractBaseStructure { + void place(final Location loc, final Chunk... chunks); + + default String getName() { + return this.getClass().getSimpleName(); + } +} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructure.java index 11fd44d..01ad8aa 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructure.java @@ -17,7 +17,7 @@ import org.bukkit.Location; import org.bukkit.World; -public interface GenerableStructure { +public interface GenerableStructure extends AbstractBaseStructure { int SEARCH_RADIUS = 64; boolean canGenerate(Location loc); @@ -45,7 +45,7 @@ default Location locateNearest(final Location pos) { for (int chunkX = minX; chunkX <= maxX; chunkX++) { for (final int chunkZ : new int[] { minZ, maxZ }) { final Location loc = createLocation(world, chunkX, chunkZ); - if (canGenerate(loc)) { + if (this.canGenerate(loc)) { ret = loc; break search; } @@ -55,7 +55,7 @@ default Location locateNearest(final Location pos) { for (int chunkZ = minZ + 1; chunkZ < maxZ; chunkZ++) { for (final int chunkX : new int[] { minX, maxX }) { final Location loc = createLocation(world, chunkX, chunkZ); - if (canGenerate(loc)) { + if (this.canGenerate(loc)) { ret = loc; break search; } diff --git a/src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java index 5cd032f..90e9a66 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/LocatedStructure.java @@ -18,16 +18,18 @@ import org.bukkit.Chunk; import org.bukkit.Location; -public abstract class LocatedStructure extends Structure { - public abstract LocatedPlaceableStructure build(Location loc); +public abstract class LocatedStructure implements AbstractBaseStructure { + public abstract LocatedPlaceableStructure build(final Location loc); @Override - public final void place(Location loc) { - build(loc).place(); - } - - @Override - public final void place(Location loc, Chunk chunk) { - build(loc).place(chunk); + public final void place(final Location loc, final Chunk... chunks) { + if (chunks.length > 0) { + final LocatedPlaceableStructure builder = this.build(loc); + for (Chunk chk: chunks){ + builder.place(chk); + } + } else { + this.build(loc).place(); + } } } diff --git a/src/main/java/xyz/webmc/wlib/api/structures/RelativeStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/RelativeStructure.java index c7f71bd..bd31f17 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/RelativeStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/RelativeStructure.java @@ -18,16 +18,18 @@ import org.bukkit.Chunk; import org.bukkit.Location; -public abstract class RelativeStructure extends Structure { +public abstract class RelativeStructure implements AbstractBaseStructure { public abstract RelativePlaceableStructure build(); @Override - public final void place(final Location loc) { - this.build().place(loc); - } - - @Override - public final void place(final Location loc, final Chunk chunk) { - this.build().place(loc, chunk); + public final void place(final Location loc, final Chunk... chunks) { + if (chunks.length > 0) { + final RelativePlaceableStructure builder = this.build(); + for (Chunk chk: chunks){ + builder.place(loc, chk); + } + } else { + this.build().place(loc); + } } } diff --git a/src/main/java/xyz/webmc/wlib/api/structures/Structure.java b/src/main/java/xyz/webmc/wlib/api/structures/Structure.java deleted file mode 100644 index 29cec19..0000000 --- a/src/main/java/xyz/webmc/wlib/api/structures/Structure.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2026 Colbster937 - * - * SPDX-License-Identifier: AGPL-3.0-or-later - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * See the LICENSE file for details. - */ - -package xyz.webmc.wlib.api.structures; - -import java.util.HashMap; -import java.util.Map; - -import dev.colbster937.reflect.MirrorSafe; -import org.bukkit.Chunk; -import org.bukkit.Location; - -@SuppressWarnings({ "unchecked" }) -public abstract class Structure { - private static final Map, Structure> INSTANCES = new HashMap<>(); - - public abstract void place(Location loc); - - public abstract void place(Location loc, Chunk chunk); - - public String getName() { - return this.getClass().getSimpleName(); - } - - public static final T getInstance(final Class clazz, final Object... params) { - Structure structure = INSTANCES.get(clazz); - - if (structure == null) { - structure = MirrorSafe.invokeConstructor(clazz, params); - INSTANCES.put(clazz, structure); - } - - return (T) structure; - } -} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/StructuresInstances.java b/src/main/java/xyz/webmc/wlib/api/structures/StructuresInstances.java new file mode 100644 index 0000000..182969f --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structures/StructuresInstances.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.api.structures; + + +import java.util.HashMap; +import java.util.Map; + +import dev.colbster937.reflect.MirrorSafe; + + +@SuppressWarnings({"unchecked"}) +public class StructuresInstances { + private static final Map, AbstractBaseStructure> INSTANCES = new HashMap<>(); + + public static final T getInstance(final Class clazz, final Object... params) { + registerInstance(clazz, params); + + return (T) INSTANCES.get(clazz); + } + + public static final void registerInstance(final Class clazz, final Object... params) { + if (INSTANCES.containsKey(clazz)) { + INSTANCES.put(clazz, MirrorSafe.invokeConstructor(clazz, params)); + } + } +} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java b/src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java index 9a66366..faf3aed 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/blocks/LocatedBlock.java @@ -49,19 +49,19 @@ public LocatedBlock(final int x, final int y, final int z, final Material mat, f this(x, y, z, XMaterial.matchXMaterial(mat), dataLegacy); } - public int getX() { + public final int getX() { return this.loc.getBlockX(); } - public int getY() { + public final int getY() { return this.loc.getBlockY(); } - public int getZ() { + public final int getZ() { return this.loc.getBlockZ(); } - public Location getLocation() { + public final Location getLocation() { return this.loc; } @@ -69,7 +69,7 @@ public void place() { super.place(this.loc); } - public RelativeBlock toRelative(final Location newRelativeOrigin) { + public final RelativeBlock toRelative(final Location newRelativeOrigin) { return new RelativeBlock( this.loc.getBlockX() - newRelativeOrigin.getBlockX(), this.loc.getBlockY() - newRelativeOrigin.getBlockY(), diff --git a/src/main/java/xyz/webmc/wlib/api/structures/blocks/PlaceableBlock.java b/src/main/java/xyz/webmc/wlib/api/structures/blocks/PlaceableBlock.java index fee4494..dc6bc59 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/blocks/PlaceableBlock.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/blocks/PlaceableBlock.java @@ -20,6 +20,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.block.Block; public abstract class PlaceableBlock { protected final XMaterial mat; @@ -33,13 +34,13 @@ protected PlaceableBlock(final XMaterial mat, final String dataModern, final byt } protected void place(final Location loc) { - final org.bukkit.block.Block blk = loc.getBlock(); + final Block blk = loc.getBlock(); final Material _mat = this.mat.get(); if (mat != null) { if (WLIB.getIsModernServer() && this.dataModern != null && _mat != null) { final Object data = MirrorSafe.invokeMethod(Bukkit.class, "createBlockData", new Object[] { "minecraft:" + _mat.name().toLowerCase() + this.dataModern }); - MirrorSafe.invokeMethod(org.bukkit.block.Block.class, blk, "setBlockData", data, false); + MirrorSafe.invokeMethod(Block.class, blk, "setBlockData", data, false); } else { blk.setType(_mat, false); } @@ -47,18 +48,18 @@ protected void place(final Location loc) { } public final XMaterial getMaterial() { - return mat; + return this.mat; } public final Material getBukkitMaterial() { - return mat.get(); + return this.mat.get(); } public final String getDataModern() { - return dataModern; + return this.dataModern; } public final byte getDataLegacy() { - return dataLegacy; + return this.dataLegacy; } } diff --git a/src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java b/src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java index 13662ab..c5acfb9 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/blocks/RelativeBlock.java @@ -55,16 +55,16 @@ public RelativeBlock(final int x, final int y, final int z, final Material mat, this(x, y, z, XMaterial.matchXMaterial(mat), dataLegacy); } - public int getX() { - return x; + public final int getX() { + return this.x; } - public int getY() { - return y; + public final int getY() { + return this.y; } - public int getZ() { - return z; + public final int getZ() { + return this.z; } @Override @@ -72,7 +72,7 @@ public void place(final Location loc) { super.place(loc.clone().add(x, y, z)); } - public LocatedBlock toLocated(final Location relativeOrigin) { + public final LocatedBlock toLocated(final Location relativeOrigin) { return new LocatedBlock( relativeOrigin.clone().add(x, y, z), this.mat, diff --git a/src/main/java/xyz/webmc/wlib/api/structures/placeable/LocatedPlaceableStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/placeable/LocatedPlaceableStructure.java index 558d5f6..42d73e2 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/placeable/LocatedPlaceableStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/placeable/LocatedPlaceableStructure.java @@ -17,13 +17,11 @@ import xyz.webmc.wlib.api.structures.blocks.RelativeBlock; import xyz.webmc.wlib.api.util.SchemUtil; -import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Map; import com.cryptomorin.xseries.XMaterial; -import net.sandrohc.schematic4j.exception.ParsingException; import net.sandrohc.schematic4j.schematic.Schematic; import net.sandrohc.schematic4j.schematic.types.SchematicBlock; import net.sandrohc.schematic4j.schematic.types.SchematicBlockPos; @@ -33,7 +31,7 @@ public class LocatedPlaceableStructure extends PlaceableStructure { private final Location location; - public LocatedPlaceableStructure(Location location) { + public LocatedPlaceableStructure(final Location location) { super(new ArrayList<>()); this.location = location; } @@ -44,7 +42,7 @@ public void place() { } } - public void place(Chunk chunk) { + public void place(final Chunk chunk) { for (final LocatedBlock block : this.blocks) { final Location blockLocation = block.getLocation(); if (blockLocation.getWorld() == chunk.getWorld() && block.getX() >> 4 == chunk.getX() && block.getZ() >> 4 == chunk.getZ()) { @@ -54,7 +52,7 @@ public void place(Chunk chunk) { } @Override - public void loadSchematic(InputStream stream, int offsetx, int offsety, int offsetz) { + public void loadSchematic(final InputStream stream, final int offsetx, final int offsety, final int offsetz) { try (stream) { final Schematic schematic = SchemUtil.readSchematic(stream); final SchematicBlockPos offset = schematic.offset(); @@ -86,7 +84,7 @@ public void loadSchematic(InputStream stream, int offsetx, int offsety, int offs } } } - } catch (final IOException | ParsingException ex) { + } catch (final Exception ex) { throw new RuntimeException(ex); } } diff --git a/src/main/java/xyz/webmc/wlib/api/structures/placeable/PlaceableStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/placeable/PlaceableStructure.java index 9acaef7..11dab63 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/placeable/PlaceableStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/placeable/PlaceableStructure.java @@ -26,25 +26,13 @@ public abstract class PlaceableStructure { protected List blocks = new ArrayList<>(); - protected PlaceableStructure(List blocks) { + protected PlaceableStructure(final List blocks) { this.blocks = blocks; } - public void addBlock(B blk) { - this.blocks.add(blk); - } - - public void addBlocks(Collection blks) { - this.blocks.addAll(blks); - } - - public void addBlocks(B... blks) { - this.blocks.addAll(List.of(blks)); - } - - public abstract void loadSchematic(InputStream stream, int offsetx, int offsety, int offsetz); + public abstract void loadSchematic(final InputStream stream, final int offsetx, final int offsety, final int offsetz); - public void loadSchematic(File file, int offsetx, int offsety, int offsetz) { + public final void loadSchematic(final File file, final int offsetx, final int offsety, final int offsetz) { try (final FileInputStream fis = new FileInputStream(file)) { this.loadSchematic(fis, offsetx, offsety, offsetz); } catch (final Exception ex) { @@ -52,11 +40,23 @@ public void loadSchematic(File file, int offsetx, int offsety, int offsetz) { } } - public void loadSchematic(InputStream stream) { + public final void loadSchematic(final InputStream stream) { this.loadSchematic(stream, 0, 0, 0); } - public void loadSchematic(File file) { + public final void loadSchematic(final File file) { this.loadSchematic(file, 0, 0, 0); } + + public final void addBlock(final B blk) { + this.blocks.add(blk); + } + + public final void addBlocks(final Collection blks) { + this.blocks.addAll(blks); + } + + public final void addBlocks(final B... blks) { + this.blocks.addAll(List.of(blks)); + } } diff --git a/src/main/java/xyz/webmc/wlib/api/structures/placeable/RelativePlaceableStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/placeable/RelativePlaceableStructure.java index 06785aa..f516132 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/placeable/RelativePlaceableStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/placeable/RelativePlaceableStructure.java @@ -16,13 +16,11 @@ import xyz.webmc.wlib.api.structures.blocks.RelativeBlock; import xyz.webmc.wlib.api.util.SchemUtil; -import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Map; import com.cryptomorin.xseries.XMaterial; -import net.sandrohc.schematic4j.exception.ParsingException; import net.sandrohc.schematic4j.schematic.Schematic; import net.sandrohc.schematic4j.schematic.types.SchematicBlock; import net.sandrohc.schematic4j.schematic.types.SchematicBlockPos; @@ -34,13 +32,13 @@ public RelativePlaceableStructure() { super(new ArrayList<>()); } - public void place(Location loc) { + public void place(final Location loc) { for (final RelativeBlock block : this.blocks) { block.place(loc); } } - public void place(Location loc, Chunk chunk) { + public void place(final Location loc, final Chunk chunk) { for (final RelativeBlock block : this.blocks) { final Location blockLocation = loc.clone().add(block.getX(), block.getY(), block.getZ()); if (blockLocation.getWorld() == chunk.getWorld() && blockLocation.getBlockX() >> 4 == chunk.getX() && blockLocation.getBlockZ() >> 4 == chunk.getZ()) { @@ -50,7 +48,7 @@ public void place(Location loc, Chunk chunk) { } @Override - public void loadSchematic(InputStream stream, int offsetx, int offsety, int offsetz) { + public final void loadSchematic(final InputStream stream, final int offsetx, final int offsety, final int offsetz) { try (stream) { final Schematic schematic = SchemUtil.readSchematic(stream); final SchematicBlockPos offset = schematic.offset(); @@ -81,7 +79,7 @@ public void loadSchematic(InputStream stream, int offsetx, int offsety, int offs } } } - } catch (final IOException | ParsingException ex) { + } catch (final Exception ex) { throw new RuntimeException(); } } diff --git a/src/main/java/xyz/webmc/wlib/internal/command/WLIBCommand.java b/src/main/java/xyz/webmc/wlib/internal/command/WLIBCommand.java index 98f63a6..dd1950b 100644 --- a/src/main/java/xyz/webmc/wlib/internal/command/WLIBCommand.java +++ b/src/main/java/xyz/webmc/wlib/internal/command/WLIBCommand.java @@ -15,10 +15,11 @@ import xyz.webmc.wlib.api.WLIB; import xyz.webmc.wlib.api.command.WCommand; -import xyz.webmc.wlib.api.structures.Structure; +import xyz.webmc.wlib.api.structures.AbstractBaseStructure; import xyz.webmc.wlib.api.util.PermissionUtil; import xyz.webmc.wlib.api.util.SchedulerUtil; import xyz.webmc.wlib.api.util.TextUtil; +import xyz.webmc.wlib.internal.structures.CoordinateStructure; import xyz.webmc.wlib.internal.structures.HerobrineShrineTestStructure; import xyz.webmc.wlib.internal.structures.RickQRCodeTestStructure; @@ -76,12 +77,14 @@ public final boolean run(final CommandSender sender, final String label, final S bool1 = false; if (sender instanceof Player plr) { final String struct = args[2].trim(); - Structure structure = null; + AbstractBaseStructure structure = null; if (struct.equals("shrine")) { structure = HerobrineShrineTestStructure.getInstance(); } else if (struct.equals("rick")) { structure = RickQRCodeTestStructure.getInstance(); + } else if (struct.equals("coord")) { + structure = CoordinateStructure.getInstance(); } if (structure != null) { @@ -143,6 +146,7 @@ public final List tab(final CommandSender sender, final String label, fi if (args[0].equals("debug") && args[1].equals("place") && sender.hasPermission("wlib.debug")) { ret.add("shrine"); ret.add("rick"); + ret.add("coord"); } } diff --git a/src/main/java/xyz/webmc/wlib/internal/structures/CoordinateStructure.java b/src/main/java/xyz/webmc/wlib/internal/structures/CoordinateStructure.java new file mode 100644 index 0000000..6cad322 --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/internal/structures/CoordinateStructure.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.internal.structures; + +import xyz.webmc.wlib.api.structures.LocatedStructure; +import xyz.webmc.wlib.api.structures.StructuresInstances; +import xyz.webmc.wlib.api.structures.blocks.LocatedBlock; +import xyz.webmc.wlib.api.structures.placeable.LocatedPlaceableStructure; + +import com.cryptomorin.xseries.XMaterial; +import org.bukkit.Location; + +public final class CoordinateStructure extends LocatedStructure { + @Override + public LocatedPlaceableStructure build(final Location loc) { + final LocatedPlaceableStructure structure = new LocatedPlaceableStructure(loc); + final int x = loc.getBlockX(); + final int z = loc.getBlockZ(); + final int y = loc.getBlockY(); + + final int maxBits = Math.max(1, Integer.SIZE - Integer.numberOfLeadingZeros(Math.max(Math.abs(x), Math.abs(z)))); + for (int bit = 0; bit < maxBits; bit++) { + final int xBit = (x >> bit) & 1; + final int zBit = (z >> bit) & 1; + + structure.addBlock(new LocatedBlock(x + 1 + bit, y, z, bitToMaterial(xBit))); + structure.addBlock(new LocatedBlock(x, y, z + 1 + bit, bitToMaterial(zBit))); + } + + return structure; + } + + private static XMaterial bitToMaterial(final int bit) { + return bit == 0 ? XMaterial.WHITE_CONCRETE : XMaterial.BLACK_CONCRETE; + } + + public static CoordinateStructure getInstance() { + return StructuresInstances.getInstance(CoordinateStructure.class); + } + + static { + StructuresInstances.registerInstance(CoordinateStructure.class); + } +} diff --git a/src/main/java/xyz/webmc/wlib/internal/structures/HerobrineShrineTestStructure.java b/src/main/java/xyz/webmc/wlib/internal/structures/HerobrineShrineTestStructure.java index fce9691..ee5abfe 100644 --- a/src/main/java/xyz/webmc/wlib/internal/structures/HerobrineShrineTestStructure.java +++ b/src/main/java/xyz/webmc/wlib/internal/structures/HerobrineShrineTestStructure.java @@ -15,7 +15,7 @@ import xyz.webmc.wlib.api.structures.GenerableStructure; import xyz.webmc.wlib.api.structures.RelativeStructure; -import xyz.webmc.wlib.api.structures.Structure; +import xyz.webmc.wlib.api.structures.StructuresInstances; import xyz.webmc.wlib.api.structures.blocks.RelativeBlock; import xyz.webmc.wlib.api.structures.placeable.RelativePlaceableStructure; @@ -60,6 +60,10 @@ public RelativePlaceableStructure build() { } public static HerobrineShrineTestStructure getInstance() { - return Structure.getInstance(HerobrineShrineTestStructure.class); + return StructuresInstances.getInstance(HerobrineShrineTestStructure.class); + } + + static { + StructuresInstances.registerInstance(HerobrineShrineTestStructure.class); } } diff --git a/src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java b/src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java index 6de3a36..0ab36a6 100644 --- a/src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java +++ b/src/main/java/xyz/webmc/wlib/internal/structures/RickQRCodeTestStructure.java @@ -14,7 +14,7 @@ package xyz.webmc.wlib.internal.structures; import xyz.webmc.wlib.api.structures.RelativeStructure; -import xyz.webmc.wlib.api.structures.Structure; +import xyz.webmc.wlib.api.structures.StructuresInstances; import xyz.webmc.wlib.api.structures.placeable.RelativePlaceableStructure; import java.io.InputStream; @@ -29,6 +29,10 @@ public RelativePlaceableStructure build() { } public static RickQRCodeTestStructure getInstance() { - return Structure.getInstance(RickQRCodeTestStructure.class); + return StructuresInstances.getInstance(RickQRCodeTestStructure.class); + } + + static { + StructuresInstances.registerInstance(RickQRCodeTestStructure.class); } } From aaa796b893a1dba1123501da4193aa164b6ce1cc Mon Sep 17 00:00:00 2001 From: noone-075 Date: Wed, 9 Sep 2026 22:16:02 +0200 Subject: [PATCH 06/12] feat: add chunk generation helpers --- .../api/structures/GenerableStructure.java | 44 ---------- .../structures/GenerableStructuresUtils.java | 83 +++++++++++++++++++ .../api/structures/StructuresInstances.java | 2 +- 3 files changed, 84 insertions(+), 45 deletions(-) create mode 100644 src/main/java/xyz/webmc/wlib/api/structures/GenerableStructuresUtils.java diff --git a/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructure.java b/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructure.java index 01ad8aa..6e748fd 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructure.java @@ -15,7 +15,6 @@ import org.bukkit.Chunk; import org.bukkit.Location; -import org.bukkit.World; public interface GenerableStructure extends AbstractBaseStructure { int SEARCH_RADIUS = 64; @@ -23,47 +22,4 @@ public interface GenerableStructure extends AbstractBaseStructure { boolean canGenerate(Location loc); boolean canGenerate(Chunk chunk); - default Location createLocation(final World world, final int chunkX, final int chunkZ) { - return new Location(world, chunkX << 4, 65, chunkZ << 4); - } - - default Location locateNearest(final Location pos) { - Location ret = null; - - if (pos != null && pos.getWorld() != null) { - final int centerChunkX = pos.getChunk().getX(); - final int centerChunkZ = pos.getChunk().getZ(); - final World world = pos.getWorld(); - - search: - for (int radius = 0; radius <= SEARCH_RADIUS; radius++) { - final int minX = centerChunkX - radius; - final int maxX = centerChunkX + radius; - final int minZ = centerChunkZ - radius; - final int maxZ = centerChunkZ + radius; - - for (int chunkX = minX; chunkX <= maxX; chunkX++) { - for (final int chunkZ : new int[] { minZ, maxZ }) { - final Location loc = createLocation(world, chunkX, chunkZ); - if (this.canGenerate(loc)) { - ret = loc; - break search; - } - } - } - - for (int chunkZ = minZ + 1; chunkZ < maxZ; chunkZ++) { - for (final int chunkX : new int[] { minX, maxX }) { - final Location loc = createLocation(world, chunkX, chunkZ); - if (this.canGenerate(loc)) { - ret = loc; - break search; - } - } - } - } - } - - return ret; - } } diff --git a/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructuresUtils.java b/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructuresUtils.java new file mode 100644 index 0000000..6ed90d9 --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structures/GenerableStructuresUtils.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. + */ + +package xyz.webmc.wlib.api.structures; + +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; + +public class GenerableStructuresUtils { + private static Location createLocation(final World world, final int chunkX, final int chunkZ) { + return new Location(world, chunkX << 4, 65, chunkZ << 4); + } + + public static Location locateNearest(final GenerableStructure structure, final Location pos) { + Location ret = null; + + if (structure != null && pos != null && pos.getWorld() != null) { + final int centerChunkX = pos.getChunk().getX(); + final int centerChunkZ = pos.getChunk().getZ(); + final int searchRadius = GenerableStructure.SEARCH_RADIUS; + + search: + for (int radius = 0; radius <= searchRadius; radius++) { + final int minX = centerChunkX - radius; + final int maxX = centerChunkX + radius; + final int minZ = centerChunkZ - radius; + final int maxZ = centerChunkZ + radius; + + for (int chunkX = minX; chunkX <= maxX; chunkX++) { + for (final int chunkZ : new int[] { minZ, maxZ }) { + final Location loc = createLocation(pos.getWorld(), chunkX, chunkZ); + if (structure.canGenerate(loc)) { + ret = loc; + break search; + } + } + } + + for (int chunkZ = minZ + 1; chunkZ < maxZ; chunkZ++) { + for (final int chunkX : new int[] { minX, maxX }) { + final Location loc = createLocation(pos.getWorld(), chunkX, chunkZ); + if (structure.canGenerate(loc)) { + ret = loc; + break search; + } + } + } + } + } + + return ret; + } + + public static void generateChunk(final T structure, final Chunk chunk) { + if (structure == null || chunk == null) { + return; + } + + final Location loc = locateNearest(structure, chunk.getBlock(0, 65, 0).getLocation()); + if (loc != null) { + structure.place(loc, chunk); + } + } + + public static void generateChunk(final Class structureClass, + final Chunk chunk) { + if (structureClass != null) { + generateChunk(StructuresInstances.getInstance(structureClass), chunk); + } + } + +} diff --git a/src/main/java/xyz/webmc/wlib/api/structures/StructuresInstances.java b/src/main/java/xyz/webmc/wlib/api/structures/StructuresInstances.java index 182969f..b58de4e 100644 --- a/src/main/java/xyz/webmc/wlib/api/structures/StructuresInstances.java +++ b/src/main/java/xyz/webmc/wlib/api/structures/StructuresInstances.java @@ -31,7 +31,7 @@ public static final T getInstance(final Class< } public static final void registerInstance(final Class clazz, final Object... params) { - if (INSTANCES.containsKey(clazz)) { + if (!INSTANCES.containsKey(clazz)) { INSTANCES.put(clazz, MirrorSafe.invokeConstructor(clazz, params)); } } From 8f9a11a86e1ca603023a9c5f5bc4fe1b91c42dbc Mon Sep 17 00:00:00 2001 From: noone_75 Date: Mon, 14 Sep 2026 11:45:43 +0200 Subject: [PATCH 07/12] fix: remove useless SuppressWarnings --- src/main/java/xyz/webmc/wlib/api/structure/BlockRelative.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/xyz/webmc/wlib/api/structure/BlockRelative.java b/src/main/java/xyz/webmc/wlib/api/structure/BlockRelative.java index a22aafc..fb2347f 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/BlockRelative.java +++ b/src/main/java/xyz/webmc/wlib/api/structure/BlockRelative.java @@ -22,7 +22,6 @@ import org.bukkit.Material; import org.bukkit.block.Block; -@SuppressWarnings({ "removal" }) @Deprecated(forRemoval = true) public class BlockRelative { private final int x; From e2ad7e71324ecc94b2a6d4f14f346f68d53adf87 Mon Sep 17 00:00:00 2001 From: noone_75 Date: Mon, 14 Sep 2026 11:52:05 +0200 Subject: [PATCH 08/12] feat: new workflow to test build --- .github/workflows/test.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..ab8c3f8 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,35 @@ +on: + push: + paths: + - 'src/**' + - 'pom.xml' + pull_request: + paths: + - 'src/**' + - 'pom.xml' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - id: vars + run: | + echo "JAVA=$(mvn help:evaluate -Dexpression=maven.compiler.release -q -DforceStdout)" >> "$GITHUB_OUTPUT" + echo "VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" >> "$GITHUB_OUTPUT" + - uses: actions/setup-java@v5 + with: + distribution: liberica + java-version: ${{ steps.vars.outputs.JAVA }} + - run: ./src/build/scripts/TestCode.sh + - run: mvn -B package -DskipTests + - uses: actions/upload-artifact@v7 + with: + name: wlib-${{ steps.vars.outputs.VERSION }} + path: target/wlib-${{ steps.vars.outputs.VERSION }}.jar + if-no-files-found: error From 457f6762d395685c55549ace7e1d9f2339f44b23 Mon Sep 17 00:00:00 2001 From: noone_75 Date: Mon, 14 Sep 2026 12:00:01 +0200 Subject: [PATCH 09/12] fix: make it executable --- src/build/scripts/TestCode.sh | 1 - 1 file changed, 1 deletion(-) mode change 100644 => 100755 src/build/scripts/TestCode.sh diff --git a/src/build/scripts/TestCode.sh b/src/build/scripts/TestCode.sh old mode 100644 new mode 100755 index fb78bb6..dd05d8f --- a/src/build/scripts/TestCode.sh +++ b/src/build/scripts/TestCode.sh @@ -1,2 +1 @@ mvn test $@ - From 42be90d68c534f81ed896a73950d7e1b480913bf Mon Sep 17 00:00:00 2001 From: noone-075 Date: Mon, 14 Sep 2026 14:19:36 +0200 Subject: [PATCH 10/12] feat: added canGenerate(BuilderChunk) --- .../xyz/webmc/wlib/api/structure/GenerableStructure.java | 2 +- .../internal/structure/HerobrineShrineTestStructure.java | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/xyz/webmc/wlib/api/structure/GenerableStructure.java b/src/main/java/xyz/webmc/wlib/api/structure/GenerableStructure.java index 00e717a..15632a6 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/GenerableStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structure/GenerableStructure.java @@ -21,5 +21,5 @@ public interface GenerableStructure extends BaseStructure { boolean canGenerate(Location loc); boolean canGenerate(Chunk chunk); - + boolean canGenerate(BuilderChunk chk); } diff --git a/src/main/java/xyz/webmc/wlib/internal/structure/HerobrineShrineTestStructure.java b/src/main/java/xyz/webmc/wlib/internal/structure/HerobrineShrineTestStructure.java index ed87639..bf86852 100644 --- a/src/main/java/xyz/webmc/wlib/internal/structure/HerobrineShrineTestStructure.java +++ b/src/main/java/xyz/webmc/wlib/internal/structure/HerobrineShrineTestStructure.java @@ -13,6 +13,7 @@ package xyz.webmc.wlib.internal.structure; +import xyz.webmc.wlib.api.structure.BuilderChunk; import xyz.webmc.wlib.api.structure.GenerableStructure; import xyz.webmc.wlib.api.structure.RelativeStructure; import xyz.webmc.wlib.api.structure.blocks.RelativeBlock; @@ -34,6 +35,11 @@ public boolean canGenerate(Chunk chunk) { return true; } + @Override + public boolean canGenerate(BuilderChunk chunk) { + return true; + } + @Override public RelativePlaceableStructure build() { final RelativePlaceableStructure structure = new RelativePlaceableStructure(); From d0c64e5018b97b4743170d737741bce8ba2d08c8 Mon Sep 17 00:00:00 2001 From: noone Date: Mon, 14 Sep 2026 19:56:15 +0200 Subject: [PATCH 11/12] feat: moved to Absolute and other things --- ...dStructure.java => AbsoluteStructure.java} | 8 +- .../api/structure/block/AbsoluteBlock.java | 78 +++++++++++++++++++ .../structure/block/AbstractBlockBase.java | 76 ++++++++++++++---- .../api/structure/block/BlockRelative.java | 31 +++----- .../api/structure/block/RelativeBlock.java | 77 ++++++++++++++++++ .../{LocatedBlock.java => AbsoluteBlock.java} | 16 ++-- .../api/structure/blocks/RelativeBlock.java | 4 +- .../api/structure/iface/TestStructure.java | 18 ----- ...e.java => AbsolutePlaceableStructure.java} | 14 ++-- .../AbstractPlaceableStructureBase.java | 2 +- .../placeable/RelativePlaceableStructure.java | 2 +- .../GenerableStructuresUtils.java | 3 +- .../structure/CoordinateStructure.java | 16 ++-- .../HerobrineShrineTestStructure.java | 2 +- 14 files changed, 263 insertions(+), 84 deletions(-) rename src/main/java/xyz/webmc/wlib/api/structure/{LocatedStructure.java => AbsoluteStructure.java} (71%) create mode 100644 src/main/java/xyz/webmc/wlib/api/structure/block/AbsoluteBlock.java create mode 100644 src/main/java/xyz/webmc/wlib/api/structure/block/RelativeBlock.java rename src/main/java/xyz/webmc/wlib/api/structure/blocks/{LocatedBlock.java => AbsoluteBlock.java} (76%) delete mode 100644 src/main/java/xyz/webmc/wlib/api/structure/iface/TestStructure.java rename src/main/java/xyz/webmc/wlib/api/structure/placeable/{LocatedPlaceableStructure.java => AbsolutePlaceableStructure.java} (87%) rename src/main/java/xyz/webmc/wlib/api/{structure => util}/GenerableStructuresUtils.java (96%) diff --git a/src/main/java/xyz/webmc/wlib/api/structure/LocatedStructure.java b/src/main/java/xyz/webmc/wlib/api/structure/AbsoluteStructure.java similarity index 71% rename from src/main/java/xyz/webmc/wlib/api/structure/LocatedStructure.java rename to src/main/java/xyz/webmc/wlib/api/structure/AbsoluteStructure.java index 850e082..0f1a55c 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/LocatedStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structure/AbsoluteStructure.java @@ -13,17 +13,17 @@ package xyz.webmc.wlib.api.structure; -import xyz.webmc.wlib.api.structure.placeable.LocatedPlaceableStructure; +import xyz.webmc.wlib.api.structure.placeable.AbsolutePlaceableStructure; import org.bukkit.Location; -public abstract class LocatedStructure implements BaseStructure { - public abstract LocatedPlaceableStructure build(Location loc); +public abstract class AbsoluteStructure implements BaseStructure { + public abstract AbsolutePlaceableStructure build(Location loc); @Override public final void place(Location loc, Object... chunks) { if (chunks.length > 0) { - final LocatedPlaceableStructure builder = this.build(loc); + final AbsolutePlaceableStructure builder = this.build(loc); for (Object chk: chunks){ builder.place(chk); } diff --git a/src/main/java/xyz/webmc/wlib/api/structure/block/AbsoluteBlock.java b/src/main/java/xyz/webmc/wlib/api/structure/block/AbsoluteBlock.java new file mode 100644 index 0000000..41ccb54 --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structure/block/AbsoluteBlock.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package xyz.webmc.wlib.api.structure.block; + +import com.cryptomorin.xseries.XMaterial; +import org.bukkit.Location; +import org.bukkit.Material; + +public non-sealed class AbsoluteBlock extends AbstractBlockBase { + private final Location loc; + + public AbsoluteBlock(Location loc, XMaterial mat, String dataModern, byte dataLegacy) { + super(mat, dataModern, dataLegacy); + this.loc = loc; + } + + public AbsoluteBlock(int x, int y, int z, XMaterial mat) { + this(new Location(null, x, y, z), mat, null, (byte) 0); + } + + public AbsoluteBlock(int x, int y, int z, Material mat) { + this(x, y, z, XMaterial.matchXMaterial(mat)); + } + + public AbsoluteBlock(int x, int y, int z, XMaterial mat, String dataModern) { + this(new Location(null, x, y, z), mat, dataModern, (byte) 0); + } + + public AbsoluteBlock(int x, int y, int z, Material mat, String dataModern) { + this(x, y, z, XMaterial.matchXMaterial(mat), dataModern); + } + + public AbsoluteBlock(int x, int y, int z, XMaterial mat, byte dataLegacy) { + this(new Location(null, x, y, z), mat, null, dataLegacy); + } + + public AbsoluteBlock(int x, int y, int z, Material mat, byte dataLegacy) { + this(x, y, z, XMaterial.matchXMaterial(mat), dataLegacy); + } + + public final int getX() { + return this.loc.getBlockX(); + } + + public final int getY() { + return this.loc.getBlockY(); + } + + public final int getZ() { + return this.loc.getBlockZ(); + } + + public final Location getLocation() { + return this.loc; + } + + public void place() { + super.place(this.loc); + } + + public void place(Object chunk) { + super.place(this.loc, chunk); + } + + public final RelativeBlock toRelative(Location newRelativeOrigin) { + return new RelativeBlock( + this.loc.getBlockX() - newRelativeOrigin.getBlockX(), + this.loc.getBlockY() - newRelativeOrigin.getBlockY(), + this.loc.getBlockZ() - newRelativeOrigin.getBlockZ(), + this.mat, + this.dataModern, + this.dataLegacy); + } +} diff --git a/src/main/java/xyz/webmc/wlib/api/structure/block/AbstractBlockBase.java b/src/main/java/xyz/webmc/wlib/api/structure/block/AbstractBlockBase.java index a9f5f87..752e6f7 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/block/AbstractBlockBase.java +++ b/src/main/java/xyz/webmc/wlib/api/structure/block/AbstractBlockBase.java @@ -14,19 +14,21 @@ package xyz.webmc.wlib.api.structure.block; import xyz.webmc.wlib.api.WLIB; +import xyz.webmc.wlib.api.structure.BuilderChunk; import com.cryptomorin.xseries.XMaterial; +import dev.colbster937.reflect.MirrorSafe; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.block.Block; -@SuppressWarnings({ "removal" }) -@Deprecated(forRemoval = true) -public abstract sealed class AbstractBlockBase permits BlockRelative { + +public abstract sealed class AbstractBlockBase permits AbsoluteBlock, BlockRelative, RelativeBlock { protected final XMaterial mat; protected final String dataModern; protected final byte dataLegacy; - @Deprecated(forRemoval = true) protected AbstractBlockBase(XMaterial mat, String dataModern, byte dataLegacy) { WLIB.warnDeprecatedUsage(); this.mat = mat; @@ -34,46 +36,92 @@ protected AbstractBlockBase(XMaterial mat, String dataModern, byte dataLegacy) { this.dataLegacy = dataLegacy; } - @Deprecated(forRemoval = true) protected AbstractBlockBase(XMaterial mat, String data) { this(mat, data, (byte) 0); WLIB.warnDeprecatedUsage(); } - @Deprecated(forRemoval = true) protected AbstractBlockBase(XMaterial mat, byte data) { this(mat, null, data); WLIB.warnDeprecatedUsage(); } - @Deprecated(forRemoval = true) - protected abstract void place(Location loc); + protected void place(Location loc) { + final Material material = this.getBukkitMaterial(); + if (material == null) { + return; + } + + final Block block = loc.getBlock(); + if (WLIB.getIsModernServer() && this.dataModern != null) { + final Object data = MirrorSafe.invokeMethod(Bukkit.class, "createBlockData", + new Object[] { "minecraft:" + material.name().toLowerCase() + this.dataModern }); + MirrorSafe.invokeMethod(Block.class, block, "setBlockData", data, false); + } else { + block.setType(material, false); + if (this.dataLegacy != 0) { + block.setData(this.dataLegacy); + } + } + } + + protected void place(Location loc, Object chunk) { + if (chunk instanceof org.bukkit.Chunk liveChunk) { + if (loc.getWorld() == liveChunk.getWorld() + && loc.getBlockX() >> 4 == liveChunk.getX() + && loc.getBlockZ() >> 4 == liveChunk.getZ()) { + this.place(loc); + } + return; + } + + if (chunk instanceof BuilderChunk builderChunk) { + if (loc.getBlockX() >> 4 != builderChunk.x() + || loc.getBlockZ() >> 4 != builderChunk.z()) { + return; + } + + final Material material = this.getBukkitMaterial(); + if (material == null) { + return; + } + + final int x = loc.getBlockX() - (builderChunk.x() << 4); + final int y = loc.getBlockY(); + final int z = loc.getBlockZ() - (builderChunk.z() << 4); + if (this.dataModern != null) { + final Object data = MirrorSafe.invokeMethod(Bukkit.class, "createBlockData", + new Object[] { "minecraft:" + material.name().toLowerCase() + this.dataModern }); + MirrorSafe.invokeMethod(builderChunk.chunkData().getClass(), builderChunk.chunkData(), "setBlockData", x, y, z, data); + } else { + MirrorSafe.invokeMethod(builderChunk.chunkData().getClass(), builderChunk.chunkData(), "setBlock", x, y, z, material); + } + return; + } + + throw new IllegalArgumentException("Unsupported chunk type: " + chunk); + } - @Deprecated(forRemoval = true) public final XMaterial getXMaterial() { WLIB.warnDeprecatedUsage(); return this.mat; } - @Deprecated(forRemoval = true) public final XMaterial getMaterial() { WLIB.warnDeprecatedUsage(); return this.getXMaterial(); } - @Deprecated(forRemoval = true) public final Material getBukkitMaterial() { WLIB.warnDeprecatedUsage(); - return this.mat.get(); + return this.mat == null ? null : this.mat.get(); } - @Deprecated(forRemoval = true) public final String getDataModern() { WLIB.warnDeprecatedUsage(); return this.dataModern; } - @Deprecated(forRemoval = true) public final byte getDataLegacy() { WLIB.warnDeprecatedUsage(); return this.dataLegacy; diff --git a/src/main/java/xyz/webmc/wlib/api/structure/block/BlockRelative.java b/src/main/java/xyz/webmc/wlib/api/structure/block/BlockRelative.java index 061d108..9fa1cce 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/block/BlockRelative.java +++ b/src/main/java/xyz/webmc/wlib/api/structure/block/BlockRelative.java @@ -16,11 +16,8 @@ import xyz.webmc.wlib.api.WLIB; import com.cryptomorin.xseries.XMaterial; -import dev.colbster937.reflect.MirrorSafe; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.block.Block; @SuppressWarnings({ "removal" }) @Deprecated(forRemoval = true) @@ -29,6 +26,7 @@ public non-sealed class BlockRelative extends AbstractBlockBase { private final int y; private final int z; + @Deprecated(forRemoval = true) protected BlockRelative(int x, int y, int z, XMaterial mat, String dataModern, byte dataLegacy) { super(mat, dataModern, dataLegacy); WLIB.warnDeprecatedUsage(); @@ -37,67 +35,62 @@ protected BlockRelative(int x, int y, int z, XMaterial mat, String dataModern, b this.z = z; } + @Deprecated(forRemoval = true) public BlockRelative(int x, int y, int z, XMaterial mat) { this(x, y, z, mat, null, (byte) 0); WLIB.warnDeprecatedUsage(); } + @Deprecated(forRemoval = true) public BlockRelative(int x, int y, int z, Material mat) { this(x, y, z, XMaterial.matchXMaterial(mat)); WLIB.warnDeprecatedUsage(); } + @Deprecated(forRemoval = true) public BlockRelative(int x, int y, int z, XMaterial mat, String dataModern) { this(x, y, z, mat, dataModern, (byte) 0); WLIB.warnDeprecatedUsage(); } + @Deprecated(forRemoval = true) public BlockRelative(int x, int y, int z, Material mat, String dataModern) { this(x, y, z, XMaterial.matchXMaterial(mat), dataModern); WLIB.warnDeprecatedUsage(); } + @Deprecated(forRemoval = true) public BlockRelative(int x, int y, int z, XMaterial mat, byte dataLegacy) { this(x, y, z, mat, null, dataLegacy); WLIB.warnDeprecatedUsage(); } + @Deprecated(forRemoval = true) public BlockRelative(int x, int y, int z, Material mat, byte dataLegacy) { this(x, y, z, XMaterial.matchXMaterial(mat), dataLegacy); WLIB.warnDeprecatedUsage(); } + @Deprecated(forRemoval = true) @Override public void place(Location loc) { WLIB.warnDeprecatedUsage(); - if (this.mat != null) { - final Location rel = loc.clone().add(this.x, this.y, this.z); - final Block blk = rel.getBlock(); - final Material _mat = this.getBukkitMaterial(); - if (_mat != null) { - if (WLIB.getIsModernServer() && this.dataModern != null) { - final Object data = MirrorSafe.invokeMethod(Bukkit.class, "createBlockData", new Object[] { "minecraft:" + _mat.name().toLowerCase() + this.dataModern }); - MirrorSafe.invokeMethod(Block.class, blk, "setBlockData", data, false); - } else { - blk.setType(_mat, false); - if (this.dataLegacy != 0) { - blk.setData(this.dataLegacy); - } - } - } - } + super.place(loc.clone().add(this.x, this.y, this.z)); } + @Deprecated(forRemoval = true) public final int getX() { WLIB.warnDeprecatedUsage(); return this.x; } + @Deprecated(forRemoval = true) public final int getY() { WLIB.warnDeprecatedUsage(); return this.y; } + @Deprecated(forRemoval = true) public final int getZ() { WLIB.warnDeprecatedUsage(); return this.z; diff --git a/src/main/java/xyz/webmc/wlib/api/structure/block/RelativeBlock.java b/src/main/java/xyz/webmc/wlib/api/structure/block/RelativeBlock.java new file mode 100644 index 0000000..0197f26 --- /dev/null +++ b/src/main/java/xyz/webmc/wlib/api/structure/block/RelativeBlock.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2026 Colbster937 + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package xyz.webmc.wlib.api.structure.block; + +import com.cryptomorin.xseries.XMaterial; +import org.bukkit.Location; +import org.bukkit.Material; + +public non-sealed class RelativeBlock extends AbstractBlockBase { + private final int x; + private final int y; + private final int z; + + public RelativeBlock(int x, int y, int z, XMaterial mat, String dataModern, byte dataLegacy) { + super(mat, dataModern, dataLegacy); + this.x = x; + this.y = y; + this.z = z; + } + + public RelativeBlock(int x, int y, int z, XMaterial mat) { + this(x, y, z, mat, null, (byte) 0); + } + + public RelativeBlock(int x, int y, int z, Material mat) { + this(x, y, z, XMaterial.matchXMaterial(mat)); + } + + public RelativeBlock(int x, int y, int z, XMaterial mat, String dataModern) { + this(x, y, z, mat, dataModern, (byte) 0); + } + + public RelativeBlock(int x, int y, int z, Material mat, String dataModern) { + this(x, y, z, XMaterial.matchXMaterial(mat), dataModern); + } + + public RelativeBlock(int x, int y, int z, XMaterial mat, byte dataLegacy) { + this(x, y, z, mat, null, dataLegacy); + } + + public RelativeBlock(int x, int y, int z, Material mat, byte dataLegacy) { + this(x, y, z, XMaterial.matchXMaterial(mat), dataLegacy); + } + + public final int getX() { + return this.x; + } + + public final int getY() { + return this.y; + } + + public final int getZ() { + return this.z; + } + + @Override + public void place(Location loc) { + super.place(loc.clone().add(this.x, this.y, this.z)); + } + + public void place(Location loc, Object chunk) { + super.place(loc.clone().add(this.x, this.y, this.z), chunk); + } + + public final AbsoluteBlock toAbsolute(Location relativeOrigin) { + return new AbsoluteBlock( + relativeOrigin.clone().add(this.x, this.y, this.z), + this.mat, + this.dataModern, + this.dataLegacy); + } +} diff --git a/src/main/java/xyz/webmc/wlib/api/structure/blocks/LocatedBlock.java b/src/main/java/xyz/webmc/wlib/api/structure/blocks/AbsoluteBlock.java similarity index 76% rename from src/main/java/xyz/webmc/wlib/api/structure/blocks/LocatedBlock.java rename to src/main/java/xyz/webmc/wlib/api/structure/blocks/AbsoluteBlock.java index 4158958..dfe8a9f 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/blocks/LocatedBlock.java +++ b/src/main/java/xyz/webmc/wlib/api/structure/blocks/AbsoluteBlock.java @@ -17,35 +17,35 @@ import org.bukkit.Location; import org.bukkit.Material; -public class LocatedBlock extends AbstractBlockBase { +public class AbsoluteBlock extends AbstractBlockBase { private final Location loc; - public LocatedBlock(Location loc, XMaterial mat, String dataModern, byte dataLegacy) { + public AbsoluteBlock(Location loc, XMaterial mat, String dataModern, byte dataLegacy) { super(mat, dataModern, dataLegacy); this.loc = loc; } - public LocatedBlock(int x, int y, int z, XMaterial mat) { + public AbsoluteBlock(int x, int y, int z, XMaterial mat) { this(new Location(null, x, y, z), mat, null, (byte) 0); } - public LocatedBlock(int x, int y, int z, Material mat) { + public AbsoluteBlock(int x, int y, int z, Material mat) { this(x, y, z, XMaterial.matchXMaterial(mat)); } - public LocatedBlock(int x, int y, int z, XMaterial mat, String dataModern) { + public AbsoluteBlock(int x, int y, int z, XMaterial mat, String dataModern) { this(new Location(null, x, y, z), mat, dataModern, (byte) 0); } - public LocatedBlock(int x, int y, int z, Material mat, String dataModern) { + public AbsoluteBlock(int x, int y, int z, Material mat, String dataModern) { this(x, y, z, XMaterial.matchXMaterial(mat), dataModern); } - public LocatedBlock(int x, int y, int z, XMaterial mat, byte dataLegacy) { + public AbsoluteBlock(int x, int y, int z, XMaterial mat, byte dataLegacy) { this(new Location(null, x, y, z), mat, null, dataLegacy); } - public LocatedBlock(int x, int y, int z, Material mat, byte dataLegacy) { + public AbsoluteBlock(int x, int y, int z, Material mat, byte dataLegacy) { this(x, y, z, XMaterial.matchXMaterial(mat), dataLegacy); } diff --git a/src/main/java/xyz/webmc/wlib/api/structure/blocks/RelativeBlock.java b/src/main/java/xyz/webmc/wlib/api/structure/blocks/RelativeBlock.java index d9587bb..30726e8 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/blocks/RelativeBlock.java +++ b/src/main/java/xyz/webmc/wlib/api/structure/blocks/RelativeBlock.java @@ -76,8 +76,8 @@ public void place(Location loc, Object chunk) { super.place(loc.clone().add(this.x, this.y, this.z), chunk); } - public final LocatedBlock toLocated(Location relativeOrigin) { - return new LocatedBlock( + public final AbsoluteBlock toAbsolute(Location relativeOrigin) { + return new AbsoluteBlock( relativeOrigin.clone().add(this.x, this.y, this.z), this.mat, this.dataModern, diff --git a/src/main/java/xyz/webmc/wlib/api/structure/iface/TestStructure.java b/src/main/java/xyz/webmc/wlib/api/structure/iface/TestStructure.java deleted file mode 100644 index 0f00a1f..0000000 --- a/src/main/java/xyz/webmc/wlib/api/structure/iface/TestStructure.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2026 Colbster937 - * - * SPDX-License-Identifier: AGPL-3.0-or-later - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * See the LICENSE file for details. - */ - -package xyz.webmc.wlib.api.structure.iface; - -@Deprecated(forRemoval = true) -public interface TestStructure { -} diff --git a/src/main/java/xyz/webmc/wlib/api/structure/placeable/LocatedPlaceableStructure.java b/src/main/java/xyz/webmc/wlib/api/structure/placeable/AbsolutePlaceableStructure.java similarity index 87% rename from src/main/java/xyz/webmc/wlib/api/structure/placeable/LocatedPlaceableStructure.java rename to src/main/java/xyz/webmc/wlib/api/structure/placeable/AbsolutePlaceableStructure.java index 733e32a..14036e6 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/placeable/LocatedPlaceableStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structure/placeable/AbsolutePlaceableStructure.java @@ -14,8 +14,8 @@ package xyz.webmc.wlib.api.structure.placeable; import xyz.webmc.wlib.api.structure.BuilderChunk; -import xyz.webmc.wlib.api.structure.blocks.LocatedBlock; -import xyz.webmc.wlib.api.structure.blocks.RelativeBlock; +import xyz.webmc.wlib.api.structure.block.AbsoluteBlock; +import xyz.webmc.wlib.api.structure.block.RelativeBlock; import xyz.webmc.wlib.api.util.SchemUtil; import java.io.InputStream; @@ -29,22 +29,22 @@ import org.bukkit.Chunk; import org.bukkit.Location; -public class LocatedPlaceableStructure extends AbstractPlaceableStructureBase { +public class AbsolutePlaceableStructure extends AbstractPlaceableStructureBase { private final Location location; - public LocatedPlaceableStructure(Location location) { + public AbsolutePlaceableStructure(Location location) { super(new ArrayList<>()); this.location = location; } public void place() { - for (final LocatedBlock block : this.blocks) { + for (final AbsoluteBlock block : this.blocks) { block.place(); } } public void place(Object chunk) { - for (final LocatedBlock block : this.blocks) { + for (final AbsoluteBlock block : this.blocks) { final Location blockLocation = block.getLocation(); if (isInChunk(blockLocation, chunk)) { block.place(chunk); @@ -80,7 +80,7 @@ public void loadSchematic(InputStream stream, int offsetx, int offsety, int offs z - offset.z + offsetz, material, "[" + data + "]"); - this.blocks.add(relativeBlock.toLocated(this.location)); + this.blocks.add(relativeBlock.toAbsolute(this.location)); } } } diff --git a/src/main/java/xyz/webmc/wlib/api/structure/placeable/AbstractPlaceableStructureBase.java b/src/main/java/xyz/webmc/wlib/api/structure/placeable/AbstractPlaceableStructureBase.java index a48c2a7..d1e12f9 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/placeable/AbstractPlaceableStructureBase.java +++ b/src/main/java/xyz/webmc/wlib/api/structure/placeable/AbstractPlaceableStructureBase.java @@ -13,7 +13,7 @@ package xyz.webmc.wlib.api.structure.placeable; -import xyz.webmc.wlib.api.structure.blocks.AbstractBlockBase; +import xyz.webmc.wlib.api.structure.block.AbstractBlockBase; import java.io.File; import java.io.FileInputStream; diff --git a/src/main/java/xyz/webmc/wlib/api/structure/placeable/RelativePlaceableStructure.java b/src/main/java/xyz/webmc/wlib/api/structure/placeable/RelativePlaceableStructure.java index d2f4be7..07b98c0 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/placeable/RelativePlaceableStructure.java +++ b/src/main/java/xyz/webmc/wlib/api/structure/placeable/RelativePlaceableStructure.java @@ -14,7 +14,7 @@ package xyz.webmc.wlib.api.structure.placeable; import xyz.webmc.wlib.api.structure.BuilderChunk; -import xyz.webmc.wlib.api.structure.blocks.RelativeBlock; +import xyz.webmc.wlib.api.structure.block.RelativeBlock; import xyz.webmc.wlib.api.util.SchemUtil; import java.io.InputStream; diff --git a/src/main/java/xyz/webmc/wlib/api/structure/GenerableStructuresUtils.java b/src/main/java/xyz/webmc/wlib/api/util/GenerableStructuresUtils.java similarity index 96% rename from src/main/java/xyz/webmc/wlib/api/structure/GenerableStructuresUtils.java rename to src/main/java/xyz/webmc/wlib/api/util/GenerableStructuresUtils.java index c1daddf..3512de1 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/GenerableStructuresUtils.java +++ b/src/main/java/xyz/webmc/wlib/api/util/GenerableStructuresUtils.java @@ -11,8 +11,9 @@ * See the LICENSE file for details. */ -package xyz.webmc.wlib.api.structure; +package xyz.webmc.wlib.api.util; +import xyz.webmc.wlib.api.structure.GenerableStructure; import xyz.webmc.wlib.internal.util.TestStructureUtil; import org.bukkit.Chunk; diff --git a/src/main/java/xyz/webmc/wlib/internal/structure/CoordinateStructure.java b/src/main/java/xyz/webmc/wlib/internal/structure/CoordinateStructure.java index 43d07aa..28a2b3e 100644 --- a/src/main/java/xyz/webmc/wlib/internal/structure/CoordinateStructure.java +++ b/src/main/java/xyz/webmc/wlib/internal/structure/CoordinateStructure.java @@ -13,18 +13,18 @@ package xyz.webmc.wlib.internal.structure; -import xyz.webmc.wlib.api.structure.LocatedStructure; -import xyz.webmc.wlib.api.structure.blocks.LocatedBlock; -import xyz.webmc.wlib.api.structure.placeable.LocatedPlaceableStructure; +import xyz.webmc.wlib.api.structure.AbsoluteStructure; +import xyz.webmc.wlib.api.structure.block.AbsoluteBlock; +import xyz.webmc.wlib.api.structure.placeable.AbsolutePlaceableStructure; import xyz.webmc.wlib.internal.util.TestStructureUtil; import com.cryptomorin.xseries.XMaterial; import org.bukkit.Location; -public final class CoordinateStructure extends LocatedStructure { +public final class CoordinateStructure extends AbsoluteStructure { @Override - public LocatedPlaceableStructure build(Location loc) { - final LocatedPlaceableStructure structure = new LocatedPlaceableStructure(loc); + public AbsolutePlaceableStructure build(Location loc) { + final AbsolutePlaceableStructure structure = new AbsolutePlaceableStructure(loc); final int x = loc.getBlockX(); final int z = loc.getBlockZ(); final int y = loc.getBlockY(); @@ -34,8 +34,8 @@ public LocatedPlaceableStructure build(Location loc) { final int xBit = (x >> bit) & 1; final int zBit = (z >> bit) & 1; - structure.addBlock(new LocatedBlock(x + 1 + bit, y, z, bitToMaterial(xBit))); - structure.addBlock(new LocatedBlock(x, y, z + 1 + bit, bitToMaterial(zBit))); + structure.addBlock(new AbsoluteBlock(x + 1 + bit, y, z, bitToMaterial(xBit))); + structure.addBlock(new AbsoluteBlock(x, y, z + 1 + bit, bitToMaterial(zBit))); } return structure; diff --git a/src/main/java/xyz/webmc/wlib/internal/structure/HerobrineShrineTestStructure.java b/src/main/java/xyz/webmc/wlib/internal/structure/HerobrineShrineTestStructure.java index bf86852..73dd8f4 100644 --- a/src/main/java/xyz/webmc/wlib/internal/structure/HerobrineShrineTestStructure.java +++ b/src/main/java/xyz/webmc/wlib/internal/structure/HerobrineShrineTestStructure.java @@ -16,7 +16,7 @@ import xyz.webmc.wlib.api.structure.BuilderChunk; import xyz.webmc.wlib.api.structure.GenerableStructure; import xyz.webmc.wlib.api.structure.RelativeStructure; -import xyz.webmc.wlib.api.structure.blocks.RelativeBlock; +import xyz.webmc.wlib.api.structure.block.RelativeBlock; import xyz.webmc.wlib.api.structure.placeable.RelativePlaceableStructure; import xyz.webmc.wlib.internal.util.TestStructureUtil; From 4db647e0f162ce67fefee6a26e4f2129075b0429 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 14 Sep 2026 17:57:09 +0000 Subject: [PATCH 12/12] chore: auto-format code --- .../xyz/webmc/wlib/api/structure/block/AbsoluteBlock.java | 7 +++++++ .../xyz/webmc/wlib/api/structure/block/RelativeBlock.java | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/main/java/xyz/webmc/wlib/api/structure/block/AbsoluteBlock.java b/src/main/java/xyz/webmc/wlib/api/structure/block/AbsoluteBlock.java index 41ccb54..fdb585f 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/block/AbsoluteBlock.java +++ b/src/main/java/xyz/webmc/wlib/api/structure/block/AbsoluteBlock.java @@ -2,6 +2,13 @@ * Copyright (C) 2026 Colbster937 * * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. */ package xyz.webmc.wlib.api.structure.block; diff --git a/src/main/java/xyz/webmc/wlib/api/structure/block/RelativeBlock.java b/src/main/java/xyz/webmc/wlib/api/structure/block/RelativeBlock.java index 0197f26..968ca8f 100644 --- a/src/main/java/xyz/webmc/wlib/api/structure/block/RelativeBlock.java +++ b/src/main/java/xyz/webmc/wlib/api/structure/block/RelativeBlock.java @@ -2,6 +2,13 @@ * Copyright (C) 2026 Colbster937 * * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * See the LICENSE file for details. */ package xyz.webmc.wlib.api.structure.block;