wip: further code cleanup
This commit is contained in:
		@@ -6,18 +6,14 @@ import org.jetbrains.annotations.NotNull;
 | 
				
			|||||||
public record PixelBlockConfiguration(
 | 
					public record PixelBlockConfiguration(
 | 
				
			||||||
        int pixelsPerBlock,
 | 
					        int pixelsPerBlock,
 | 
				
			||||||
        boolean liveUpdate,
 | 
					        boolean liveUpdate,
 | 
				
			||||||
        int worldGrassBorderWidth,
 | 
					 | 
				
			||||||
        double hitboxOffset,
 | 
					        double hitboxOffset,
 | 
				
			||||||
        boolean deleteOnBreak, // TODO does no longer exists
 | 
					 | 
				
			||||||
        boolean onlyBreakableByOwner,
 | 
					        boolean onlyBreakableByOwner,
 | 
				
			||||||
        boolean onlyEditableByOwner
 | 
					        boolean onlyEditableByOwner
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    public static void setDefaults(FileConfiguration config) {
 | 
					    public static void setDefaults(FileConfiguration config) {
 | 
				
			||||||
        config.addDefault(Keys.PixelsPerBlock.key, 16);
 | 
					        config.addDefault(Keys.PixelsPerBlock.key, 16);
 | 
				
			||||||
        config.addDefault(Keys.LiveUpdate.key, true);
 | 
					        config.addDefault(Keys.LiveUpdate.key, true);
 | 
				
			||||||
        config.addDefault(Keys.WorldGrassBorderWidth.key, 5);
 | 
					 | 
				
			||||||
        config.addDefault(Keys.HitboxOffset.key, 0.005);
 | 
					        config.addDefault(Keys.HitboxOffset.key, 0.005);
 | 
				
			||||||
        config.addDefault(Keys.DeleteOnBreak.key, false);
 | 
					 | 
				
			||||||
        config.addDefault(Keys.OnlyBreakableByOwners.key, false);
 | 
					        config.addDefault(Keys.OnlyBreakableByOwners.key, false);
 | 
				
			||||||
        config.addDefault(Keys.OnlyEditableByOwners.key, true);
 | 
					        config.addDefault(Keys.OnlyEditableByOwners.key, true);
 | 
				
			||||||
        config.options().copyDefaults(true);
 | 
					        config.options().copyDefaults(true);
 | 
				
			||||||
@@ -26,9 +22,7 @@ public record PixelBlockConfiguration(
 | 
				
			|||||||
    public enum Keys {
 | 
					    public enum Keys {
 | 
				
			||||||
        PixelsPerBlock("pixelsPerBlock"),
 | 
					        PixelsPerBlock("pixelsPerBlock"),
 | 
				
			||||||
        LiveUpdate("liveUpdate"),
 | 
					        LiveUpdate("liveUpdate"),
 | 
				
			||||||
        WorldGrassBorderWidth("worldGrassBorderWidth"),
 | 
					 | 
				
			||||||
        HitboxOffset("hitboxOffset"),
 | 
					        HitboxOffset("hitboxOffset"),
 | 
				
			||||||
        DeleteOnBreak("deleteOnBreak"),
 | 
					 | 
				
			||||||
        OnlyBreakableByOwners("onlyBreakableByOwners"),
 | 
					        OnlyBreakableByOwners("onlyBreakableByOwners"),
 | 
				
			||||||
        OnlyEditableByOwners("onlyEditableByOwners");
 | 
					        OnlyEditableByOwners("onlyEditableByOwners");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,8 +4,6 @@ import eu.mhsl.minecraft.pixelblocks.utils.Direction;
 | 
				
			|||||||
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
 | 
					import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
 | 
				
			||||||
import org.bukkit.Bukkit;
 | 
					import org.bukkit.Bukkit;
 | 
				
			||||||
import org.bukkit.Location;
 | 
					import org.bukkit.Location;
 | 
				
			||||||
import org.bukkit.entity.Entity;
 | 
					 | 
				
			||||||
import org.bukkit.entity.EntityType;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.sql.*;
 | 
					import java.sql.*;
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
@@ -13,138 +11,21 @@ import java.util.List;
 | 
				
			|||||||
import java.util.UUID;
 | 
					import java.util.UUID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class PixelBlockDatabase {
 | 
					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) {
 | 
					    public PixelBlockDatabase(String url) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
 | 
					            Class.forName("org.sqlite.JDBC");
 | 
				
			||||||
            this.db = DriverManager.getConnection(url);
 | 
					            this.db = DriverManager.getConnection(url);
 | 
				
			||||||
        } catch (SQLException e) {
 | 
					 | 
				
			||||||
            throw new RuntimeException("Failed to load Database", e);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Statement getStatement() throws SQLException {
 | 
					            this.db.createStatement().execute(
 | 
				
			||||||
        return this.db.createStatement();
 | 
					                    "CREATE TABLE IF NOT EXISTS pixelblocks (" +
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void removePixelBlock(PixelBlock pixelBlock) {
 | 
					 | 
				
			||||||
        Bukkit.getScheduler().runTask(PixelBlocksPlugin.plugin, () -> {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            try {
 | 
					 | 
				
			||||||
                PreparedStatement prep = this.db.prepareStatement("DELETE FROM pixelblocks WHERE uuid = ?");
 | 
					 | 
				
			||||||
                prep.setString(1, pixelBlock.blockUUID.toString());
 | 
					 | 
				
			||||||
                prep.executeUpdate();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                prep.close();
 | 
					 | 
				
			||||||
            } catch (SQLException e) {
 | 
					 | 
				
			||||||
                System.err.println(e.getMessage());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void savePixelBlock(PixelBlock pixelBlock) {
 | 
					 | 
				
			||||||
        Bukkit.getScheduler().runTask(PixelBlocksPlugin.plugin, () -> {
 | 
					 | 
				
			||||||
            List<UUID> uuids = new ArrayList<>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            try (var statement = getStatement()) {
 | 
					 | 
				
			||||||
                ResultSet pixelBlocksResult = statement.executeQuery("SELECT * FROM pixelblocks;");
 | 
					 | 
				
			||||||
                while (pixelBlocksResult.next()) {
 | 
					 | 
				
			||||||
                    uuids.add(UUID.fromString(pixelBlocksResult.getString("uuid")));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } catch (SQLException e) {
 | 
					 | 
				
			||||||
                System.err.println(e.getMessage());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(!uuids.contains(pixelBlock.blockUUID)) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                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());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    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());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    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());
 | 
					 | 
				
			||||||
                    } 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());
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    prep.setString(11, pixelBlock.facingDirection.toString());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    prep.executeUpdate();
 | 
					 | 
				
			||||||
                    prep.close();
 | 
					 | 
				
			||||||
                } catch (SQLException e) {
 | 
					 | 
				
			||||||
                    System.err.println(e.getMessage());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                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());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    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());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    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());
 | 
					 | 
				
			||||||
                    } 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());
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    prep.setString(10, pixelBlock.blockUUID.toString());
 | 
					 | 
				
			||||||
                    prep.setString(11, pixelBlock.facingDirection.toString());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    prep.executeUpdate();
 | 
					 | 
				
			||||||
                    prep.close();
 | 
					 | 
				
			||||||
                } catch (SQLException e) {
 | 
					 | 
				
			||||||
                    System.err.println(e.getMessage());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void loadPixelBlocks() {
 | 
					 | 
				
			||||||
        List<Entity> 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());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        String sql = "CREATE TABLE IF NOT EXISTS pixelblocks (" +
 | 
					 | 
				
			||||||
                            "uuid CHAR(36) PRIMARY KEY, " +
 | 
					                            "uuid CHAR(36) PRIMARY KEY, " +
 | 
				
			||||||
                            "owner CHAR(36), " +
 | 
					                            "owner CHAR(36), " +
 | 
				
			||||||
                            "locationWorldName CHAR(36), " +
 | 
					                            "locationWorldName CHAR(36), " +
 | 
				
			||||||
@@ -156,51 +37,156 @@ public class PixelBlockDatabase {
 | 
				
			|||||||
                            "entryLocationY DOUBLE, " +
 | 
					                            "entryLocationY DOUBLE, " +
 | 
				
			||||||
                            "entryLocationZ DOUBLE, " +
 | 
					                            "entryLocationZ DOUBLE, " +
 | 
				
			||||||
                            "direction CHAR(36)" +
 | 
					                            "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")
 | 
					 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Location newEntryLocation = new Location(
 | 
					            this.deletePixelBlock = this.db.prepareStatement("DELETE FROM pixelblocks WHERE uuid = ?");
 | 
				
			||||||
                        Bukkit.getWorld(pixelBlocksResult.getString("entryLocationWorldName")),
 | 
					            this.getAllPixelBlocks = this.db.prepareStatement("SELECT * FROM pixelblocks");
 | 
				
			||||||
                        pixelBlocksResult.getDouble("entryLocationX"),
 | 
					            this.insertNewPixelBlock = this.db.prepareStatement(
 | 
				
			||||||
                        pixelBlocksResult.getDouble("entryLocationY"),
 | 
					            "INSERT INTO pixelblocks(uuid, owner, " +
 | 
				
			||||||
                        pixelBlocksResult.getDouble("entryLocationZ")
 | 
					                "locationWorldName, locationX, locationY, locationZ, " +
 | 
				
			||||||
 | 
					                "entryLocationWorldName, entryLocationX, entryLocationY, entryLocationZ, direction) " +
 | 
				
			||||||
 | 
					                "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 | 
					            this.updateExistingPixelBlock = this.db.prepareStatement(
 | 
				
			||||||
                if(!newPixelBlockLocation.getChunk().isEntitiesLoaded()) {
 | 
					            "UPDATE pixelblocks " +
 | 
				
			||||||
                    newPixelBlockLocation.getChunk().load(true);
 | 
					                "SET owner=?, locationWorldName=?, locationX=?, locationY=?, locationZ=?," +
 | 
				
			||||||
                    newPixelBlockLocation.getChunk().getEntities();
 | 
					                "entryLocationWorldName=?, entryLocationX=?, entryLocationY=?, entryLocationZ=?, direction=? " +
 | 
				
			||||||
 | 
					                "WHERE uuid=?;"
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        } catch (SQLException | RuntimeException | ClassNotFoundException e) {
 | 
				
			||||||
 | 
					            throw new RuntimeException("Failed to load Database", e);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                entities.stream().filter(entity -> entity
 | 
					    public void close() throws SQLException {
 | 
				
			||||||
                    .getLocation()
 | 
					        deletePixelBlock.close();
 | 
				
			||||||
                    .add(0, PixelBlocksPlugin.configuration.hitboxOffset(), 0)
 | 
					        getAllPixelBlocks.close();
 | 
				
			||||||
                    .toBlockLocation()
 | 
					        insertNewPixelBlock.close();
 | 
				
			||||||
                    .equals(newPixelBlockLocation))
 | 
					        updateExistingPixelBlock.close();
 | 
				
			||||||
                    .forEach(Entity::remove);
 | 
					        db.close();
 | 
				
			||||||
 | 
					 | 
				
			||||||
                PixelBlock newPixelBlock = new PixelBlock(
 | 
					 | 
				
			||||||
                        newPixelBlockLocation,
 | 
					 | 
				
			||||||
                        UUID.fromString(pixelBlocksResult.getString("owner")),
 | 
					 | 
				
			||||||
                        UUID.fromString(pixelBlocksResult.getString("uuid"))
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
                newPixelBlock.lastEntryLocation = newEntryLocation;
 | 
					 | 
				
			||||||
                newPixelBlock.place(newPixelBlockLocation, Direction.valueOf(pixelBlocksResult.getString("direction")));
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void deletePixelBlock(PixelBlock pixelBlock) {
 | 
				
			||||||
 | 
					        Bukkit.getScheduler().runTaskAsynchronously(PixelBlocksPlugin.plugin, () -> {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                this.deletePixelBlock.setString(1, pixelBlock.blockUUID.toString());
 | 
				
			||||||
 | 
					                this.deletePixelBlock.executeUpdate();
 | 
				
			||||||
 | 
					                PixelBlocksPlugin.plugin.getLogger().info("DB: Deleted PixelBlock: " + pixelBlock.blockUUID);
 | 
				
			||||||
            } catch (SQLException e) {
 | 
					            } 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<UUID> storedPixelBlocks = new ArrayList<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                ResultSet pixelBlocksResult = this.getAllPixelBlocks.executeQuery();
 | 
				
			||||||
 | 
					                while (pixelBlocksResult.next()) {
 | 
				
			||||||
 | 
					                    storedPixelBlocks.add(UUID.fromString(pixelBlocksResult.getString("uuid")));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } catch (SQLException e) {
 | 
				
			||||||
 | 
					                throw new RuntimeException("Failed to fetch PixelBlock list", e);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(!storedPixelBlocks.contains(pixelBlock.blockUUID)) {
 | 
				
			||||||
 | 
					                // create new entry if it does not exist
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    this.insertNewPixelBlock.setString(1, pixelBlock.blockUUID.toString());
 | 
				
			||||||
 | 
					                    this.insertNewPixelBlock.setString(2, pixelBlock.ownerUUID.toString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    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) {
 | 
				
			||||||
 | 
					                        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 {
 | 
				
			||||||
 | 
					                        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());
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    this.insertNewPixelBlock.setString(11, pixelBlock.facingDirection.toString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    this.insertNewPixelBlock.executeUpdate();
 | 
				
			||||||
 | 
					                    PixelBlocksPlugin.plugin.getLogger().info("DB: Created PixelBlock: " + pixelBlock.blockUUID);
 | 
				
			||||||
 | 
					                } catch (SQLException e) {
 | 
				
			||||||
 | 
					                    throw new RuntimeException("Failed to save PixelBlock", e);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                // update existing entry
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    this.updateExistingPixelBlock.setString(1, pixelBlock.ownerUUID.toString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    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) {
 | 
				
			||||||
 | 
					                        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 {
 | 
				
			||||||
 | 
					                        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());
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    this.updateExistingPixelBlock.setString(10, pixelBlock.blockUUID.toString());
 | 
				
			||||||
 | 
					                    this.updateExistingPixelBlock.setString(11, pixelBlock.facingDirection.toString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    this.updateExistingPixelBlock.executeUpdate();
 | 
				
			||||||
 | 
					                    PixelBlocksPlugin.plugin.getLogger().info("DB: Updated PixelBlock: " + pixelBlock.blockUUID);
 | 
				
			||||||
 | 
					                } catch (SQLException e) {
 | 
				
			||||||
 | 
					                    throw new RuntimeException("Failed updating PixelBlock", e);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void loadPixelBlocks() {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            ResultSet allPixelBlocks = this.getAllPixelBlocks.executeQuery();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            while (allPixelBlocks.next()) {
 | 
				
			||||||
 | 
					                Location blockLocation = new Location(
 | 
				
			||||||
 | 
					                    Bukkit.getWorld(allPixelBlocks.getString("locationWorldName")),
 | 
				
			||||||
 | 
					                    allPixelBlocks.getDouble("locationX"),
 | 
				
			||||||
 | 
					                    allPixelBlocks.getDouble("locationY"),
 | 
				
			||||||
 | 
					                    allPixelBlocks.getDouble("locationZ")
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Location entryLocation = new Location(
 | 
				
			||||||
 | 
					                    Bukkit.getWorld(allPixelBlocks.getString("entryLocationWorldName")),
 | 
				
			||||||
 | 
					                    allPixelBlocks.getDouble("entryLocationX"),
 | 
				
			||||||
 | 
					                    allPixelBlocks.getDouble("entryLocationY"),
 | 
				
			||||||
 | 
					                    allPixelBlocks.getDouble("entryLocationZ")
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                PixelBlock block = new PixelBlock(
 | 
				
			||||||
 | 
					                    blockLocation,
 | 
				
			||||||
 | 
					                    UUID.fromString(allPixelBlocks.getString("owner")),
 | 
				
			||||||
 | 
					                    UUID.fromString(allPixelBlocks.getString("uuid")),
 | 
				
			||||||
 | 
					                    Direction.valueOf(allPixelBlocks.getString("direction"))
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                block.setLastEntryLocation(entryLocation);
 | 
				
			||||||
 | 
					                PixelBlocksPlugin.plugin.getLogger().info("DB: Loaded PixelBlock: " + block.blockUUID);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (SQLException e) {
 | 
				
			||||||
 | 
					            throw new RuntimeException("Failed loading PixelBlocks", e);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ package eu.mhsl.minecraft.pixelblocks;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
 | 
					import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
 | 
				
			||||||
import net.kyori.adventure.text.Component;
 | 
					import net.kyori.adventure.text.Component;
 | 
				
			||||||
 | 
					import net.kyori.adventure.text.format.NamedTextColor;
 | 
				
			||||||
import org.bukkit.Bukkit;
 | 
					import org.bukkit.Bukkit;
 | 
				
			||||||
import org.bukkit.Material;
 | 
					import org.bukkit.Material;
 | 
				
			||||||
import org.bukkit.NamespacedKey;
 | 
					import org.bukkit.NamespacedKey;
 | 
				
			||||||
@@ -11,16 +12,28 @@ import org.bukkit.inventory.ShapedRecipe;
 | 
				
			|||||||
import org.bukkit.inventory.meta.ItemMeta;
 | 
					import org.bukkit.inventory.meta.ItemMeta;
 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Optional;
 | 
					import java.util.Optional;
 | 
				
			||||||
 | 
					import java.util.UUID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class PixelBlockItem {
 | 
					public class PixelBlockItem {
 | 
				
			||||||
 | 
					    public static UUID unusedBlockID = UUID.fromString("98fdf0ae-c3ab-4ef7-ae25-efd518d600de");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static @NotNull ItemStack getBlockAsItem(@NotNull PixelBlock block) {
 | 
					    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());
 | 
					        String ownerName = Optional.ofNullable(Bukkit.getOfflinePlayer(block.ownerUUID).getName()).orElseGet(() -> block.ownerUUID.toString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ItemMeta meta = itemStack.getItemMeta();
 | 
					        ItemMeta meta = itemStack.getItemMeta();
 | 
				
			||||||
        meta.itemName(Component.text(block.blockUUID.toString()));
 | 
					        meta.itemName(Component.text(block.blockUUID.toString()));
 | 
				
			||||||
        meta.displayName(Component.text("Pixelblock von " + ownerName));
 | 
					        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);
 | 
					        meta.setEnchantmentGlintOverride(true);
 | 
				
			||||||
        itemStack.setItemMeta(meta);
 | 
					        itemStack.setItemMeta(meta);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -31,8 +44,12 @@ public class PixelBlockItem {
 | 
				
			|||||||
        ItemStack item = ItemStack.of(Material.GRAY_STAINED_GLASS);
 | 
					        ItemStack item = ItemStack.of(Material.GRAY_STAINED_GLASS);
 | 
				
			||||||
        ItemMeta meta = item.getItemMeta();
 | 
					        ItemMeta meta = item.getItemMeta();
 | 
				
			||||||
        meta.displayName(Component.text("Leerer Pixelblock"));
 | 
					        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.setEnchantmentGlintOverride(true);
 | 
				
			||||||
        meta.itemName(Component.text("Pixelblock"));
 | 
					        meta.itemName(Component.text(unusedBlockID.toString()));
 | 
				
			||||||
        item.setItemMeta(meta);
 | 
					        item.setItemMeta(meta);
 | 
				
			||||||
        return item;
 | 
					        return item;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,8 @@ import org.bukkit.configuration.file.FileConfiguration;
 | 
				
			|||||||
import org.bukkit.event.Listener;
 | 
					import org.bukkit.event.Listener;
 | 
				
			||||||
import org.bukkit.plugin.java.JavaPlugin;
 | 
					import org.bukkit.plugin.java.JavaPlugin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.File;
 | 
				
			||||||
 | 
					import java.sql.SQLException;
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Objects;
 | 
					import java.util.Objects;
 | 
				
			||||||
@@ -18,7 +20,7 @@ public final class PixelBlocksPlugin extends JavaPlugin {
 | 
				
			|||||||
    public static PixelBlockConfiguration configuration;
 | 
					    public static PixelBlockConfiguration configuration;
 | 
				
			||||||
    public static PixelBlockDatabase database;
 | 
					    public static PixelBlockDatabase database;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static List<PixelBlock> placedPixelBlocks = new ArrayList<>();
 | 
					    public static List<PixelBlock> pixelBlocks = new ArrayList<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void onLoad() {
 | 
					    public void onLoad() {
 | 
				
			||||||
@@ -31,14 +33,13 @@ public final class PixelBlocksPlugin extends JavaPlugin {
 | 
				
			|||||||
        PixelBlocksPlugin.configuration = new PixelBlockConfiguration(
 | 
					        PixelBlocksPlugin.configuration = new PixelBlockConfiguration(
 | 
				
			||||||
                config.getInt(PixelBlockConfiguration.Keys.PixelsPerBlock.getKey()),
 | 
					                config.getInt(PixelBlockConfiguration.Keys.PixelsPerBlock.getKey()),
 | 
				
			||||||
                config.getBoolean(PixelBlockConfiguration.Keys.LiveUpdate.getKey()),
 | 
					                config.getBoolean(PixelBlockConfiguration.Keys.LiveUpdate.getKey()),
 | 
				
			||||||
                config.getInt(PixelBlockConfiguration.Keys.WorldGrassBorderWidth.getKey()),
 | 
					 | 
				
			||||||
                config.getDouble(PixelBlockConfiguration.Keys.HitboxOffset.getKey()),
 | 
					                config.getDouble(PixelBlockConfiguration.Keys.HitboxOffset.getKey()),
 | 
				
			||||||
                config.getBoolean(PixelBlockConfiguration.Keys.DeleteOnBreak.getKey()),
 | 
					 | 
				
			||||||
                config.getBoolean(PixelBlockConfiguration.Keys.OnlyBreakableByOwners.getKey()),
 | 
					                config.getBoolean(PixelBlockConfiguration.Keys.OnlyBreakableByOwners.getKey()),
 | 
				
			||||||
                config.getBoolean(PixelBlockConfiguration.Keys.OnlyEditableByOwners.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
 | 
					    @Override
 | 
				
			||||||
@@ -46,14 +47,16 @@ public final class PixelBlocksPlugin extends JavaPlugin {
 | 
				
			|||||||
        database.loadPixelBlocks();
 | 
					        database.loadPixelBlocks();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Listener[] listeners = {
 | 
					        Listener[] listeners = {
 | 
				
			||||||
                new PlayerInteractListener(),
 | 
					                new EnterPixelBlockListener(),
 | 
				
			||||||
                new PlayerMoveListener(),
 | 
					                new FallOutOfPixelBlockListener(),
 | 
				
			||||||
//                new BlockBreakListener(),
 | 
					                new BreakPixelListener(),
 | 
				
			||||||
                new BlockPlaceListener(),
 | 
					                new PlacePixelBlockListener(),
 | 
				
			||||||
                new InventoryListener(),
 | 
					                new PixelWorldInventoryListener(),
 | 
				
			||||||
                new PlayerChangeWorldListener(),
 | 
					                new PixelWorldExitListener(),
 | 
				
			||||||
                new CraftItemListener(),
 | 
					                new CraftPixelBlockListener(),
 | 
				
			||||||
                new InPixelWorldCancelListener()
 | 
					                new PixelWorldBehaviourListener(),
 | 
				
			||||||
 | 
					                new BreakPixelBlockListener(),
 | 
				
			||||||
 | 
					                new PlacePixelListener()
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (Listener listener : listeners) {
 | 
					        for (Listener listener : listeners) {
 | 
				
			||||||
@@ -65,4 +68,13 @@ public final class PixelBlocksPlugin extends JavaPlugin {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        Bukkit.addRecipe(PixelBlockItem.getRecipe());
 | 
					        Bukkit.addRecipe(PixelBlockItem.getRecipe());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void onDisable() {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            database.close();
 | 
				
			||||||
 | 
					        } catch (SQLException e) {
 | 
				
			||||||
 | 
					            throw new RuntimeException("Failed disabling", e);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,8 +1,8 @@
 | 
				
			|||||||
package eu.mhsl.minecraft.pixelblocks.commands;
 | 
					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.utils.Direction;
 | 
				
			||||||
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
 | 
					import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
 | 
				
			||||||
import org.bukkit.Bukkit;
 | 
					 | 
				
			||||||
import org.bukkit.Location;
 | 
					import org.bukkit.Location;
 | 
				
			||||||
import org.bukkit.World;
 | 
					import org.bukkit.World;
 | 
				
			||||||
import org.bukkit.command.Command;
 | 
					import org.bukkit.command.Command;
 | 
				
			||||||
@@ -11,7 +11,6 @@ import org.bukkit.command.CommandSender;
 | 
				
			|||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Arrays;
 | 
					 | 
				
			||||||
import java.util.UUID;
 | 
					import java.util.UUID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class CreatePixelBlockCommand implements CommandExecutor {
 | 
					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) {
 | 
					    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
 | 
				
			||||||
        if(sender instanceof Player p) {
 | 
					        if(sender instanceof Player p) {
 | 
				
			||||||
            World playerWorld = p.getWorld();
 | 
					            World playerWorld = p.getWorld();
 | 
				
			||||||
            World[] standardWorlds = {Bukkit.getWorlds().get(0), Bukkit.getWorlds().get(1)};
 | 
					            if(PixelBlockWorld.getPixelBlockWorlds().contains(playerWorld)) {
 | 
				
			||||||
 | 
					                p.sendMessage("Pixelblöcke können nicht innerhalb anderen Pixelblöcken erstellt werden.");
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(Arrays.stream(standardWorlds).toList().contains(playerWorld)) {
 | 
					 | 
				
			||||||
            Location playerLocation = p.getLocation();
 | 
					            Location playerLocation = p.getLocation();
 | 
				
			||||||
                PixelBlock pixelBlock = new PixelBlock(playerLocation, p.getUniqueId(), UUID.randomUUID());
 | 
					            PixelBlock block = new PixelBlock(
 | 
				
			||||||
                pixelBlock.place(playerLocation, Direction.south);
 | 
					                playerLocation,
 | 
				
			||||||
            } else {
 | 
					                p.getUniqueId(),
 | 
				
			||||||
                p.sendMessage("Du kannst nur in der Overworld oder im Nether Pixelblocks erstellen!");
 | 
					                UUID.randomUUID(),
 | 
				
			||||||
 | 
					                Direction.south
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            block.place(playerLocation, Direction.south);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					        return true;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        return(true);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,7 @@
 | 
				
			|||||||
package eu.mhsl.minecraft.pixelblocks.commands;
 | 
					package eu.mhsl.minecraft.pixelblocks.commands;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin;
 | 
					 | 
				
			||||||
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
 | 
					import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
 | 
				
			||||||
import org.bukkit.Bukkit;
 | 
					import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlockWorld;
 | 
				
			||||||
import org.bukkit.Location;
 | 
					 | 
				
			||||||
import org.bukkit.World;
 | 
					import org.bukkit.World;
 | 
				
			||||||
import org.bukkit.command.Command;
 | 
					import org.bukkit.command.Command;
 | 
				
			||||||
import org.bukkit.command.CommandExecutor;
 | 
					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) {
 | 
					    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
 | 
				
			||||||
        if(sender instanceof Player p) {
 | 
					        if(sender instanceof Player p) {
 | 
				
			||||||
            World playerWorld = p.getWorld();
 | 
					            World playerWorld = p.getWorld();
 | 
				
			||||||
            World[] standardWorlds = {Bukkit.getWorlds().get(0), Bukkit.getWorlds().get(1), Bukkit.getWorlds().get(2)};
 | 
					            if(PixelBlockWorld.getOtherWorlds().contains(playerWorld)) {
 | 
				
			||||||
 | 
					                p.sendMessage("Du kannst nur Pixelblöcke verlassen.");
 | 
				
			||||||
            if(!Arrays.stream(standardWorlds).toList().contains(playerWorld)) {
 | 
					                return true;
 | 
				
			||||||
 | 
					 | 
				
			||||||
                List<PixelBlock> 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!");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return(true);
 | 
					            PixelBlock currentPixelBlock = PixelBlock.getPixelBlockFromBlockWorld(playerWorld);
 | 
				
			||||||
 | 
					            Objects.requireNonNull(currentPixelBlock);
 | 
				
			||||||
 | 
					            p.teleport(currentPixelBlock.lastEntryLocation);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
					 | 
				
			||||||
//        }
 | 
					 | 
				
			||||||
//    }
 | 
					 | 
				
			||||||
//}
 | 
					 | 
				
			||||||
@@ -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);
 | 
					 | 
				
			||||||
//            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -3,29 +3,14 @@ package eu.mhsl.minecraft.pixelblocks.listeners;
 | 
				
			|||||||
import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin;
 | 
					import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin;
 | 
				
			||||||
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
 | 
					import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
 | 
				
			||||||
import io.papermc.paper.event.player.PrePlayerAttackEntityEvent;
 | 
					import io.papermc.paper.event.player.PrePlayerAttackEntityEvent;
 | 
				
			||||||
import org.bukkit.*;
 | 
					import org.bukkit.Location;
 | 
				
			||||||
import org.bukkit.entity.Interaction;
 | 
					import org.bukkit.entity.Interaction;
 | 
				
			||||||
import org.bukkit.event.EventHandler;
 | 
					import org.bukkit.event.EventHandler;
 | 
				
			||||||
import org.bukkit.event.Listener;
 | 
					import org.bukkit.event.Listener;
 | 
				
			||||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class PlayerInteractListener implements Listener {
 | 
					public class BreakPixelBlockListener implements Listener {
 | 
				
			||||||
    @EventHandler
 | 
					    @EventHandler
 | 
				
			||||||
    static void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
 | 
					    static void destroyPixelBlock(PrePlayerAttackEntityEvent 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) {
 | 
					 | 
				
			||||||
        if(event.getAttacked() instanceof Interaction) {
 | 
					        if(event.getAttacked() instanceof Interaction) {
 | 
				
			||||||
            Location blockLocation = event.getAttacked().getLocation().add(0, PixelBlocksPlugin.configuration.hitboxOffset(), 0).toBlockLocation();
 | 
					            Location blockLocation = event.getAttacked().getLocation().add(0, PixelBlocksPlugin.configuration.hitboxOffset(), 0).toBlockLocation();
 | 
				
			||||||
            blockLocation.setYaw(0);
 | 
					            blockLocation.setYaw(0);
 | 
				
			||||||
@@ -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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -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);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -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());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -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());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -9,7 +9,7 @@ import org.bukkit.event.entity.EntityExplodeEvent;
 | 
				
			|||||||
import org.bukkit.event.player.PlayerDropItemEvent;
 | 
					import org.bukkit.event.player.PlayerDropItemEvent;
 | 
				
			||||||
import org.bukkit.event.player.PlayerPortalEvent;
 | 
					import org.bukkit.event.player.PlayerPortalEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class InPixelWorldCancelListener implements Listener {
 | 
					public class PixelWorldBehaviourListener implements Listener {
 | 
				
			||||||
    @EventHandler
 | 
					    @EventHandler
 | 
				
			||||||
    static void onBlockExplode(BlockExplodeEvent event) {
 | 
					    static void onBlockExplode(BlockExplodeEvent event) {
 | 
				
			||||||
        CommonEventHandlers.cancelIfInPixelWorld(event, event.getBlock().getWorld());
 | 
					        CommonEventHandlers.cancelIfInPixelWorld(event, event.getBlock().getWorld());
 | 
				
			||||||
@@ -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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -6,7 +6,7 @@ import org.bukkit.event.inventory.*;
 | 
				
			|||||||
import org.bukkit.inventory.CraftingInventory;
 | 
					import org.bukkit.inventory.CraftingInventory;
 | 
				
			||||||
import org.bukkit.inventory.PlayerInventory;
 | 
					import org.bukkit.inventory.PlayerInventory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class InventoryListener implements Listener {
 | 
					public class PixelWorldInventoryListener implements Listener {
 | 
				
			||||||
    @EventHandler
 | 
					    @EventHandler
 | 
				
			||||||
    static void onInventoryOpen(InventoryOpenEvent event) {
 | 
					    static void onInventoryOpen(InventoryOpenEvent event) {
 | 
				
			||||||
        if(CommonEventHandlers.isInPixelWorld(event.getPlayer().getWorld())) {
 | 
					        if(CommonEventHandlers.isInPixelWorld(event.getPlayer().getWorld())) {
 | 
				
			||||||
@@ -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()));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -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();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -38,7 +38,7 @@ public class PixelBlock {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static @Nullable PixelBlock getPixelBlockFromBlockWorld(World world) {
 | 
					    public static @Nullable PixelBlock getPixelBlockFromBlockWorld(World world) {
 | 
				
			||||||
        return PixelBlocksPlugin.placedPixelBlocks.stream()
 | 
					        return PixelBlocksPlugin.pixelBlocks.stream()
 | 
				
			||||||
                .filter(block -> block.blockUUID.equals(getUUIDFromWorld(world)))
 | 
					                .filter(block -> block.blockUUID.equals(getUUIDFromWorld(world)))
 | 
				
			||||||
                .findFirst()
 | 
					                .findFirst()
 | 
				
			||||||
                .orElse(null);
 | 
					                .orElse(null);
 | 
				
			||||||
@@ -57,13 +57,15 @@ public class PixelBlock {
 | 
				
			|||||||
        searchLocation.setPitch(0);
 | 
					        searchLocation.setPitch(0);
 | 
				
			||||||
        searchLocation.setYaw(0);
 | 
					        searchLocation.setYaw(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return PixelBlocksPlugin.placedPixelBlocks.stream()
 | 
					        return PixelBlocksPlugin.pixelBlocks.stream()
 | 
				
			||||||
                .filter(block -> block.pixelBlockLocation.equals(searchLocation))
 | 
					                .filter(block -> block.pixelBlockLocation.equals(searchLocation))
 | 
				
			||||||
                .findFirst()
 | 
					                .findFirst()
 | 
				
			||||||
                .orElse(null);
 | 
					                .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.ownerUUID = ownerUUID;
 | 
				
			||||||
        this.blockUUID = blockUUID;
 | 
					        this.blockUUID = blockUUID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -71,7 +73,7 @@ public class PixelBlock {
 | 
				
			|||||||
        this.pixelBlockLocation.setYaw(0);
 | 
					        this.pixelBlockLocation.setYaw(0);
 | 
				
			||||||
        this.pixelBlockLocation.setPitch(0);
 | 
					        this.pixelBlockLocation.setPitch(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.facingDirection = Direction.south; // TODO ??
 | 
					        this.facingDirection = direction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.pixelWorld = new PixelBlockWorld(this);
 | 
					        this.pixelWorld = new PixelBlockWorld(this);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -89,6 +91,10 @@ public class PixelBlock {
 | 
				
			|||||||
        player.teleport(this.pixelWorld.getSpawnLocation());
 | 
					        player.teleport(this.pixelWorld.getSpawnLocation());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void setLastEntryLocation(Location lastEntryLocation) {
 | 
				
			||||||
 | 
					        this.lastEntryLocation = lastEntryLocation;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void spawnInteraction(boolean fullBlock) {
 | 
					    public void spawnInteraction(boolean fullBlock) {
 | 
				
			||||||
        if(fullBlock) {
 | 
					        if(fullBlock) {
 | 
				
			||||||
            hitbox = (Interaction) pixelBlockLocation.getWorld().spawnEntity(
 | 
					            hitbox = (Interaction) pixelBlockLocation.getWorld().spawnEntity(
 | 
				
			||||||
@@ -145,7 +151,7 @@ public class PixelBlock {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void update() {
 | 
					    public void updateEntities() {
 | 
				
			||||||
        Bukkit.getScheduler().runTask(PixelBlocksPlugin.plugin, () -> {
 | 
					        Bukkit.getScheduler().runTask(PixelBlocksPlugin.plugin, () -> {
 | 
				
			||||||
            this.clearEntities();
 | 
					            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();
 | 
					        Location newLocation = placeLocation.toBlockLocation();
 | 
				
			||||||
        newLocation.setPitch(0);
 | 
					        newLocation.setPitch(0);
 | 
				
			||||||
        newLocation.setYaw(0);
 | 
					        newLocation.setYaw(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(PixelBlock.getPixelBlockFromPlacedLocation(newLocation) == null || PixelBlock.getPixelBlockFromPlacedLocation(newLocation) == this) {
 | 
					        @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.pixelBlockLocation = newLocation;
 | 
				
			||||||
        this.facingDirection = direction;
 | 
					        this.facingDirection = direction;
 | 
				
			||||||
            update();
 | 
					        updateEntities();
 | 
				
			||||||
        PixelBlocksPlugin.database.savePixelBlock(this);
 | 
					        PixelBlocksPlugin.database.savePixelBlock(this);
 | 
				
			||||||
            PixelBlocksPlugin.placedPixelBlocks.add(this);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void destroy(Player destroyedBy) {
 | 
					    public void destroy(Player destroyedBy) {
 | 
				
			||||||
@@ -218,15 +222,16 @@ public class PixelBlock {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.pixelWorld.getPlayersInWorld().forEach(p -> {
 | 
					        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);
 | 
					            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();
 | 
					        this.clearEntities();
 | 
				
			||||||
        PixelBlocksPlugin.database.removePixelBlock(this);
 | 
					        PixelBlocksPlugin.database.deletePixelBlock(this);
 | 
				
			||||||
        PixelBlocksPlugin.placedPixelBlocks.remove(this);
 | 
					 | 
				
			||||||
        this.pixelBlockLocation.getWorld().playSound(this.pixelBlockLocation, Sound.BLOCK_COPPER_BULB_BREAK, 1.0F, 30);
 | 
					        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));
 | 
					        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;
 | 
					        return pixelWorld;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public int getPixelsPerBlock() {
 | 
				
			||||||
 | 
					        return pixelsPerBlock;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,15 +1,17 @@
 | 
				
			|||||||
package eu.mhsl.minecraft.pixelblocks.pixelblock;
 | 
					package eu.mhsl.minecraft.pixelblocks.pixelblock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin;
 | 
					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.*;
 | 
				
			||||||
import org.bukkit.entity.Entity;
 | 
					import org.bukkit.entity.Entity;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
 | 
					import org.bukkit.generator.ChunkGenerator;
 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.File;
 | 
					import java.io.File;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Objects;
 | 
					import java.util.Objects;
 | 
				
			||||||
 | 
					import java.util.Random;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import static eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin.plugin;
 | 
					import static eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin.plugin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -17,7 +19,7 @@ public class PixelBlockWorld {
 | 
				
			|||||||
    private final PixelBlock parentPixelBlock;
 | 
					    private final PixelBlock parentPixelBlock;
 | 
				
			||||||
    private final World world;
 | 
					    private final World world;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int worldGrassBorderWidth = PixelBlocksPlugin.configuration.worldGrassBorderWidth();
 | 
					    int worldGrassBorderWidth = 10;
 | 
				
			||||||
    int pixelsPerBlock = PixelBlocksPlugin.configuration.pixelsPerBlock();
 | 
					    int pixelsPerBlock = PixelBlocksPlugin.configuration.pixelsPerBlock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static boolean isPixelWorld(@NotNull World world) {
 | 
					    public static boolean isPixelWorld(@NotNull World world) {
 | 
				
			||||||
@@ -38,8 +40,16 @@ public class PixelBlockWorld {
 | 
				
			|||||||
        this.setBuildingPlatform();
 | 
					        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() {
 | 
					    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() {
 | 
					    public @NotNull Location getSpawnLocation() {
 | 
				
			||||||
@@ -47,7 +57,7 @@ public class PixelBlockWorld {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public @NotNull Location getPortalLocation() {
 | 
					    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<Player> getPlayersInWorld() {
 | 
					    public @NotNull List<Player> getPlayersInWorld() {
 | 
				
			||||||
@@ -62,11 +72,27 @@ public class PixelBlockWorld {
 | 
				
			|||||||
        return new Location(this.world, 0, -60, 0);
 | 
					        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() {
 | 
					    private World loadOrCreatePixelWorld() {
 | 
				
			||||||
        final WorldCreator worldCreator = new WorldCreator(getWorldPathName());
 | 
					        final WorldCreator worldCreator = new WorldCreator(getWorldPathName());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        worldCreator.type(WorldType.FLAT);
 | 
					        worldCreator.type(WorldType.FLAT);
 | 
				
			||||||
        worldCreator.generator(new EmptyChunkGenerator());
 | 
					        worldCreator.generator(new ChunkGenerator() {});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        World world = Bukkit.createWorld(worldCreator);
 | 
					        World world = Bukkit.createWorld(worldCreator);
 | 
				
			||||||
        Objects.requireNonNull(world);
 | 
					        Objects.requireNonNull(world);
 | 
				
			||||||
@@ -78,45 +104,71 @@ public class PixelBlockWorld {
 | 
				
			|||||||
        world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false);
 | 
					        world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        WorldBorder worldBorder = world.getWorldBorder();
 | 
					        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;
 | 
					        return world;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void setBuildingPlatform() {
 | 
					    private void setBuildingPlatform() {
 | 
				
			||||||
        Location borderStartLocation = getBuildOrigin().subtract(1, 1, 1);
 | 
					 | 
				
			||||||
        Location grassStartLocation = borderStartLocation.clone().subtract(worldGrassBorderWidth, 0, worldGrassBorderWidth);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Bukkit.getScheduler().runTask(PixelBlocksPlugin.plugin, () -> {
 | 
					        Bukkit.getScheduler().runTask(PixelBlocksPlugin.plugin, () -> {
 | 
				
			||||||
            for (int x = 0; x < (pixelsPerBlock+2) + 2 * worldGrassBorderWidth; x++) {
 | 
					            for (int x = 0; x < (pixelsPerBlock+2) + 2 * worldGrassBorderWidth; x++) {
 | 
				
			||||||
                for (int z = 0; z < (pixelsPerBlock+2) + 2 * worldGrassBorderWidth; z++) {
 | 
					                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 x = 0; x < (pixelsPerBlock+2) + 2 * worldGrassBorderWidth; x++) {
 | 
				
			||||||
                for (int z = 0; z < (pixelsPerBlock+2) + 2 * worldGrassBorderWidth; z++) {
 | 
					                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 x = 0; x < (pixelsPerBlock+2); x++) {
 | 
				
			||||||
                for (int z = 0; z < (pixelsPerBlock+2); z++) {
 | 
					                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);
 | 
					                        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);
 | 
					                        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++) {
 | 
					                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++) {
 | 
					                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);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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<Location> 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));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user