From 4bda4276931eacebc2c3ad1f4a0c4cd61472c7f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Thu, 10 Oct 2024 22:08:48 +0200 Subject: [PATCH] wip: refactoring with persistent storage containers --- .../eu/mhsl/minecraft/pixelblocks/Main.java | 4 +- .../pixelblocks/PixelBlockDatabase.java | 34 +++---- .../minecraft/pixelblocks/PixelBlockItem.java | 8 +- .../commands/ExitWorldCommand.java | 2 +- .../listeners/PlacePixelBlockListener.java | 2 +- .../pixelblocks/pixelblock/Pixel.java | 69 +++++++------ .../pixelblocks/pixelblock/PixelBlock.java | 96 +++++++++++++------ .../pixelblock/PixelBlockHitbox.java | 14 +-- .../pixelblock/PixelBlockWorld.java | 2 +- 9 files changed, 140 insertions(+), 91 deletions(-) diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/Main.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/Main.java index 25018c6..71d8e9f 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/Main.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/Main.java @@ -27,10 +27,10 @@ public final class Main extends JavaPlugin { public static List pixelBlocks = new ArrayList<>(); - public static TaskChain newChain() { + public static TaskChain chain() { return taskFactory.newChain(); } - public static TaskChain newSharedChain(String name) { + public static TaskChain sharedChain(String name) { return taskFactory.newSharedChain(name); } diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockDatabase.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockDatabase.java index 2d53137..6c9d623 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockDatabase.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockDatabase.java @@ -60,7 +60,7 @@ public class PixelBlockDatabase { public void deletePixelBlock(PixelBlock pixelBlock) { Bukkit.getScheduler().runTaskAsynchronously(Main.plugin, () -> { try { - this.deletePixelBlock.setString(1, pixelBlock.blockUUID.toString()); + this.deletePixelBlock.setString(1, pixelBlock.getBlockUUID().toString()); this.deletePixelBlock.executeUpdate(); } catch (SQLException e) { throw new RuntimeException("Failed to delete PixelBlock from the database", e); @@ -71,27 +71,27 @@ public class PixelBlockDatabase { public void savePixelBlock(PixelBlock pixelBlock) { Bukkit.getScheduler().runTask(Main.plugin, () -> { try { - this.insertOrReplacePixelBlock.setString(1, pixelBlock.blockUUID.toString()); - this.insertOrReplacePixelBlock.setString(2, pixelBlock.ownerUUID.toString()); + this.insertOrReplacePixelBlock.setString(1, pixelBlock.getBlockUUID().toString()); + this.insertOrReplacePixelBlock.setString(2, pixelBlock.getOwnerUUID().toString()); - this.insertOrReplacePixelBlock.setString(3, pixelBlock.pixelBlockLocation.getWorld().getName()); - this.insertOrReplacePixelBlock.setDouble(4, pixelBlock.pixelBlockLocation.getX()); - this.insertOrReplacePixelBlock.setDouble(5, pixelBlock.pixelBlockLocation.getY()); - this.insertOrReplacePixelBlock.setDouble(6, pixelBlock.pixelBlockLocation.getZ()); + this.insertOrReplacePixelBlock.setString(3, pixelBlock.getPixelBlockLocation().getWorld().getName()); + this.insertOrReplacePixelBlock.setDouble(4, pixelBlock.getPixelBlockLocation().getX()); + this.insertOrReplacePixelBlock.setDouble(5, pixelBlock.getPixelBlockLocation().getY()); + this.insertOrReplacePixelBlock.setDouble(6, pixelBlock.getPixelBlockLocation().getZ()); - if (pixelBlock.lastEntryLocation != null) { - this.insertOrReplacePixelBlock.setString(7, pixelBlock.lastEntryLocation.getWorld().getName()); - this.insertOrReplacePixelBlock.setDouble(8, pixelBlock.lastEntryLocation.getX()); - this.insertOrReplacePixelBlock.setDouble(9, pixelBlock.lastEntryLocation.getY()); - this.insertOrReplacePixelBlock.setDouble(10, pixelBlock.lastEntryLocation.getZ()); + if (pixelBlock.getLastEntryLocation() != null) { + this.insertOrReplacePixelBlock.setString(7, pixelBlock.getLastEntryLocation().getWorld().getName()); + this.insertOrReplacePixelBlock.setDouble(8, pixelBlock.getLastEntryLocation().getX()); + this.insertOrReplacePixelBlock.setDouble(9, pixelBlock.getLastEntryLocation().getY()); + this.insertOrReplacePixelBlock.setDouble(10, pixelBlock.getLastEntryLocation().getZ()); } else { - this.insertOrReplacePixelBlock.setString(7, pixelBlock.pixelBlockLocation.getWorld().getName()); - this.insertOrReplacePixelBlock.setDouble(8, pixelBlock.pixelBlockLocation.getX()); - this.insertOrReplacePixelBlock.setDouble(9, pixelBlock.pixelBlockLocation.getY()); - this.insertOrReplacePixelBlock.setDouble(10, pixelBlock.pixelBlockLocation.getZ()); + this.insertOrReplacePixelBlock.setString(7, pixelBlock.getPixelBlockLocation().getWorld().getName()); + this.insertOrReplacePixelBlock.setDouble(8, pixelBlock.getPixelBlockLocation().getX()); + this.insertOrReplacePixelBlock.setDouble(9, pixelBlock.getPixelBlockLocation().getY()); + this.insertOrReplacePixelBlock.setDouble(10, pixelBlock.getPixelBlockLocation().getZ()); } - this.insertOrReplacePixelBlock.setString(11, pixelBlock.facingDirection.toString()); + this.insertOrReplacePixelBlock.setString(11, pixelBlock.getFacingDirection().toString()); this.insertOrReplacePixelBlock.executeUpdate(); } catch (SQLException e) { diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockItem.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockItem.java index 176b79f..654eacb 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockItem.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockItem.java @@ -44,18 +44,18 @@ public class PixelBlockItem { } public static @NotNull ItemStack getBlockAsItem(@NotNull PixelBlock block) { - String ownerName = Optional.ofNullable(Bukkit.getOfflinePlayer(block.ownerUUID).getName()).orElseGet(() -> block.ownerUUID.toString()); + String ownerName = Optional.ofNullable(Bukkit.getOfflinePlayer(block.getOwnerUUID()).getName()).orElseGet(() -> block.getOwnerUUID().toString()); ItemStack itemStack = HeadUtil.getCustomTextureHead(itemTexture); ItemMeta meta = itemStack.getItemMeta(); meta.setMaxStackSize(1); - meta.getPersistentDataContainer().set(idProperty, PersistentDataType.STRING, block.blockUUID.toString()); - meta.getPersistentDataContainer().set(ownerProperty, PersistentDataType.STRING, block.ownerUUID.toString()); + meta.getPersistentDataContainer().set(idProperty, PersistentDataType.STRING, block.getBlockUUID().toString()); + meta.getPersistentDataContainer().set(ownerProperty, PersistentDataType.STRING, block.getOwnerUUID().toString()); meta.displayName(Component.text("Pixelblock von " + ownerName)); meta.lore(List.of( Component.text(ownerName + " ist der Besitzer dieses Blocks."), Component.text("Klicke auf den gesetzten Block, um diesen zu bearbeiten!"), - Component.text(block.blockUUID.toString()).color(NamedTextColor.DARK_GRAY) + Component.text(block.getBlockUUID().toString()).color(NamedTextColor.DARK_GRAY) )); itemStack.setItemMeta(meta); diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/commands/ExitWorldCommand.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/commands/ExitWorldCommand.java index 10a4442..5482c92 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/commands/ExitWorldCommand.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/commands/ExitWorldCommand.java @@ -23,7 +23,7 @@ public class ExitWorldCommand implements CommandExecutor { PixelBlock currentPixelBlock = PixelBlock.getPixelBlockFromBlockWorld(playerWorld); Objects.requireNonNull(currentPixelBlock); - p.teleport(currentPixelBlock.lastEntryLocation); + p.teleport(currentPixelBlock.getLastEntryLocation()); } return true; } diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlacePixelBlockListener.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlacePixelBlockListener.java index 8ebe58d..366170e 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlacePixelBlockListener.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlacePixelBlockListener.java @@ -47,7 +47,7 @@ public class PlacePixelBlockListener implements Listener { } else { UUID itemUUID = info.id(); pixelBlock = Main.pixelBlocks.stream() - .filter(block -> block.blockUUID.equals(itemUUID)) + .filter(block -> block.getBlockUUID().equals(itemUUID)) .findFirst() .orElseGet(() -> new PixelBlock( newBlockLocation, diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/Pixel.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/Pixel.java index 7c9e655..4138645 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/Pixel.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/Pixel.java @@ -1,57 +1,66 @@ package eu.mhsl.minecraft.pixelblocks.pixelblock; +import eu.mhsl.minecraft.pixelblocks.Main; import org.bukkit.Location; -import org.bukkit.World; +import org.bukkit.NamespacedKey; import org.bukkit.block.data.BlockData; import org.bukkit.entity.BlockDisplay; -import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; import org.bukkit.util.Transformation; +import org.bukkit.util.Vector; import org.jetbrains.annotations.NotNull; -import javax.annotation.Nullable; import java.util.Objects; import java.util.UUID; public class Pixel { - public final Location relativeLocation; + private static final NamespacedKey parentBlockTag = new NamespacedKey(Main.plugin, "parent"); + + private final @NotNull PixelBlock parentBlock; + private final @NotNull BlockDisplay entity; + + public final Location location; public final BlockData blockData; private final double scale; - private @Nullable UUID uuid; - public Pixel(@NotNull Location relativeLocation, @NotNull BlockData blockData, double scale) { - this.relativeLocation = new Location( - relativeLocation.getWorld(), - relativeLocation.x(), - relativeLocation.y(), - relativeLocation.z() - ); - this.blockData = blockData; - this.scale = scale; + public static Pixel existingPixel(PixelBlock parentBlock, BlockDisplay entity) { + PersistentDataContainer dataContainer = entity.getPersistentDataContainer(); + if(!dataContainer.has(parentBlockTag)) throw new IllegalArgumentException("Entity is missing the parent tag in the DataContainer"); + UUID expectedParentUuid = UUID.fromString(Objects.requireNonNull(dataContainer.get(parentBlockTag, PersistentDataType.STRING))); + if(!parentBlock.getBlockUUID().equals(expectedParentUuid)) throw new IllegalArgumentException("Pixel is from a different parent block"); + return new Pixel(parentBlock, entity); } - public void place(@NotNull Location spawnBlockLocation) { - World world = spawnBlockLocation.getWorld(); - double positionX = spawnBlockLocation.x() + (relativeLocation.x()*scale); - double positionY = spawnBlockLocation.y() + (relativeLocation.y()*scale); - double positionZ = spawnBlockLocation.z() + (relativeLocation.z()*scale); + public static Pixel newPixel(PixelBlock parentBlock, Vector relativePosition, BlockData blockData, double scale) { + return new Pixel(parentBlock, relativePosition, blockData, scale); + } - Location spawnLocation = new Location(world, positionX, positionY, positionZ); + private Pixel(@NotNull PixelBlock parentBlock, @NotNull BlockDisplay entity) { + this.parentBlock = parentBlock; + this.entity = entity; + this.location = entity.getLocation(); + this.blockData = entity.getBlock(); + this.scale = entity.getTransformation().getScale().get(0); + } - BlockDisplay entity = (BlockDisplay) world.spawnEntity(spawnLocation, EntityType.BLOCK_DISPLAY); - this.uuid = entity.getUniqueId(); + private Pixel(@NotNull PixelBlock parentBlock, @NotNull Vector relativePosition, @NotNull BlockData blockData, double scale) { + this.parentBlock = parentBlock; + this.location = parentBlock.getPixelBlockLocation().add(relativePosition.multiply(scale)); + this.blockData = blockData; + this.scale = scale; + this.entity = (BlockDisplay) this.location.getWorld().spawnEntity(this.location, EntityType.BLOCK_DISPLAY); - entity.setBlock(blockData); - - Transformation transform = entity.getTransformation(); - transform.getScale().set(scale); - entity.setTransformation(transform); + this.entity.setBlock(blockData); + Transformation transform = this.entity.getTransformation(); + transform.getScale().set(this.scale); + this.entity.setTransformation(transform); + this.entity.getPersistentDataContainer().set(parentBlockTag, PersistentDataType.STRING, this.parentBlock.getBlockUUID().toString()); } public void destroy() { - Objects.requireNonNull(this.uuid); - Entity pixelEntity = this.relativeLocation.getWorld().getEntity(this.uuid); - if(pixelEntity != null) pixelEntity.remove(); + this.entity.remove(); } } diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlock.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlock.java index 912bf26..21b93a0 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlock.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlock.java @@ -24,16 +24,16 @@ public class PixelBlock { private final float hitboxOffset = (float) Main.configuration.hitboxOffset(); private final int pixelsPerBlock = Main.configuration.pixelsPerBlock(); - public Location pixelBlockLocation; - public Direction facingDirection; - public List pixels = new ArrayList<>(); + private Location pixelBlockLocation; + private Direction facingDirection; + private final List pixels = new ArrayList<>(); - public PixelBlockHitbox hitbox; - public List placeholderIcon = new ArrayList<>(); + private PixelBlockHitbox hitbox; + private final List placeholderIcon = new ArrayList<>(); - public Location lastEntryLocation; - public UUID ownerUUID; - public UUID blockUUID; + private Location lastEntryLocation; + private final UUID ownerUUID; + private final UUID blockUUID; public static final int maxPixelsPerBlock = 2000; @@ -80,10 +80,16 @@ public class PixelBlock { this.facingDirection = direction; this.pixelWorld = new PixelBlockWorld(this); + + this.pixelBlockLocation.getNearbyEntitiesByType(BlockDisplay.class, 1).forEach(blockDisplay -> { + try { + this.pixels.add(Pixel.existingPixel(this, blockDisplay)); + } catch(IllegalArgumentException ignored) {} + }); } public TaskChain getBlockTaskChain() { - return Main.newSharedChain(this.blockUUID.toString()); + return Main.sharedChain(this.blockUUID.toString()); } public void enterBlock(@NotNull Player player) { @@ -118,11 +124,13 @@ public class PixelBlock { public void updateEntities() { this.getBlockTaskChain() .sync(this::clearEntities) - .async(() -> { + .sync(() -> { for (int x = 0; x < pixelsPerBlock; x++) { for (int y = 0; y < pixelsPerBlock; y++) { for (int z = 0; z < pixelsPerBlock; z++) { - Location relativeLocation = new Location(pixelBlockLocation.getWorld(), x, y, z); + World world = pixelBlockLocation.getWorld(); + Location relativeLocation = new Location(world, x, y, z); + Location blockLocation = this.pixelWorld.getBuildOrigin(); switch (this.facingDirection) { case south -> blockLocation.add(relativeLocation.x(), relativeLocation.y(), relativeLocation.z()); @@ -132,23 +140,23 @@ public class PixelBlock { } BlockData block = blockLocation.getBlock().getBlockData(); - if(block.getMaterial() != Material.AIR) { - pixels.add(new Pixel(relativeLocation, block, ((double) 1/pixelsPerBlock))); + if(!block.getMaterial().isEmpty()) { + this.getBlockTaskChain() + .delay(1) + .sync(() -> pixels.add(Pixel.newPixel(this, relativeLocation.toVector(), block, (double) 1 / pixelsPerBlock))) + .execute(); } } } } }) - .sync(() -> this.pixels.stream() - .limit(maxPixelsPerBlock) - .forEach(pixel -> pixel.place(this.pixelBlockLocation))) .sync(() -> { if(this.pixels.size() < 5) { - Location relativeLocation = new Location(pixelBlockLocation.getWorld(), 0, 0, 0); - BlockData block = Material.GRAY_STAINED_GLASS.createBlockData(); - Pixel newPixel = new Pixel(relativeLocation, block, 1); - pixels.add(newPixel); - newPixel.place(this.pixelBlockLocation); +// Location relativeLocation = new Location(pixelBlockLocation.getWorld(), 0, 0, 0); +// BlockData block = Material.GRAY_STAINED_GLASS.createBlockData(); +// Pixel newPixel = new Pixel(relativeLocation, block, 1); +// pixels.add(newPixel); +// newPixel.place(this.pixelBlockLocation); Location itemDisplayLocation = this.pixelBlockLocation.clone().add(0.5, 0.5, 0.5); @@ -245,13 +253,13 @@ public class PixelBlock { this.placeholderIcon.clear(); } - this.pixelBlockLocation.getWorld().getEntities().stream() - .filter(this::isPixelBlockComponent) - .filter(entity -> entity.getLocation() - .add(0, hitboxOffset, 0) - .toBlockLocation() - .equals(this.pixelBlockLocation)) - .forEach(Entity::remove); +// this.pixelBlockLocation.getWorld().getEntities().stream() +// .filter(this::isPixelBlockComponent) +// .filter(entity -> entity.getLocation() +// .add(0, hitboxOffset, 0) +// .toBlockLocation() +// .equals(this.pixelBlockLocation)) +// .forEach(Entity::remove); } private boolean isPixelBlockComponent(Entity entity) { @@ -264,4 +272,36 @@ public class PixelBlock { public @NotNull PixelBlockWorld getPixelWorld() { return pixelWorld; } + + public Location getPixelBlockLocation() { + return pixelBlockLocation.clone(); + } + + public Direction getFacingDirection() { + return facingDirection; + } + + public List getPixels() { + return pixels; + } + + public PixelBlockHitbox getHitbox() { + return hitbox; + } + + public List getPlaceholderIcon() { + return placeholderIcon; + } + + public Location getLastEntryLocation() { + return lastEntryLocation.clone(); + } + + public UUID getOwnerUUID() { + return ownerUUID; + } + + public UUID getBlockUUID() { + return blockUUID; + } } diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockHitbox.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockHitbox.java index 97a7376..c82e446 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockHitbox.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockHitbox.java @@ -11,7 +11,7 @@ public class PixelBlockHitbox { private final Interaction hitbox; public PixelBlockHitbox(boolean fullBlock, Location pixelBlockLocation, float hitboxOffset, List pixels, int pixelsPerBlock) { - if(fullBlock) { + if(fullBlock || true) { hitbox = (Interaction) pixelBlockLocation.getWorld().spawnEntity( pixelBlockLocation.clone().add(0.5, -hitboxOffset, 0.5), EntityType.INTERACTION @@ -19,13 +19,13 @@ public class PixelBlockHitbox { hitbox.setInteractionHeight(1 + 2*hitboxOffset); hitbox.setInteractionWidth(1 + 2*hitboxOffset); } else { - double startingX = MinMaxUtil.getMinProperty(pixels, pixel -> pixel.relativeLocation.getX()); - double startingY = MinMaxUtil.getMinProperty(pixels, pixel -> pixel.relativeLocation.getY()); - double startingZ = MinMaxUtil.getMinProperty(pixels, pixel -> pixel.relativeLocation.getZ()); + double startingX = MinMaxUtil.getMinProperty(pixels, pixel -> pixel.location.getX()); + double startingY = MinMaxUtil.getMinProperty(pixels, pixel -> pixel.location.getY()); + double startingZ = MinMaxUtil.getMinProperty(pixels, pixel -> pixel.location.getZ()); - double endingX = MinMaxUtil.getMaxProperty(pixels, pixel -> pixel.relativeLocation.getX()); - double endingY = MinMaxUtil.getMaxProperty(pixels, pixel -> pixel.relativeLocation.getY()); - double endingZ = MinMaxUtil.getMaxProperty(pixels, pixel -> pixel.relativeLocation.getZ()); + double endingX = MinMaxUtil.getMaxProperty(pixels, pixel -> pixel.location.getX()); + double endingY = MinMaxUtil.getMaxProperty(pixels, pixel -> pixel.location.getY()); + double endingZ = MinMaxUtil.getMaxProperty(pixels, pixel -> pixel.location.getZ()); Location spawnLocation = pixelBlockLocation.clone().add( ((startingX+endingX+1)/2)/pixelsPerBlock, diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockWorld.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockWorld.java index d698488..ac1f2e8 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockWorld.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockWorld.java @@ -49,7 +49,7 @@ public class PixelBlockWorld { } public @NotNull String getWorldPathName() { - return Main.plugin.getDataFolder().getPath() + File.separator + "worlds" + File.separator + this.parentPixelBlock.blockUUID; + return Main.plugin.getDataFolder().getPath() + File.separator + "worlds" + File.separator + this.parentPixelBlock.getBlockUUID(); } public @NotNull Location getSpawnLocation() {