diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockConfiguration.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockConfiguration.java index fc6466e..6a51741 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockConfiguration.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockConfiguration.java @@ -6,18 +6,14 @@ import org.jetbrains.annotations.NotNull; public record PixelBlockConfiguration( int pixelsPerBlock, boolean liveUpdate, - int worldGrassBorderWidth, double hitboxOffset, - boolean deleteOnBreak, // TODO does no longer exists boolean onlyBreakableByOwner, boolean onlyEditableByOwner ) { public static void setDefaults(FileConfiguration config) { config.addDefault(Keys.PixelsPerBlock.key, 16); config.addDefault(Keys.LiveUpdate.key, true); - config.addDefault(Keys.WorldGrassBorderWidth.key, 5); config.addDefault(Keys.HitboxOffset.key, 0.005); - config.addDefault(Keys.DeleteOnBreak.key, false); config.addDefault(Keys.OnlyBreakableByOwners.key, false); config.addDefault(Keys.OnlyEditableByOwners.key, true); config.options().copyDefaults(true); @@ -26,9 +22,7 @@ public record PixelBlockConfiguration( public enum Keys { PixelsPerBlock("pixelsPerBlock"), LiveUpdate("liveUpdate"), - WorldGrassBorderWidth("worldGrassBorderWidth"), HitboxOffset("hitboxOffset"), - DeleteOnBreak("deleteOnBreak"), OnlyBreakableByOwners("onlyBreakableByOwners"), OnlyEditableByOwners("onlyEditableByOwners"); diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockDatabase.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockDatabase.java index f0f3907..19128e3 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockDatabase.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockDatabase.java @@ -4,8 +4,6 @@ import eu.mhsl.minecraft.pixelblocks.utils.Direction; import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; import java.sql.*; import java.util.ArrayList; @@ -13,194 +11,182 @@ import java.util.List; import java.util.UUID; public class PixelBlockDatabase { - public Connection db; + private final Connection db; + + private final PreparedStatement getAllPixelBlocks; + private final PreparedStatement deletePixelBlock; + private final PreparedStatement insertNewPixelBlock; + private final PreparedStatement updateExistingPixelBlock; + public PixelBlockDatabase(String url) { try { + Class.forName("org.sqlite.JDBC"); this.db = DriverManager.getConnection(url); - } catch (SQLException e) { + + this.db.createStatement().execute( + "CREATE TABLE IF NOT EXISTS pixelblocks (" + + "uuid CHAR(36) PRIMARY KEY, " + + "owner CHAR(36), " + + "locationWorldName CHAR(36), " + + "locationX DOUBLE, " + + "locationY DOUBLE, " + + "locationZ DOUBLE, " + + "entryLocationWorldName CHAR(36), " + + "entryLocationX DOUBLE, " + + "entryLocationY DOUBLE, " + + "entryLocationZ DOUBLE, " + + "direction CHAR(36)" + + ")" + ); + + this.deletePixelBlock = this.db.prepareStatement("DELETE FROM pixelblocks WHERE uuid = ?"); + this.getAllPixelBlocks = this.db.prepareStatement("SELECT * FROM pixelblocks"); + this.insertNewPixelBlock = this.db.prepareStatement( + "INSERT INTO pixelblocks(uuid, owner, " + + "locationWorldName, locationX, locationY, locationZ, " + + "entryLocationWorldName, entryLocationX, entryLocationY, entryLocationZ, direction) " + + "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + ); + this.updateExistingPixelBlock = this.db.prepareStatement( + "UPDATE pixelblocks " + + "SET owner=?, locationWorldName=?, locationX=?, locationY=?, locationZ=?," + + "entryLocationWorldName=?, entryLocationX=?, entryLocationY=?, entryLocationZ=?, direction=? " + + "WHERE uuid=?;" + ); + } catch (SQLException | RuntimeException | ClassNotFoundException e) { throw new RuntimeException("Failed to load Database", e); } } - public Statement getStatement() throws SQLException { - return this.db.createStatement(); + public void close() throws SQLException { + deletePixelBlock.close(); + getAllPixelBlocks.close(); + insertNewPixelBlock.close(); + updateExistingPixelBlock.close(); + db.close(); } - public void removePixelBlock(PixelBlock pixelBlock) { - Bukkit.getScheduler().runTask(PixelBlocksPlugin.plugin, () -> { - + public void deletePixelBlock(PixelBlock pixelBlock) { + Bukkit.getScheduler().runTaskAsynchronously(PixelBlocksPlugin.plugin, () -> { try { - PreparedStatement prep = this.db.prepareStatement("DELETE FROM pixelblocks WHERE uuid = ?"); - prep.setString(1, pixelBlock.blockUUID.toString()); - prep.executeUpdate(); - - prep.close(); + this.deletePixelBlock.setString(1, pixelBlock.blockUUID.toString()); + this.deletePixelBlock.executeUpdate(); + PixelBlocksPlugin.plugin.getLogger().info("DB: Deleted PixelBlock: " + pixelBlock.blockUUID); } catch (SQLException e) { - System.err.println(e.getMessage()); + throw new RuntimeException("Failed to delete PixelBlock", e); } - }); } public void savePixelBlock(PixelBlock pixelBlock) { Bukkit.getScheduler().runTask(PixelBlocksPlugin.plugin, () -> { - List uuids = new ArrayList<>(); + List storedPixelBlocks = new ArrayList<>(); - try (var statement = getStatement()) { - ResultSet pixelBlocksResult = statement.executeQuery("SELECT * FROM pixelblocks;"); + try { + ResultSet pixelBlocksResult = this.getAllPixelBlocks.executeQuery(); while (pixelBlocksResult.next()) { - uuids.add(UUID.fromString(pixelBlocksResult.getString("uuid"))); + storedPixelBlocks.add(UUID.fromString(pixelBlocksResult.getString("uuid"))); } } catch (SQLException e) { - System.err.println(e.getMessage()); + throw new RuntimeException("Failed to fetch PixelBlock list", e); } - if(!uuids.contains(pixelBlock.blockUUID)) { - + if(!storedPixelBlocks.contains(pixelBlock.blockUUID)) { + // create new entry if it does not exist try { - PreparedStatement prep = this.db.prepareStatement( - "INSERT INTO pixelblocks(uuid, owner, " + - "locationWorldName, locationX, locationY, locationZ, " + - "entryLocationWorldName, entryLocationX, entryLocationY, entryLocationZ, direction) " + - "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" - ); - prep.setString(1, pixelBlock.blockUUID.toString()); - prep.setString(2, pixelBlock.ownerUUID.toString()); + this.insertNewPixelBlock.setString(1, pixelBlock.blockUUID.toString()); + this.insertNewPixelBlock.setString(2, pixelBlock.ownerUUID.toString()); - prep.setString(3, pixelBlock.pixelBlockLocation.getWorld().getName()); - prep.setDouble(4, pixelBlock.pixelBlockLocation.getX()); - prep.setDouble(5, pixelBlock.pixelBlockLocation.getY()); - prep.setDouble(6, pixelBlock.pixelBlockLocation.getZ()); + this.insertNewPixelBlock.setString(3, pixelBlock.pixelBlockLocation.getWorld().getName()); + this.insertNewPixelBlock.setDouble(4, pixelBlock.pixelBlockLocation.getX()); + this.insertNewPixelBlock.setDouble(5, pixelBlock.pixelBlockLocation.getY()); + this.insertNewPixelBlock.setDouble(6, pixelBlock.pixelBlockLocation.getZ()); if(pixelBlock.lastEntryLocation != null) { - prep.setString(7, pixelBlock.lastEntryLocation.getWorld().getName()); - prep.setDouble(8, pixelBlock.lastEntryLocation.getX()); - prep.setDouble(9, pixelBlock.lastEntryLocation.getY()); - prep.setDouble(10, pixelBlock.lastEntryLocation.getZ()); + this.insertNewPixelBlock.setString(7, pixelBlock.lastEntryLocation.getWorld().getName()); + this.insertNewPixelBlock.setDouble(8, pixelBlock.lastEntryLocation.getX()); + this.insertNewPixelBlock.setDouble(9, pixelBlock.lastEntryLocation.getY()); + this.insertNewPixelBlock.setDouble(10, pixelBlock.lastEntryLocation.getZ()); } else { - prep.setString(7, Bukkit.getWorlds().getFirst().getName()); - prep.setDouble(8, Bukkit.getWorlds().getFirst().getSpawnLocation().getX()); - prep.setDouble(9, Bukkit.getWorlds().getFirst().getSpawnLocation().getY()); - prep.setDouble(10, Bukkit.getWorlds().getFirst().getSpawnLocation().getZ()); + this.insertNewPixelBlock.setString(7, Bukkit.getWorlds().getFirst().getName()); + this.insertNewPixelBlock.setDouble(8, Bukkit.getWorlds().getFirst().getSpawnLocation().getX()); + this.insertNewPixelBlock.setDouble(9, Bukkit.getWorlds().getFirst().getSpawnLocation().getY()); + this.insertNewPixelBlock.setDouble(10, Bukkit.getWorlds().getFirst().getSpawnLocation().getZ()); } - prep.setString(11, pixelBlock.facingDirection.toString()); + this.insertNewPixelBlock.setString(11, pixelBlock.facingDirection.toString()); - prep.executeUpdate(); - prep.close(); + this.insertNewPixelBlock.executeUpdate(); + PixelBlocksPlugin.plugin.getLogger().info("DB: Created PixelBlock: " + pixelBlock.blockUUID); } catch (SQLException e) { - System.err.println(e.getMessage()); + throw new RuntimeException("Failed to save PixelBlock", e); } } else { + // update existing entry try { - PreparedStatement prep = this.db.prepareStatement( - "UPDATE pixelblocks " + - "SET owner=?, locationWorldName=?, locationX=?, locationY=?, locationZ=?," + - "entryLocationWorldName=?, entryLocationX=?, entryLocationY=?, entryLocationZ=?, direction=? " + - "WHERE uuid=?;" - ); - prep.setString(1, pixelBlock.ownerUUID.toString()); + this.updateExistingPixelBlock.setString(1, pixelBlock.ownerUUID.toString()); - prep.setString(2, pixelBlock.pixelBlockLocation.getWorld().getName()); - prep.setDouble(3, pixelBlock.pixelBlockLocation.getX()); - prep.setDouble(4, pixelBlock.pixelBlockLocation.getY()); - prep.setDouble(5, pixelBlock.pixelBlockLocation.getZ()); + this.updateExistingPixelBlock.setString(2, pixelBlock.pixelBlockLocation.getWorld().getName()); + this.updateExistingPixelBlock.setDouble(3, pixelBlock.pixelBlockLocation.getX()); + this.updateExistingPixelBlock.setDouble(4, pixelBlock.pixelBlockLocation.getY()); + this.updateExistingPixelBlock.setDouble(5, pixelBlock.pixelBlockLocation.getZ()); if(pixelBlock.lastEntryLocation != null) { - prep.setString(6, pixelBlock.lastEntryLocation.getWorld().getName()); - prep.setDouble(7, pixelBlock.lastEntryLocation.getX()); - prep.setDouble(8, pixelBlock.lastEntryLocation.getY()); - prep.setDouble(9, pixelBlock.lastEntryLocation.getZ()); + this.updateExistingPixelBlock.setString(6, pixelBlock.lastEntryLocation.getWorld().getName()); + this.updateExistingPixelBlock.setDouble(7, pixelBlock.lastEntryLocation.getX()); + this.updateExistingPixelBlock.setDouble(8, pixelBlock.lastEntryLocation.getY()); + this.updateExistingPixelBlock.setDouble(9, pixelBlock.lastEntryLocation.getZ()); } else { - prep.setString(6, Bukkit.getWorlds().getFirst().getName()); - prep.setDouble(7, Bukkit.getWorlds().getFirst().getSpawnLocation().getX()); - prep.setDouble(8, Bukkit.getWorlds().getFirst().getSpawnLocation().getY()); - prep.setDouble(9, Bukkit.getWorlds().getFirst().getSpawnLocation().getZ()); + this.updateExistingPixelBlock.setString(6, Bukkit.getWorlds().getFirst().getName()); + this.updateExistingPixelBlock.setDouble(7, Bukkit.getWorlds().getFirst().getSpawnLocation().getX()); + this.updateExistingPixelBlock.setDouble(8, Bukkit.getWorlds().getFirst().getSpawnLocation().getY()); + this.updateExistingPixelBlock.setDouble(9, Bukkit.getWorlds().getFirst().getSpawnLocation().getZ()); } - prep.setString(10, pixelBlock.blockUUID.toString()); - prep.setString(11, pixelBlock.facingDirection.toString()); + this.updateExistingPixelBlock.setString(10, pixelBlock.blockUUID.toString()); + this.updateExistingPixelBlock.setString(11, pixelBlock.facingDirection.toString()); - prep.executeUpdate(); - prep.close(); + this.updateExistingPixelBlock.executeUpdate(); + PixelBlocksPlugin.plugin.getLogger().info("DB: Updated PixelBlock: " + pixelBlock.blockUUID); } catch (SQLException e) { - System.err.println(e.getMessage()); + throw new RuntimeException("Failed updating PixelBlock", e); } } }); } public void loadPixelBlocks() { - List entities = new ArrayList<>(); - entities.addAll(Bukkit.getWorlds().get(0).getEntities().stream() - .filter(entity -> entity.getType().equals(EntityType.BLOCK_DISPLAY) || entity.getType().equals(EntityType.INTERACTION) || entity.getType().equals(EntityType.ITEM_DISPLAY)) - .toList()); - entities.addAll(Bukkit.getWorlds().get(1).getEntities().stream() - .filter(entity -> entity.getType().equals(EntityType.BLOCK_DISPLAY) || entity.getType().equals(EntityType.INTERACTION) || entity.getType().equals(EntityType.ITEM_DISPLAY)) - .toList()); - entities.addAll(Bukkit.getWorlds().get(2).getEntities().stream() - .filter(entity -> entity.getType().equals(EntityType.BLOCK_DISPLAY) || entity.getType().equals(EntityType.INTERACTION) || entity.getType().equals(EntityType.ITEM_DISPLAY)) - .toList()); + try { + ResultSet allPixelBlocks = this.getAllPixelBlocks.executeQuery(); - String sql = "CREATE TABLE IF NOT EXISTS pixelblocks (" + - "uuid CHAR(36) PRIMARY KEY, " + - "owner CHAR(36), " + - "locationWorldName CHAR(36), " + - "locationX DOUBLE, " + - "locationY DOUBLE, " + - "locationZ DOUBLE, " + - "entryLocationWorldName CHAR(36), " + - "entryLocationX DOUBLE, " + - "entryLocationY DOUBLE, " + - "entryLocationZ DOUBLE, " + - "direction CHAR(36)" + - ");"; - - try (var statement = getStatement()) { - statement.execute(sql); - ResultSet pixelBlocksResult = statement.executeQuery("SELECT * FROM pixelblocks;"); - - while (pixelBlocksResult.next()) { - Location newPixelBlockLocation = new Location( - Bukkit.getWorld(pixelBlocksResult.getString("locationWorldName")), - pixelBlocksResult.getDouble("locationX"), - pixelBlocksResult.getDouble("locationY"), - pixelBlocksResult.getDouble("locationZ") + while (allPixelBlocks.next()) { + Location blockLocation = new Location( + Bukkit.getWorld(allPixelBlocks.getString("locationWorldName")), + allPixelBlocks.getDouble("locationX"), + allPixelBlocks.getDouble("locationY"), + allPixelBlocks.getDouble("locationZ") ); - Location newEntryLocation = new Location( - Bukkit.getWorld(pixelBlocksResult.getString("entryLocationWorldName")), - pixelBlocksResult.getDouble("entryLocationX"), - pixelBlocksResult.getDouble("entryLocationY"), - pixelBlocksResult.getDouble("entryLocationZ") + Location entryLocation = new Location( + Bukkit.getWorld(allPixelBlocks.getString("entryLocationWorldName")), + allPixelBlocks.getDouble("entryLocationX"), + allPixelBlocks.getDouble("entryLocationY"), + allPixelBlocks.getDouble("entryLocationZ") ); - if(!newPixelBlockLocation.getChunk().isEntitiesLoaded()) { - newPixelBlockLocation.getChunk().load(true); - newPixelBlockLocation.getChunk().getEntities(); - } - - entities.stream().filter(entity -> entity - .getLocation() - .add(0, PixelBlocksPlugin.configuration.hitboxOffset(), 0) - .toBlockLocation() - .equals(newPixelBlockLocation)) - .forEach(Entity::remove); - - PixelBlock newPixelBlock = new PixelBlock( - newPixelBlockLocation, - UUID.fromString(pixelBlocksResult.getString("owner")), - UUID.fromString(pixelBlocksResult.getString("uuid")) + PixelBlock block = new PixelBlock( + blockLocation, + UUID.fromString(allPixelBlocks.getString("owner")), + UUID.fromString(allPixelBlocks.getString("uuid")), + Direction.valueOf(allPixelBlocks.getString("direction")) ); - newPixelBlock.lastEntryLocation = newEntryLocation; - newPixelBlock.place(newPixelBlockLocation, Direction.valueOf(pixelBlocksResult.getString("direction"))); + block.setLastEntryLocation(entryLocation); + PixelBlocksPlugin.plugin.getLogger().info("DB: Loaded PixelBlock: " + block.blockUUID); } - } catch (SQLException e) { - System.err.println(e.getMessage()); + throw new RuntimeException("Failed loading PixelBlocks", e); } - } } diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockItem.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockItem.java index 98e877f..a4e59d1 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockItem.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockItem.java @@ -2,6 +2,7 @@ package eu.mhsl.minecraft.pixelblocks; import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.NamespacedKey; @@ -11,16 +12,28 @@ import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; +import java.util.List; import java.util.Optional; +import java.util.UUID; public class PixelBlockItem { + public static UUID unusedBlockID = UUID.fromString("98fdf0ae-c3ab-4ef7-ae25-efd518d600de"); + public static @NotNull ItemStack getBlockAsItem(@NotNull PixelBlock block) { - ItemStack itemStack = ItemStack.of(Material.GRAY_STAINED_GLASS); + return PixelBlockItem.updateBlockAsItem(block, ItemStack.of(Material.GRAY_STAINED_GLASS)); + } + + public static @NotNull ItemStack updateBlockAsItem(@NotNull PixelBlock block, @NotNull ItemStack itemStack) { String ownerName = Optional.ofNullable(Bukkit.getOfflinePlayer(block.ownerUUID).getName()).orElseGet(() -> block.ownerUUID.toString()); ItemMeta meta = itemStack.getItemMeta(); meta.itemName(Component.text(block.blockUUID.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) + )); meta.setEnchantmentGlintOverride(true); itemStack.setItemMeta(meta); @@ -31,8 +44,12 @@ public class PixelBlockItem { ItemStack item = ItemStack.of(Material.GRAY_STAINED_GLASS); ItemMeta meta = item.getItemMeta(); meta.displayName(Component.text("Leerer Pixelblock")); + meta.lore(List.of( + Component.text("Der erste Spieler, welcher den Block platziert wird der Besitzer des Blocks."), + Component.text("Klicke auf den gesetzten Block, um diesen zu bearbeiten!") + )); meta.setEnchantmentGlintOverride(true); - meta.itemName(Component.text("Pixelblock")); + meta.itemName(Component.text(unusedBlockID.toString())); item.setItemMeta(meta); return item; } diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlocksPlugin.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlocksPlugin.java index 6f2c459..7864a4a 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlocksPlugin.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlocksPlugin.java @@ -9,6 +9,8 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.event.Listener; import org.bukkit.plugin.java.JavaPlugin; +import java.io.File; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -18,7 +20,7 @@ public final class PixelBlocksPlugin extends JavaPlugin { public static PixelBlockConfiguration configuration; public static PixelBlockDatabase database; - public static List placedPixelBlocks = new ArrayList<>(); + public static List pixelBlocks = new ArrayList<>(); @Override public void onLoad() { @@ -31,14 +33,13 @@ public final class PixelBlocksPlugin extends JavaPlugin { PixelBlocksPlugin.configuration = new PixelBlockConfiguration( config.getInt(PixelBlockConfiguration.Keys.PixelsPerBlock.getKey()), config.getBoolean(PixelBlockConfiguration.Keys.LiveUpdate.getKey()), - config.getInt(PixelBlockConfiguration.Keys.WorldGrassBorderWidth.getKey()), config.getDouble(PixelBlockConfiguration.Keys.HitboxOffset.getKey()), - config.getBoolean(PixelBlockConfiguration.Keys.DeleteOnBreak.getKey()), config.getBoolean(PixelBlockConfiguration.Keys.OnlyBreakableByOwners.getKey()), config.getBoolean(PixelBlockConfiguration.Keys.OnlyEditableByOwners.getKey()) ); - PixelBlocksPlugin.database = new PixelBlockDatabase("jdbc:sqlite:pixelblocks.db"); + File databaseFile = new File(plugin.getDataFolder(), "blocks.db"); + PixelBlocksPlugin.database = new PixelBlockDatabase("jdbc:sqlite:" + databaseFile); } @Override @@ -46,14 +47,16 @@ public final class PixelBlocksPlugin extends JavaPlugin { database.loadPixelBlocks(); Listener[] listeners = { - new PlayerInteractListener(), - new PlayerMoveListener(), -// new BlockBreakListener(), - new BlockPlaceListener(), - new InventoryListener(), - new PlayerChangeWorldListener(), - new CraftItemListener(), - new InPixelWorldCancelListener() + new EnterPixelBlockListener(), + new FallOutOfPixelBlockListener(), + new BreakPixelListener(), + new PlacePixelBlockListener(), + new PixelWorldInventoryListener(), + new PixelWorldExitListener(), + new CraftPixelBlockListener(), + new PixelWorldBehaviourListener(), + new BreakPixelBlockListener(), + new PlacePixelListener() }; for (Listener listener : listeners) { @@ -65,4 +68,13 @@ public final class PixelBlocksPlugin extends JavaPlugin { Bukkit.addRecipe(PixelBlockItem.getRecipe()); } + + @Override + public void onDisable() { + try { + database.close(); + } catch (SQLException e) { + throw new RuntimeException("Failed disabling", e); + } + } } diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/chunkGenerators/EmptyChunkGenerator.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/chunkGenerators/EmptyChunkGenerator.java deleted file mode 100644 index da783d6..0000000 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/chunkGenerators/EmptyChunkGenerator.java +++ /dev/null @@ -1,15 +0,0 @@ -package eu.mhsl.minecraft.pixelblocks.chunkGenerators; - -import org.bukkit.World; -import org.bukkit.generator.ChunkGenerator; - -import javax.annotation.Nonnull; -import java.util.Random; - -public class EmptyChunkGenerator extends ChunkGenerator { - @Override - @Nonnull - public ChunkData generateChunkData(@Nonnull World world, @Nonnull Random random, int x, int y, @Nonnull BiomeGrid biome) { - return createChunkData(world); - } -} diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/commands/CreatePixelBlockCommand.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/commands/CreatePixelBlockCommand.java index 7b537ca..4b8c69b 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/commands/CreatePixelBlockCommand.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/commands/CreatePixelBlockCommand.java @@ -1,8 +1,8 @@ package eu.mhsl.minecraft.pixelblocks.commands; +import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlockWorld; import eu.mhsl.minecraft.pixelblocks.utils.Direction; import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.command.Command; @@ -11,7 +11,6 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; -import java.util.Arrays; import java.util.UUID; public class CreatePixelBlockCommand implements CommandExecutor { @@ -19,17 +18,20 @@ public class CreatePixelBlockCommand implements CommandExecutor { public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { if(sender instanceof Player p) { World playerWorld = p.getWorld(); - World[] standardWorlds = {Bukkit.getWorlds().get(0), Bukkit.getWorlds().get(1)}; - - if(Arrays.stream(standardWorlds).toList().contains(playerWorld)) { - Location playerLocation = p.getLocation(); - PixelBlock pixelBlock = new PixelBlock(playerLocation, p.getUniqueId(), UUID.randomUUID()); - pixelBlock.place(playerLocation, Direction.south); - } else { - p.sendMessage("Du kannst nur in der Overworld oder im Nether Pixelblocks erstellen!"); + if(PixelBlockWorld.getPixelBlockWorlds().contains(playerWorld)) { + p.sendMessage("Pixelblöcke können nicht innerhalb anderen Pixelblöcken erstellt werden."); + return true; } - } - return(true); + Location playerLocation = p.getLocation(); + PixelBlock block = new PixelBlock( + playerLocation, + p.getUniqueId(), + UUID.randomUUID(), + Direction.south + ); + block.place(playerLocation, Direction.south); + } + return true; } } 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 3d5d40d..10a4442 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/commands/ExitWorldCommand.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/commands/ExitWorldCommand.java @@ -1,9 +1,7 @@ package eu.mhsl.minecraft.pixelblocks.commands; -import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin; import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; -import org.bukkit.Bukkit; -import org.bukkit.Location; +import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlockWorld; import org.bukkit.World; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -18,28 +16,15 @@ public class ExitWorldCommand implements CommandExecutor { public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { if(sender instanceof Player p) { World playerWorld = p.getWorld(); - World[] standardWorlds = {Bukkit.getWorlds().get(0), Bukkit.getWorlds().get(1), Bukkit.getWorlds().get(2)}; - - if(!Arrays.stream(standardWorlds).toList().contains(playerWorld)) { - - List ownedBlocks = PixelBlocksPlugin.placedPixelBlocks.stream() - .filter(pixelBlock -> pixelBlock.ownerUUID.equals(p.getUniqueId())) - .sorted(Comparator.comparing(pixelBlock -> pixelBlock.lastEntryTime)) - .toList(); - - Location newLocation; - if(!ownedBlocks.isEmpty()) { - newLocation = ownedBlocks.getLast().lastEntryLocation; - } else { - newLocation = Bukkit.getWorlds().getFirst().getSpawnLocation(); - } - p.teleport(newLocation); - - } else { - p.sendMessage("Dieser Command ist nur für PixelBlock Welten verfügbar!"); + if(PixelBlockWorld.getOtherWorlds().contains(playerWorld)) { + p.sendMessage("Du kannst nur Pixelblöcke verlassen."); + return true; } - } - return(true); + PixelBlock currentPixelBlock = PixelBlock.getPixelBlockFromBlockWorld(playerWorld); + Objects.requireNonNull(currentPixelBlock); + p.teleport(currentPixelBlock.lastEntryLocation); + } + return true; } } diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/BlockBreakListener.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/BlockBreakListener.java deleted file mode 100644 index 6645e5b..0000000 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/BlockBreakListener.java +++ /dev/null @@ -1,18 +0,0 @@ -//package eu.mhsl.minecraft.pixelblocks.listeners; -// -//import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; -//import org.bukkit.event.EventHandler; -//import org.bukkit.event.Listener; -//import org.bukkit.event.block.BlockBreakEvent; -// -//public class BlockBreakListener implements Listener { -// @EventHandler -// static void onBlockBreak(BlockBreakEvent event) { -// if(CommonEventHandlers.isInPixelWorld(event.getBlock().getWorld())) { -// PixelBlock pixelBlock = PixelBlock.getPixelBlockFromWorld(event.getBlock().getLocation().getWorld()); -// -// assert pixelBlock != null; -// pixelBlock.handleBlockBreak(event); -// } -// } -//} diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/BlockPlaceListener.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/BlockPlaceListener.java deleted file mode 100644 index 6b4c688..0000000 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/BlockPlaceListener.java +++ /dev/null @@ -1,55 +0,0 @@ -package eu.mhsl.minecraft.pixelblocks.listeners; - -import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; -import eu.mhsl.minecraft.pixelblocks.utils.Direction; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.Arrays; -import java.util.UUID; - -public class BlockPlaceListener implements Listener { - @EventHandler - static void onBlockPlace(BlockPlaceEvent event) { - - if(event.getItemInHand().getItemMeta().getDisplayName().contains("Pixelblock") - && !event.getItemInHand().getItemMeta().getItemName().isEmpty() - && event.getItemInHand().getItemMeta().getEnchantmentGlintOverride()) { - event.setCancelled(true); - - World playerWorld = event.getPlayer().getWorld(); - World[] standardWorlds = {Bukkit.getWorlds().get(0), Bukkit.getWorlds().get(1)}; // don't allow Pixelblocks in the end dimension - - if(Arrays.stream(standardWorlds).toList().contains(playerWorld)) { - Location newBlockLocation = event.getBlock().getLocation(); - - if(event.getItemInHand().getItemMeta().getItemName().startsWith("Pixelblock")) { - ItemMeta newMeta = event.getItemInHand().getItemMeta(); - newMeta.setItemName(UUID.randomUUID().toString()); - event.getItemInHand().setItemMeta(newMeta); - } - - PixelBlock pixelBlock = new PixelBlock(newBlockLocation, event.getPlayer().getUniqueId(), UUID.fromString(event.getItemInHand().getItemMeta().getItemName())); - if(pixelBlock.place(newBlockLocation, Direction.vectorToDirection(event.getPlayer().getLocation().getDirection()))) { - event.getPlayer().getInventory().remove(event.getItemInHand()); - } else { - event.getPlayer().sendMessage("Hier wurde bereits ein Pixelblock plaziert."); - } - } else { - event.getPlayer().sendMessage("Du kannst nur in der Overworld oder im Nether Pixelblocks platzieren!"); - } - } else { -// if(CommonEventHandlers.isInPixelWorld(event.getBlock().getWorld())) { -// PixelBlock pixelBlock = PixelBlock.getPixelBlockFromWorld(event.getBlock().getLocation().getWorld()); -// -// assert pixelBlock != null; -// pixelBlock.handleBlockPlace(event); -// } - } - } -} diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlayerInteractListener.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/BreakPixelBlockListener.java similarity index 50% rename from src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlayerInteractListener.java rename to src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/BreakPixelBlockListener.java index 433002f..31b3e0a 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlayerInteractListener.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/BreakPixelBlockListener.java @@ -3,29 +3,14 @@ package eu.mhsl.minecraft.pixelblocks.listeners; import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin; import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; import io.papermc.paper.event.player.PrePlayerAttackEntityEvent; -import org.bukkit.*; +import org.bukkit.Location; import org.bukkit.entity.Interaction; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerInteractEntityEvent; -public class PlayerInteractListener implements Listener { +public class BreakPixelBlockListener implements Listener { @EventHandler - static void onPlayerInteractEntity(PlayerInteractEntityEvent event) { - if(event.getRightClicked() instanceof Interaction) { - Location interactionLocation = event.getRightClicked().getLocation().clone().add(0, PixelBlocksPlugin.configuration.hitboxOffset(), 0).toBlockLocation(); - interactionLocation.setYaw(0); - interactionLocation.setPitch(0); - - PixelBlock pixelBlock = PixelBlock.getPixelBlockFromPlacedLocation(interactionLocation); - - assert pixelBlock != null; - pixelBlock.enterBlock(event.getPlayer()); - } - } - - @EventHandler - static void onPlayerAttackEntity(PrePlayerAttackEntityEvent event) { + static void destroyPixelBlock(PrePlayerAttackEntityEvent event) { if(event.getAttacked() instanceof Interaction) { Location blockLocation = event.getAttacked().getLocation().add(0, PixelBlocksPlugin.configuration.hitboxOffset(), 0).toBlockLocation(); blockLocation.setYaw(0); diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/BreakPixelListener.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/BreakPixelListener.java new file mode 100644 index 0000000..1f33625 --- /dev/null +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/BreakPixelListener.java @@ -0,0 +1,27 @@ +package eu.mhsl.minecraft.pixelblocks.listeners; + +import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; +import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlockWorld; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; + +import java.util.Objects; + +public class BreakPixelListener implements Listener { + @EventHandler + static void onBlockBreak(BlockBreakEvent event) { + World world = event.getBlock().getWorld(); + if(!PixelBlockWorld.isPixelWorld(world)) return; + + PixelBlock pixelBlock = PixelBlock.getPixelBlockFromBlockWorld(world); + Objects.requireNonNull(pixelBlock); + + PixelBlockWorld pixelBlockWorld = pixelBlock.getPixelWorld(); + + Location blockLocation = event.getBlock().getLocation(); + if(!pixelBlockWorld.allowPlacements(blockLocation)) event.setCancelled(true); + } +} diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/CraftItemListener.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/CraftItemListener.java deleted file mode 100644 index b1de9c1..0000000 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/CraftItemListener.java +++ /dev/null @@ -1,24 +0,0 @@ -package eu.mhsl.minecraft.pixelblocks.listeners; - -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.CraftItemEvent; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.Objects; -import java.util.UUID; - -public class CraftItemListener implements Listener { - @EventHandler - static void onCraftItem(CraftItemEvent event) { - if(Objects.requireNonNull(event.getCurrentItem()).getItemMeta().getDisplayName().contains("Pixelblock")) { - if(event.isShiftClick()) { - event.setCancelled(true); - } else { - ItemMeta meta = event.getCurrentItem().getItemMeta(); - meta.setItemName("Pixelblock " + UUID.randomUUID()); - event.getCurrentItem().setItemMeta(meta); - } - } - } -} diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/CraftPixelBlockListener.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/CraftPixelBlockListener.java new file mode 100644 index 0000000..0201d53 --- /dev/null +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/CraftPixelBlockListener.java @@ -0,0 +1,25 @@ +package eu.mhsl.minecraft.pixelblocks.listeners; + +import eu.mhsl.minecraft.pixelblocks.PixelBlockItem; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.CraftItemEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Objects; + +public class CraftPixelBlockListener implements Listener { + @EventHandler + static void onCraftItem(CraftItemEvent event) { + ItemStack craftedItem = event.getCurrentItem(); + Objects.requireNonNull(craftedItem); + + ItemMeta craftedItemMeta = craftedItem.getItemMeta(); + String itemName = PlainTextComponentSerializer.plainText().serialize(craftedItemMeta.itemName()); + + if(!itemName.equals(PixelBlockItem.unusedBlockID.toString())) return; + if(event.isShiftClick()) event.setCancelled(true); + } +} diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/EnterPixelBlockListener.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/EnterPixelBlockListener.java new file mode 100644 index 0000000..4da1b36 --- /dev/null +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/EnterPixelBlockListener.java @@ -0,0 +1,30 @@ +package eu.mhsl.minecraft.pixelblocks.listeners; + +import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin; +import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; +import org.bukkit.*; +import org.bukkit.entity.Interaction; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerInteractEntityEvent; + +public class EnterPixelBlockListener implements Listener { + @EventHandler + static void enterPixelBlock(PlayerInteractEntityEvent event) { + if(event.getRightClicked() instanceof Interaction) { + Location interactionLocation = event + .getRightClicked() + .getLocation() + .add(0, PixelBlocksPlugin.configuration.hitboxOffset(), 0) + .toBlockLocation(); + + interactionLocation.setYaw(0); + interactionLocation.setPitch(0); + + PixelBlock pixelBlock = PixelBlock.getPixelBlockFromPlacedLocation(interactionLocation); + + assert pixelBlock != null; + pixelBlock.enterBlock(event.getPlayer()); + } + } +} diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/FallOutOfPixelBlockListener.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/FallOutOfPixelBlockListener.java new file mode 100644 index 0000000..856d4b6 --- /dev/null +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/FallOutOfPixelBlockListener.java @@ -0,0 +1,23 @@ +package eu.mhsl.minecraft.pixelblocks.listeners; + +import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; +import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlockWorld; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; + +import java.util.Objects; + +public class FallOutOfPixelBlockListener implements Listener { + @EventHandler + static void onPlayerMove(PlayerMoveEvent event) { + Player player = event.getPlayer(); + if(player.getLocation().y() > -65) return; + if(!PixelBlockWorld.isPixelWorld(player.getWorld())) return; + + PixelBlock pixelBlock = PixelBlock.getPixelBlockFromBlockWorld(player.getWorld()); + Objects.requireNonNull(pixelBlock); + player.teleport(pixelBlock.getPixelWorld().getSpawnLocation()); + } +} diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/InPixelWorldCancelListener.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PixelWorldBehaviourListener.java similarity index 95% rename from src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/InPixelWorldCancelListener.java rename to src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PixelWorldBehaviourListener.java index 3a072a2..04b3b5d 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/InPixelWorldCancelListener.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PixelWorldBehaviourListener.java @@ -9,7 +9,7 @@ import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerPortalEvent; -public class InPixelWorldCancelListener implements Listener { +public class PixelWorldBehaviourListener implements Listener { @EventHandler static void onBlockExplode(BlockExplodeEvent event) { CommonEventHandlers.cancelIfInPixelWorld(event, event.getBlock().getWorld()); diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PixelWorldExitListener.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PixelWorldExitListener.java new file mode 100644 index 0000000..142cd3c --- /dev/null +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PixelWorldExitListener.java @@ -0,0 +1,35 @@ +package eu.mhsl.minecraft.pixelblocks.listeners; + +import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; +import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlockWorld; +import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerChangedWorldEvent; +import org.bukkit.event.player.PlayerPortalEvent; + +import java.util.Objects; + +public class PixelWorldExitListener implements Listener { + @EventHandler + static void onPlayerChangeWorld(PlayerChangedWorldEvent event) { + World changingFrom = event.getFrom(); + if(!PixelBlockWorld.isPixelWorld(changingFrom)) return; + + PixelBlock pixelBlock = PixelBlock.getPixelBlockFromBlockWorld(changingFrom); + Objects.requireNonNull(pixelBlock); + pixelBlock.updateEntities(); + } + + @EventHandler + static void onPlayerPortal(PlayerPortalEvent event) { + World pixelBlockWorld = event.getFrom().getWorld(); + + if(!PixelBlockWorld.isPixelWorld(pixelBlockWorld)) return; + + event.setCancelled(true); + PixelBlock pixelBlock = PixelBlock.getPixelBlockFromBlockWorld(pixelBlockWorld); + Objects.requireNonNull(pixelBlock); + event.getPlayer().teleport(pixelBlock.lastEntryLocation); + } +} diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/InventoryListener.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PixelWorldInventoryListener.java similarity index 96% rename from src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/InventoryListener.java rename to src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PixelWorldInventoryListener.java index c77e4bd..3dd8429 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/InventoryListener.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PixelWorldInventoryListener.java @@ -6,7 +6,7 @@ import org.bukkit.event.inventory.*; import org.bukkit.inventory.CraftingInventory; import org.bukkit.inventory.PlayerInventory; -public class InventoryListener implements Listener { +public class PixelWorldInventoryListener implements Listener { @EventHandler static void onInventoryOpen(InventoryOpenEvent event) { if(CommonEventHandlers.isInPixelWorld(event.getPlayer().getWorld())) { diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlacePixelBlockListener.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlacePixelBlockListener.java new file mode 100644 index 0000000..5e34565 --- /dev/null +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlacePixelBlockListener.java @@ -0,0 +1,72 @@ +package eu.mhsl.minecraft.pixelblocks.listeners; + +import eu.mhsl.minecraft.pixelblocks.PixelBlockItem; +import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin; +import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; +import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlockWorld; +import eu.mhsl.minecraft.pixelblocks.utils.Direction; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.UUID; + +public class PlacePixelBlockListener implements Listener { + @EventHandler + static void onBlockPlace(BlockPlaceEvent event) { + ItemStack usedItem = event.getItemInHand(); + ItemMeta usedItemMeta = usedItem.getItemMeta(); + Component displayName = usedItemMeta.displayName(); + if(displayName == null) return; + if(!displayName.toString().contains("Pixelblock")) return; + if(!usedItemMeta.getEnchantmentGlintOverride()) return; + + World playerWorld = event.getPlayer().getWorld(); + if(PixelBlockWorld.isPixelWorld(playerWorld)) { + event.getPlayer().sendMessage("In Pixelblöcken kann kein Pixelblock erstellt werden."); + event.setCancelled(true); + return; + } + + Location newBlockLocation = event.getBlock().getLocation(); + playerWorld.getBlockAt(newBlockLocation).setType(Material.AIR); + + Direction direction = Direction.vectorToDirection(event.getPlayer().getLocation().getDirection()); + String itemName = PlainTextComponentSerializer.plainText().serialize(usedItemMeta.itemName()); + + PixelBlock pixelBlock; + if(itemName.equals(PixelBlockItem.unusedBlockID.toString())) { + pixelBlock = new PixelBlock( + newBlockLocation, + event.getPlayer().getUniqueId(), + UUID.randomUUID(), + direction + ); + } else { + UUID itemUUID = UUID.fromString(itemName); + pixelBlock = PixelBlocksPlugin.pixelBlocks.stream() + .filter(block -> block.blockUUID.equals(itemUUID)) + .findFirst() + .orElseGet(() -> new PixelBlock( + newBlockLocation, + event.getPlayer().getUniqueId(), + itemUUID, + direction + )); + } + + try { + pixelBlock.place(newBlockLocation, direction); + } catch (IllegalArgumentException e) { + event.setCancelled(true); + event.getPlayer().sendMessage(Component.text(e.getMessage())); + } + } +} diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlacePixelListener.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlacePixelListener.java new file mode 100644 index 0000000..008b3bb --- /dev/null +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlacePixelListener.java @@ -0,0 +1,27 @@ +package eu.mhsl.minecraft.pixelblocks.listeners; + +import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; +import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlockWorld; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPlaceEvent; + +import java.util.Objects; + +public class PlacePixelListener implements Listener { + @EventHandler + static void onBlockPlace(BlockPlaceEvent event) { + World world = event.getBlock().getWorld(); + if(!PixelBlockWorld.isPixelWorld(world)) return; + + PixelBlock pixelBlock = PixelBlock.getPixelBlockFromBlockWorld(world); + Objects.requireNonNull(pixelBlock); + + PixelBlockWorld pixelBlockWorld = pixelBlock.getPixelWorld(); + + Location blockLocation = event.getBlock().getLocation(); + if(!pixelBlockWorld.allowPlacements(blockLocation)) event.setCancelled(true); + } +} diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlayerChangeWorldListener.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlayerChangeWorldListener.java deleted file mode 100644 index 9b73ad9..0000000 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlayerChangeWorldListener.java +++ /dev/null @@ -1,18 +0,0 @@ -package eu.mhsl.minecraft.pixelblocks.listeners; - -import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerChangedWorldEvent; - -import java.util.Objects; - -public class PlayerChangeWorldListener implements Listener { - @EventHandler - static void onPlayerChangeWorld(PlayerChangedWorldEvent event) { - if(CommonEventHandlers.isInPixelWorld(event.getFrom())) { -// Bukkit.getScheduler().runTaskLater(plugin, () -> Objects.requireNonNull(PixelBlock.getPixelBlockFromWorld(event.getFrom())).update(), 60); - Objects.requireNonNull(PixelBlock.getPixelBlockFromBlockWorld(event.getFrom())).update(); - } - } -} diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlayerMoveListener.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlayerMoveListener.java deleted file mode 100644 index 61bba8a..0000000 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/listeners/PlayerMoveListener.java +++ /dev/null @@ -1,32 +0,0 @@ -package eu.mhsl.minecraft.pixelblocks.listeners; - -import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; -import org.bukkit.Location; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerMoveEvent; - -public class PlayerMoveListener implements Listener { - @EventHandler - static void onPlayerMove(PlayerMoveEvent event) { - if(CommonEventHandlers.isInPixelWorld(event.getPlayer().getWorld())) { - Location playerLocation = event.getPlayer().getLocation(); - PixelBlock pixelBlock = PixelBlock.getPixelBlockFromBlockWorld(event.getPlayer().getWorld()); - assert pixelBlock != null; - Location portalLocation = pixelBlock.getPixelWorld().getPortalLocation().clone(); - - if(playerLocation.y() < -65) { - event.getPlayer().teleport(pixelBlock.getPixelWorld().getSpawnLocation()); - } else if(playerLocation.getZ() < portalLocation.getZ()+1 - && playerLocation.getZ() > portalLocation.getZ()) { - if(playerLocation.getX() < portalLocation.getX()+3 - && playerLocation.getX() > portalLocation.getX()+1) { - if(playerLocation.getY() < portalLocation.getY()+4 - && playerLocation.getY() > portalLocation.getY()+1) { - event.getPlayer().teleport(pixelBlock.lastEntryLocation); - } - } - } - } - } -} 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 0a88e0e..3170042 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlock.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlock.java @@ -38,7 +38,7 @@ public class PixelBlock { } public static @Nullable PixelBlock getPixelBlockFromBlockWorld(World world) { - return PixelBlocksPlugin.placedPixelBlocks.stream() + return PixelBlocksPlugin.pixelBlocks.stream() .filter(block -> block.blockUUID.equals(getUUIDFromWorld(world))) .findFirst() .orElse(null); @@ -57,13 +57,15 @@ public class PixelBlock { searchLocation.setPitch(0); searchLocation.setYaw(0); - return PixelBlocksPlugin.placedPixelBlocks.stream() + return PixelBlocksPlugin.pixelBlocks.stream() .filter(block -> block.pixelBlockLocation.equals(searchLocation)) .findFirst() .orElse(null); } - public PixelBlock(Location originLocation, UUID ownerUUID, UUID blockUUID) { + public PixelBlock(Location originLocation, UUID ownerUUID, UUID blockUUID, Direction direction) { + PixelBlocksPlugin.pixelBlocks.add(this); + this.ownerUUID = ownerUUID; this.blockUUID = blockUUID; @@ -71,7 +73,7 @@ public class PixelBlock { this.pixelBlockLocation.setYaw(0); this.pixelBlockLocation.setPitch(0); - this.facingDirection = Direction.south; // TODO ?? + this.facingDirection = direction; this.pixelWorld = new PixelBlockWorld(this); } @@ -89,6 +91,10 @@ public class PixelBlock { player.teleport(this.pixelWorld.getSpawnLocation()); } + public void setLastEntryLocation(Location lastEntryLocation) { + this.lastEntryLocation = lastEntryLocation; + } + public void spawnInteraction(boolean fullBlock) { if(fullBlock) { hitbox = (Interaction) pixelBlockLocation.getWorld().spawnEntity( @@ -145,7 +151,7 @@ public class PixelBlock { } } - public void update() { + public void updateEntities() { Bukkit.getScheduler().runTask(PixelBlocksPlugin.plugin, () -> { this.clearEntities(); @@ -195,20 +201,18 @@ public class PixelBlock { }); } - public boolean place(Location placeLocation, Direction direction) { + public void place(Location placeLocation, Direction direction) { Location newLocation = placeLocation.toBlockLocation(); newLocation.setPitch(0); newLocation.setYaw(0); - if(PixelBlock.getPixelBlockFromPlacedLocation(newLocation) == null || PixelBlock.getPixelBlockFromPlacedLocation(newLocation) == this) { - this.pixelBlockLocation = newLocation; - this.facingDirection = direction; - update(); - PixelBlocksPlugin.database.savePixelBlock(this); - PixelBlocksPlugin.placedPixelBlocks.add(this); - return true; - } - return false; + @Nullable PixelBlock blockAtLocation = PixelBlock.getPixelBlockFromPlacedLocation(newLocation); + if(blockAtLocation != null && blockAtLocation != this) throw new IllegalArgumentException("Es können nicht mehrere Pixelblöcke ineinander platziert werden."); + + this.pixelBlockLocation = newLocation; + this.facingDirection = direction; + updateEntities(); + PixelBlocksPlugin.database.savePixelBlock(this); } public void destroy(Player destroyedBy) { @@ -218,15 +222,16 @@ public class PixelBlock { } this.pixelWorld.getPlayersInWorld().forEach(p -> { - p.sendMessage("Der Pixelblock wurde abgebaut!"); + p.sendMessage("Der Pixelblock wurde von einem anderen Spieler abgebaut."); p.teleport(this.lastEntryLocation); }); - this.pixelWorld.getEntitiesInWorld().forEach(entity -> entity.teleport(this.lastEntryLocation)); + this.pixelWorld.getEntitiesInWorld().stream() + .filter(entity -> entity instanceof Item) + .forEach(entity -> entity.teleport(this.lastEntryLocation)); this.clearEntities(); - PixelBlocksPlugin.database.removePixelBlock(this); - PixelBlocksPlugin.placedPixelBlocks.remove(this); + PixelBlocksPlugin.database.deletePixelBlock(this); this.pixelBlockLocation.getWorld().playSound(this.pixelBlockLocation, Sound.BLOCK_COPPER_BULB_BREAK, 1.0F, 30); this.pixelBlockLocation.getWorld().dropItem(this.pixelBlockLocation.add(new Vector(0.5, 0.5, 0.5)), PixelBlockItem.getBlockAsItem(this)); } @@ -267,7 +272,11 @@ public class PixelBlock { } - public PixelBlockWorld getPixelWorld() { + public @NotNull PixelBlockWorld getPixelWorld() { return pixelWorld; } + + public int getPixelsPerBlock() { + return 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 ee9b412..23e3e92 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockWorld.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockWorld.java @@ -1,15 +1,17 @@ package eu.mhsl.minecraft.pixelblocks.pixelblock; import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin; -import eu.mhsl.minecraft.pixelblocks.chunkGenerators.EmptyChunkGenerator; +import eu.mhsl.minecraft.pixelblocks.utils.LocationUtil; import org.bukkit.*; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.generator.ChunkGenerator; import org.jetbrains.annotations.NotNull; import java.io.File; import java.util.List; import java.util.Objects; +import java.util.Random; import static eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin.plugin; @@ -17,7 +19,7 @@ public class PixelBlockWorld { private final PixelBlock parentPixelBlock; private final World world; - int worldGrassBorderWidth = PixelBlocksPlugin.configuration.worldGrassBorderWidth(); + int worldGrassBorderWidth = 10; int pixelsPerBlock = PixelBlocksPlugin.configuration.pixelsPerBlock(); public static boolean isPixelWorld(@NotNull World world) { @@ -38,8 +40,16 @@ public class PixelBlockWorld { this.setBuildingPlatform(); } + public boolean allowPlacements(Location blockLocation) { + Location origin = getBuildOrigin(); + int offset = pixelsPerBlock - 1; + return blockLocation.x() >= origin.x() && blockLocation.x() <= origin.x() + offset + && blockLocation.z() >= origin.z() && blockLocation.z() <= origin.z() + offset + && blockLocation.y() >= origin.y() && blockLocation.y() <= origin.y() + offset; + } + public @NotNull String getWorldPathName() { - return PixelBlocksPlugin.plugin.getDataFolder().getPath() + File.separator + this.parentPixelBlock.blockUUID; + return PixelBlocksPlugin.plugin.getDataFolder().getPath() + File.separator + "worlds" + File.separator + this.parentPixelBlock.blockUUID; } public @NotNull Location getSpawnLocation() { @@ -47,7 +57,7 @@ public class PixelBlockWorld { } public @NotNull Location getPortalLocation() { - return this.getBuildOrigin().add((double) pixelsPerBlock/2 -2, 0, -worldGrassBorderWidth); + return this.getBuildOrigin().add((double) pixelsPerBlock/2 -2, 0, -worldGrassBorderWidth+3); } public @NotNull List getPlayersInWorld() { @@ -62,11 +72,27 @@ public class PixelBlockWorld { return new Location(this.world, 0, -60, 0); } + public @NotNull Location getBuildOriginEnd() { + return getBuildOrigin().add(pixelsPerBlock, pixelsPerBlock, pixelsPerBlock); + } + + public @NotNull Location getBorderOrigin() { + return getBuildOrigin().subtract(1, 1, 1); + } + + public @NotNull Location getPlatformOrigin() { + return getBorderOrigin().subtract(worldGrassBorderWidth, 0, worldGrassBorderWidth); + } + + public @NotNull Location getPlatformOriginEnd() { + return getBorderOrigin().add(worldGrassBorderWidth + pixelsPerBlock, 0, worldGrassBorderWidth + pixelsPerBlock); + } + private World loadOrCreatePixelWorld() { final WorldCreator worldCreator = new WorldCreator(getWorldPathName()); worldCreator.type(WorldType.FLAT); - worldCreator.generator(new EmptyChunkGenerator()); + worldCreator.generator(new ChunkGenerator() {}); World world = Bukkit.createWorld(worldCreator); Objects.requireNonNull(world); @@ -78,45 +104,71 @@ public class PixelBlockWorld { world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false); WorldBorder worldBorder = world.getWorldBorder(); - worldBorder.setCenter(getBuildOrigin()); + worldBorder.setCenter(getBuildOrigin().add((double) pixelsPerBlock / 2, 0, (double) pixelsPerBlock / 2)); + worldBorder.setSize(pixelsPerBlock + (2*worldGrassBorderWidth)); + worldBorder.setWarningDistance(0); + worldBorder.setDamageAmount(0); return world; } private void setBuildingPlatform() { - Location borderStartLocation = getBuildOrigin().subtract(1, 1, 1); - Location grassStartLocation = borderStartLocation.clone().subtract(worldGrassBorderWidth, 0, worldGrassBorderWidth); - Bukkit.getScheduler().runTask(PixelBlocksPlugin.plugin, () -> { for (int x = 0; x < (pixelsPerBlock+2) + 2 * worldGrassBorderWidth; x++) { for (int z = 0; z < (pixelsPerBlock+2) + 2 * worldGrassBorderWidth; z++) { - grassStartLocation.clone().add(x, 0, z).getBlock().setType(Material.GRASS_BLOCK); + getPlatformOrigin().add(x, 0, z).getBlock().setType(Material.GRASS_BLOCK); } } for (int x = 0; x < (pixelsPerBlock+2) + 2 * worldGrassBorderWidth; x++) { for (int z = 0; z < (pixelsPerBlock+2) + 2 * worldGrassBorderWidth; z++) { - grassStartLocation.clone().add(x, -1, z).getBlock().setType(Material.DIRT); + getPlatformOrigin().add(x, -1, z).getBlock().setType(Material.DIRT); } } + for (int x = 0; x < (pixelsPerBlock+2); x++) { for (int z = 0; z < (pixelsPerBlock+2); z++) { - Location currentLocation = borderStartLocation.clone().add(x, 0, z); + Location currentLocation = getBorderOrigin().add(x, 0, z); - if (currentLocation.x() == borderStartLocation.x() || currentLocation.z() == borderStartLocation.z()) { + if (currentLocation.x() == getBorderOrigin().x() || currentLocation.z() == getBorderOrigin().z()) { currentLocation.getBlock().setType(Material.RED_CONCRETE); - } else if (currentLocation.x() == borderStartLocation.x() + (pixelsPerBlock+1) || currentLocation.z() == borderStartLocation.z() + (pixelsPerBlock+1)) { + } else if (currentLocation.x() == getBorderOrigin().x() + (pixelsPerBlock+1) || currentLocation.z() == getBorderOrigin().z() + (pixelsPerBlock+1)) { currentLocation.getBlock().setType(Material.RED_CONCRETE); } } } - for (int x = (2*worldGrassBorderWidth+pixelsPerBlock-1)/2; x < (2*worldGrassBorderWidth+pixelsPerBlock-1)/2+4; x++) { + Random random = new Random(); + LocationUtil.iterateBlocks(getPlatformOrigin().add(1, 1, 1), getPlatformOriginEnd().add(0, 1, 0), location -> { + if (allowPlacements(location)) return; + if (!location.clone().subtract(0, 1, 0).getBlock().getType().equals(Material.GRASS_BLOCK)) return; + if (!location.getBlock().getType().equals(Material.AIR)) return; + + if (random.nextInt(10) == 0) { + Material[] flowers = { + Material.DANDELION, + Material.POPPY, + Material.BLUE_ORCHID, + Material.ALLIUM, + Material.AZURE_BLUET, + Material.RED_TULIP, + Material.ORANGE_TULIP, + Material.WHITE_TULIP, + Material.CORNFLOWER, + Material.LILY_OF_THE_VALLEY, + }; + + Material randomFlower = flowers[random.nextInt(flowers.length)]; + location.getBlock().setType(randomFlower); + } + }); + + for (int x = 0; x < 4; x++) { for (int y = 0; y < 5; y++) { - grassStartLocation.clone().add(x, 1+y, 0).getBlock().setType(Material.OBSIDIAN); + getPortalLocation().add(x, y, 0).getBlock().setType(Material.OBSIDIAN); } } - for (int x = (2*worldGrassBorderWidth+pixelsPerBlock-1)/2+1; x < (2*worldGrassBorderWidth+pixelsPerBlock-1)/2+3; x++) { + for (int x = 1; x < 3; x++) { for (int y = 1; y < 4; y++) { - grassStartLocation.clone().add(x, 1+y, 0).getBlock().setType(Material.NETHER_PORTAL); + getPortalLocation().add(x, y, 0).getBlock().setType(Material.NETHER_PORTAL); } } }); diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/utils/LocationUtil.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/utils/LocationUtil.java new file mode 100644 index 0000000..83bc1f1 --- /dev/null +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/utils/LocationUtil.java @@ -0,0 +1,30 @@ +package eu.mhsl.minecraft.pixelblocks.utils; + +import org.bukkit.Location; +import org.bukkit.World; + +import java.util.function.Consumer; + +public class LocationUtil { + public static void iterateBlocks(Location loc1, Location loc2, Consumer action) { + if (loc1.getWorld() != loc2.getWorld()) { + throw new IllegalArgumentException("Locations must be in the same world"); + } + + World world = loc1.getWorld(); + int minX = Math.min(loc1.getBlockX(), loc2.getBlockX()); + int maxX = Math.max(loc1.getBlockX(), loc2.getBlockX()); + int minY = Math.min(loc1.getBlockY(), loc2.getBlockY()); + int maxY = Math.max(loc1.getBlockY(), loc2.getBlockY()); + int minZ = Math.min(loc1.getBlockZ(), loc2.getBlockZ()); + int maxZ = Math.max(loc1.getBlockZ(), loc2.getBlockZ()); + + for (int x = minX; x <= maxX; x++) { + for (int y = minY; y <= maxY; y++) { + for (int z = minZ; z <= maxZ; z++) { + action.accept(new Location(world, x, y, z)); + } + } + } + } +}