wip: further code cleanup

This commit is contained in:
Elias Müller 2024-07-23 22:25:00 +02:00
parent e5e1f39989
commit 93dc9d8a80
25 changed files with 556 additions and 407 deletions

View File

@ -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");

View File

@ -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);
}
} }
} }

View File

@ -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;
} }

View File

@ -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);
}
}
} }

View File

@ -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);
}
}

View File

@ -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);
} }
} }

View File

@ -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;
} }
} }

View File

@ -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);
// }
// }
//}

View File

@ -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);
// }
}
}
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);
}
}
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}
}

View File

@ -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());
}
}

View File

@ -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());

View File

@ -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);
}
}

View File

@ -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())) {

View File

@ -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()));
}
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}
}

View File

@ -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);
}
}
}
}
}
}

View File

@ -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;
}
} }

View File

@ -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);
} }
} }
}); });

View File

@ -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));
}
}
}
}
}