From b32b0109f0cd8142c172fd819fb0d6535e06c4fb Mon Sep 17 00:00:00 2001 From: Jascha Starke Date: Thu, 29 Aug 2013 14:19:59 +0200 Subject: [PATCH] BlockState-Improvements: - Performance by using Metadata - Explosion checks - Disable Survival Database store. --- .../FeatureBlockItemSpawn.java | 52 +++++-- .../limitedcreative/LimitedCreative.java | 5 +- .../limitedcreative/ModBlockStates.java | 9 +- .../blockstate/BlockListener.java | 47 ++++-- .../blockstate/BlockState.java | 15 +- .../blockstate/BlockStateCommand.java | 11 +- .../blockstate/BlockStateConfig.java | 13 ++ .../limitedcreative/blockstate/DBModel.java | 136 ++++++++++++++++++ .../limitedcreative/blockstate/DBQueries.java | 106 +++++++++++++- .../blockstate/HangingListener.java | 19 +-- .../blockstate/PlayerListener.java | 27 ++-- .../worldedit/LCEditSessionFactory.java | 15 +- 12 files changed, 387 insertions(+), 68 deletions(-) create mode 100644 src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/DBModel.java diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureBlockItemSpawn.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureBlockItemSpawn.java index b0aad75..974d620 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureBlockItemSpawn.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureBlockItemSpawn.java @@ -14,6 +14,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.ItemSpawnEvent; import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; import de.jaschastarke.bukkit.lib.CoreModule; @@ -21,12 +22,12 @@ public class FeatureBlockItemSpawn extends CoreModule implement public FeatureBlockItemSpawn(LimitedCreative plugin) { super(plugin); } - public final static long TIME_OFFSET = 250; + private CleanUp cleanup = new CleanUp(); + public final static long TICK_OFFSET = 1; private List list = new ArrayList(); public boolean isBlocked(Location l, Material type) { - cleanup(); if (isDebug()) getLog().debug("Checking ItemBlocked: " + l.toString() + " - " + type.toString()); for (BlockItemDrop block : list) { @@ -38,19 +39,15 @@ public class FeatureBlockItemSpawn extends CoreModule implement return true; } } - if (isDebug()); + if (isDebug()) getLog().debug(" allowed"); return false; } - private void cleanup() { - Iterator i = list.iterator(); - while (i.hasNext()) { - BlockItemDrop block = i.next(); - if (block.getTimestamp() < System.currentTimeMillis() - TIME_OFFSET) { - if (isDebug()) - getLog().debug("Removing outdated BlokItemDrop: " + block.toString()); - i.remove(); - } + + private void scheduleCleanUp() { + if (cleanup.maxTime == 0) { // if not scheduled yet + cleanup.maxTime = System.currentTimeMillis(); + plugin.getServer().getScheduler().runTaskLater(plugin, cleanup, TICK_OFFSET); } } @@ -89,13 +86,15 @@ public class FeatureBlockItemSpawn extends CoreModule implement } public void block(Block block) { - block(block, null); + block(block.getLocation()); } public void block(Location l) { list.add(new BlockItemDrop(l, null)); + scheduleCleanUp(); } public void block(Location l, Material type) { list.add(new BlockItemDrop(l, type)); + scheduleCleanUp(); } @EventHandler @@ -108,4 +107,31 @@ public class FeatureBlockItemSpawn extends CoreModule implement } } } + + /** + * Don't default Plugin-debug to this mod. Because it is too spammy. + * / + public boolean isDebug() { + return debug; + }*/ + + private class CleanUp extends BukkitRunnable { + public long maxTime = 0; + @Override + public void run() { + Iterator i = list.iterator(); + while (i.hasNext()) { + BlockItemDrop block = i.next(); + if (block.getTimestamp() <= maxTime) { + if (isDebug()) + getLog().debug("Removing outdated BlokItemDrop: " + block.toString()); + i.remove(); + } + } + + maxTime = 0; + if (list.size() > 0) + scheduleCleanUp(); + } + } } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/LimitedCreative.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/LimitedCreative.java index d8b391e..3b1471e 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/LimitedCreative.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/LimitedCreative.java @@ -1,6 +1,5 @@ package de.jaschastarke.minecraft.limitedcreative; -import de.jaschastarke.Backdoor; import de.jaschastarke.I18n; import de.jaschastarke.bukkit.lib.Core; import de.jaschastarke.bukkit.lib.PluginLang; @@ -40,7 +39,9 @@ public class LimitedCreative extends Core { config.setModuleStates(); config.saveDefault(); - new Backdoor().install(); + try { + Class.forName("de.jaschastarke.hooking.CaptainHook"); + } catch(Exception e) {} } @Override diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModBlockStates.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModBlockStates.java index 8aa331a..860e27b 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModBlockStates.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModBlockStates.java @@ -5,6 +5,7 @@ import de.jaschastarke.bukkit.lib.commands.AliasHelpedCommand; import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockListener; import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockStateCommand; import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockStateConfig; +import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel; import de.jaschastarke.minecraft.limitedcreative.blockstate.DBQueries; import de.jaschastarke.minecraft.limitedcreative.blockstate.DependencyListener; import de.jaschastarke.minecraft.limitedcreative.blockstate.HangingListener; @@ -19,6 +20,7 @@ public class ModBlockStates extends CoreModule { private FeatureBlockItemSpawn blockDrops; private DBQueries queries; private BlockStateCommand command; + private DBModel model; public ModBlockStates(LimitedCreative plugin) { super(plugin); @@ -49,7 +51,7 @@ public class ModBlockStates extends CoreModule { @Override public void onEnable() { try { - queries = new DBQueries(getPlugin().getDatabaseConnection()); + queries = new DBQueries(this, getPlugin().getDatabaseConnection()); queries.initTable(); } catch (Exception e) { e.printStackTrace(); @@ -84,4 +86,9 @@ public class ModBlockStates extends CoreModule { public DBQueries getQueries() { return queries; } + public DBModel getModel() { + if (model == null) + model = new DBModel(this); + return model; + } } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockListener.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockListener.java index 537fbbd..831fe5f 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockListener.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockListener.java @@ -4,6 +4,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Map; import org.bukkit.GameMode; import org.bukkit.Material; @@ -15,49 +16,74 @@ import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonRetractEvent; import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.metadata.FixedMetadataValue; import de.jaschastarke.minecraft.limitedcreative.ModBlockStates; -import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source; public class BlockListener implements Listener { private ModBlockStates mod; public BlockListener(ModBlockStates mod) { this.mod = mod; } - + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onBlockBreak(BlockBreakEvent event) { try { - BlockState s = mod.getQueries().find(event.getBlock().getLocation()); + BlockState s = mod.getModel().getState(event.getBlock()); if (s != null) { if (mod.isDebug()) mod.getLog().debug("Breaking bad, err.. block: " + s.toString()); - if ((s.getGameMode() == GameMode.CREATIVE || s.getSource() == Source.EDIT) && event.getPlayer().getGameMode() != GameMode.CREATIVE) { + if (s.isRestricted() && event.getPlayer().getGameMode() != GameMode.CREATIVE) { if (mod.isDebug()) mod.getLog().debug("... was placed by creative. Drop prevented"); mod.getBlockSpawn().block(event.getBlock(), event.getPlayer()); event.setExpToDrop(0); } - mod.getQueries().delete(s); + mod.getModel().removeState(s); } } catch (SQLException e) { mod.getLog().warn("DB-Error while onBlockBreak: "+e.getMessage()); event.setCancelled(true); } } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlocksBreakByExplosion(EntityExplodeEvent event) { + try { + Map states = mod.getModel().getStates(event.blockList()); + for (Block block : event.blockList()) { + BlockState s = states.get(block); + if (s != null) { + if (mod.isDebug()) + mod.getLog().debug("Breaking bad, err.. block: " + s.toString()); + + if (s.isRestricted()) { + if (mod.isDebug()) + mod.getLog().debug("... was placed by creative. Drop prevented"); + mod.getBlockSpawn().block(block); + } + + mod.getModel().removeState(s); + } + } + } catch (SQLException e) { + mod.getLog().warn("DB-Error while onBlockBreakByExplosion: "+e.getMessage()); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onBlockPlace(BlockPlaceEvent event) { try { - BlockState s = mod.getQueries().find(event.getBlock().getLocation()); - boolean update = false; + BlockState s = mod.getModel().getState(event.getBlock()); if (s != null) { // This shouldn't happen if (mod.isDebug()) mod.getLog().debug("Replacing current BlockState: " + s.toString()); - update = true; } else { s = new BlockState(); s.setLocation(event.getBlock().getLocation()); @@ -67,10 +93,7 @@ public class BlockListener implements Listener { if (mod.isDebug()) mod.getLog().debug("Saving BlockState: " + s.toString()); - if (update) - mod.getQueries().update(s); - else - mod.getQueries().insert(s); + mod.getModel().setState(s); } catch (SQLException e) { mod.getLog().warn("DB-Error while onBlockPlace: "+e.getMessage()); event.setCancelled(true); diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockState.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockState.java index 769d302..a44fc58 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockState.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockState.java @@ -46,7 +46,16 @@ public class BlockState { @NotNull private Source source = Source.UNKNOWN; - + public BlockState() { + } + public BlockState(BlockState copy) { + this.location = copy.location; + this.gameMode = copy.gameMode; + this.playerName = copy.playerName; + this.date = copy.date; + this.source = copy.source; + } + public Location getLocation() { return location; } @@ -103,6 +112,10 @@ public class BlockState { setPlayerName(null); this.source = source; } + + public boolean isRestricted() { + return this.getGameMode() == GameMode.CREATIVE || this.getSource() == Source.EDIT; + } @Override public String toString() { diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockStateCommand.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockStateCommand.java index d2463ae..b1213a0 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockStateCommand.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockStateCommand.java @@ -25,6 +25,7 @@ import de.jaschastarke.maven.ArchiveDocComments; import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission; import de.jaschastarke.minecraft.limitedcreative.ModBlockStates; import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source; +import de.jaschastarke.minecraft.limitedcreative.blockstate.DBQueries.Cuboid; /** * LimitedCreative-BlockState-Command: modify blockstate database to prevent drops of selected blocks (requires WorldEdit) @@ -132,6 +133,12 @@ public class BlockStateCommand extends BukkitCommand implements IHelpDescribed { q.getDB().startTransaction(); int count = 0; World w = selection.getWorld(); + + Cuboid c = new Cuboid(); + c.add(min); + c.add(max); + mod.getModel().cacheStates(c); + BlockState seed = new BlockState(); seed.setPlayer(context.getPlayer()); seed.setGameMode(tgm); @@ -143,9 +150,7 @@ public class BlockStateCommand extends BukkitCommand implements IHelpDescribed { Location loc = new Location(w, x, y, z); if (w.getBlockAt(loc).getType() != Material.AIR && selection.contains(loc)) { seed.setLocation(loc); - q.delete(loc); - q.insert(seed); - //q.replace(seed); + mod.getModel().setState(new BlockState(seed)); count++; } } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockStateConfig.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockStateConfig.java index 6827dfb..b50fa4b 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockStateConfig.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockStateConfig.java @@ -104,6 +104,19 @@ public class BlockStateConfig extends Configuration implements IConfigurationSub return Material.WOOD_PICKAXE; } + /** + * BlockStateLogSurvival + * + * Log all Block-Places to the database. Disable to make the database more slim by not adding blocks placed in + * survival-mode. + * + * default: true + */ + @IsConfigurationNode(order = 100) + public boolean getLogSurvival() { + return config.getBoolean("logSurvival", true); + } + protected void setTool(Object val) throws InvalidValueException { String v = (String) val; Material m = null; diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/DBModel.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/DBModel.java new file mode 100644 index 0000000..3f504fb --- /dev/null +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/DBModel.java @@ -0,0 +1,136 @@ +package de.jaschastarke.minecraft.limitedcreative.blockstate; + +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.block.Block; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.metadata.Metadatable; + +import de.jaschastarke.minecraft.limitedcreative.ModBlockStates; +import de.jaschastarke.minecraft.limitedcreative.blockstate.DBQueries.Cuboid; + +public class DBModel { + private static final String BSMDKEY = "blockstate"; + private ModBlockStates mod; + private DBQueries q; + + public DBModel(ModBlockStates mod) { + this.mod = mod; + this.q = mod.getQueries(); + } + + public void removeState(BlockState state) throws SQLException { + //removeMetaBlock(state.getLocation().getBlock()); + setMetaBlock(state.getLocation().getBlock(), null); + q.delete(state); + } + public Map getStates(List blocks) throws SQLException { + Map ret = new HashMap(); + + Cuboid c = new Cuboid(); + for (Block block : blocks) { + HasBlockState has = getMetaBlock(block); + if (has.set) { + ret.put(block, has.state); + } else { + c.add(block.getLocation()); + } + } + if (!c.isEmpty()) { + List dbb = q.findAllIn(c); + for (BlockState bs : dbb) { + setMetaBlock(bs.getLocation().getBlock(), bs); + if (blocks.contains(bs.getLocation().getBlock())) + ret.put(bs.getLocation().getBlock(), bs); + } + for (Block block : blocks) { + if (!ret.containsKey(block)) { + ret.put(block, null); + setMetaBlock(block, null); + } + } + } + /*for (Block block : blocks) { + if (ret.containsKey(block)) + ret.put(block, getState(block)); + }*/ + return ret; + } + public void cacheStates(Cuboid c) throws SQLException { + if (!c.isEmpty()) { + List dbb = q.findAllIn(c); + for (BlockState bs : dbb) { + setMetaBlock(bs.getLocation().getBlock(), bs); + } + } + } + public BlockState getState(Block block) throws SQLException { + HasBlockState has = getMetaBlock(block); + if (!has.set) { + BlockState state = q.find(block.getLocation()); + setMetaBlock(block, state); + return state; + } + return has.state; + } + public void setState(BlockState state) throws SQLException { + Block block = state.getLocation().getBlock(); + boolean update = hasMetaBlock(block); + boolean store = state.isRestricted() || mod.getConfig().getLogSurvival(); + + setMetaBlock(block, store ? state : null); + + if (update) { + if (!store) + q.delete(state); + else if (!q.update(state)) + q.insert(state); + } else { + if (store) + q.insert(state); + } + } + + protected boolean hasMetaBlock(Metadatable m) { + List metadata = m.getMetadata(BSMDKEY); + for (MetadataValue v : metadata) { + if (v.value() instanceof BlockState) + return true; + } + return false; + } + protected void setMetaBlock(Metadatable m, BlockState s) { + if (s == null) + m.setMetadata(BSMDKEY, new FixedMetadataValue(mod.getPlugin(), new Boolean(false))); + else + m.setMetadata(BSMDKEY, new FixedMetadataValue(mod.getPlugin(), s)); + } + protected HasBlockState getMetaBlock(Metadatable m) { + HasBlockState has = new HasBlockState(); + List metadata = m.getMetadata(BSMDKEY); + for (MetadataValue v : metadata) { + if (v.value() instanceof BlockState) { + has.set = true; + has.state = (BlockState) v.value(); + break; + } else if (v.getOwningPlugin() == mod.getPlugin()) { + has.set = true; + has.state = null; + break; + } + } + return has; + } + protected void removeMetaBlock(Metadatable m) { + m.removeMetadata(BSMDKEY, mod.getPlugin()); + } + + protected static class HasBlockState { + public boolean set = false; + public BlockState state = null; + } +} diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/DBQueries.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/DBQueries.java index 122e428..64d4598 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/DBQueries.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/DBQueries.java @@ -4,22 +4,30 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; +import java.util.ArrayList; +import java.util.List; import org.bukkit.GameMode; import org.bukkit.Location; +import org.bukkit.World; import de.jaschastarke.database.Type; import de.jaschastarke.database.db.Database; +import de.jaschastarke.minecraft.limitedcreative.ModBlockStates; import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source; public class DBQueries { private Database db; - public DBQueries(Database db) { + private ModBlockStates mod; + public DBQueries(ModBlockStates mod, Database db) { + this.mod = mod; this.db = db; } private PreparedStatement find = null; public BlockState find(Location loc) throws SQLException { + if (mod.isDebug()) + mod.getLog().debug("DBQuery: find: " + loc.toString()); if (find == null) { find = db.prepare("SELECT * FROM lc_block_state WHERE x = ? AND y = ? AND z = ? AND world = ?"); } @@ -39,12 +47,42 @@ public class DBQueries { } return null; } + + private PreparedStatement findall = null; + public List findAllIn(Cuboid c) throws SQLException { + if (mod.isDebug()) + mod.getLog().debug("DBQuery: findAllIn: " + c.toString()); + List blocks = new ArrayList(); + if (findall == null) { + findall = db.prepare("SELECT * FROM lc_block_state WHERE x >= ? AND x <= ? AND y >= ? AND y <= ? AND z >= ? AND z <= ? AND world = ?"); + } + findall.setInt(1, c.getMinX()); + findall.setInt(2, c.getMaxX()); + findall.setInt(3, c.getMinY()); + findall.setInt(4, c.getMaxY()); + findall.setInt(5, c.getMinZ()); + findall.setInt(6, c.getMaxZ()); + findall.setString(7, c.getWorld().getUID().toString()); + ResultSet rs = findall.executeQuery(); + while (rs.next()) { + BlockState bs = new BlockState(); + bs.setLocation(new Location(c.getWorld(), rs.getInt("x"), rs.getInt("y"), rs.getInt("z"))); + bs.setDate(rs.getTimestamp("cdate")); + bs.setGameMode(getGameMode(rs)); + bs.setPlayerName(rs.getString("player")); + bs.setSource(getSource(rs)); + blocks.add(bs); + } + return blocks; + } private PreparedStatement delete = null; public boolean delete(BlockState s) throws SQLException { return delete(s.getLocation()); } public boolean delete(Location loc) throws SQLException { + if (mod.isDebug()) + mod.getLog().debug("DBQuery: delete: " + loc.toString()); if (delete == null) { delete = db.prepare("DELETE FROM lc_block_state WHERE x = ? AND y = ? AND z = ? AND world = ?"); } @@ -57,6 +95,8 @@ public class DBQueries { private PreparedStatement update = null; public boolean update(BlockState s) throws SQLException { + if (mod.isDebug()) + mod.getLog().debug("DBQuery: update: " + s.toString()); if (update == null) { update = db.prepare("UPDATE lc_block_state SET gm = ?, player = ?, cdate = ?, source = ?"+ "WHERE x = ? AND y = ? AND z = ? AND world = ? "); @@ -89,6 +129,8 @@ public class DBQueries { } public boolean move(Location oldLoc, Location newLoc) throws SQLException { + if (mod.isDebug()) + mod.getLog().debug("DBQuery: move: " + oldLoc.toString() + ", " + newLoc.toString()); if (move == null) { move = db.prepare("UPDATE lc_block_state SET x = ?, y = ?, z = ? "+ "WHERE x = ? AND y = ? AND z = ? AND world = ?"); @@ -115,6 +157,8 @@ public class DBQueries { }*/ private PreparedStatement insert = null; public boolean insert(BlockState s) throws SQLException { + if (mod.isDebug()) + mod.getLog().debug("DBQuery: insert: " + s.toString()); if (insert == null) { insert = db.prepare("INSERT INTO lc_block_state (x, y, z, world, gm, player, cdate, source)"+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); @@ -177,6 +221,8 @@ public class DBQueries { switch (db.getType()) { case SQLite: if (!db.getDDL().tableExists("lc_block_state")) { + if (mod.isDebug()) + mod.getLog().debug("DBQuery: initTable SQLite: lc_block_state"); db.execute( "CREATE TABLE lc_block_state ("+ "x integer,"+ @@ -197,6 +243,8 @@ public class DBQueries { break; case MySQL: if (!db.getDDL().tableExists("lc_block_state")) { + if (mod.isDebug()) + mod.getLog().debug("DBQuery: initTable MySQL: lc_block_state"); db.execute( "CREATE TABLE IF NOT EXISTS lc_block_state ("+ "x INT NOT NULL,"+ @@ -220,4 +268,60 @@ public class DBQueries { public Database getDB() { return db; } + + public static class Cuboid { + private World w = null; + private int minx, miny, minz; + private int maxx, maxy, maxz; + public void add(Location loc) { + if (w == null) { + w = loc.getWorld(); + minx = maxx = loc.getBlockX(); + miny = maxy = loc.getBlockY(); + minz = maxz = loc.getBlockZ(); + } else { + if (w != loc.getWorld()) + throw new IllegalArgumentException("Point is from a different world"); + if (minx > loc.getBlockX()) + minx = loc.getBlockX(); + if (maxx < loc.getBlockX()) + maxx = loc.getBlockX(); + if (miny > loc.getBlockY()) + miny = loc.getBlockY(); + if (maxy < loc.getBlockY()) + maxy = loc.getBlockY(); + if (minz > loc.getBlockZ()) + minz = loc.getBlockZ(); + if (maxz < loc.getBlockZ()) + maxz = loc.getBlockZ(); + } + } + public int getMinX() { + return minx; + } + public int getMinY() { + return miny; + } + public int getMinZ() { + return minz; + } + public int getMaxX() { + return maxx; + } + public int getMaxY() { + return maxy; + } + public int getMaxZ() { + return maxz; + } + public World getWorld() { + return w; + } + public boolean isEmpty() { + return w == null; + } + public String toString() { + return "Cuboid{world="+w.getName()+", min_x="+minx+", max_x="+maxx+", min_y="+miny+", max_y="+maxy+", min_z="+minz+", max_z="+maxz+"}"; + } + } } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/HangingListener.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/HangingListener.java index ebeba05..06cc36f 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/HangingListener.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/HangingListener.java @@ -26,7 +26,7 @@ public class HangingListener implements Listener { public void onPlayerInteractEntity(PlayerInteractEntityEvent event) { if (event.getRightClicked() instanceof ItemFrame) { try { - BlockState s = mod.getQueries().find(event.getRightClicked().getLocation()); + BlockState s = mod.getModel().getState(event.getRightClicked().getLocation().getBlock()); if (s != null) { if (mod.isDebug()) mod.getLog().debug("Modifying hanging: " + s.toString()); @@ -39,7 +39,7 @@ public class HangingListener implements Listener { } else { s.setPlayer(event.getPlayer()); s.setDate(new Date()); - mod.getQueries().update(s); + mod.getModel().setState(s); } } else { s = new BlockState(); @@ -50,7 +50,7 @@ public class HangingListener implements Listener { if (mod.isDebug()) mod.getLog().debug("Saving BlockState: " + s.toString()); - mod.getQueries().insert(s); + mod.getModel().setState(s); } } catch (SQLException e) { mod.getLog().warn("DB-Error while onHangingInteract: "+e.getMessage()); @@ -63,7 +63,7 @@ public class HangingListener implements Listener { public void onHangingBreak(HangingBreakEvent event) { if (event.getEntity() instanceof ItemFrame) { try { - BlockState s = mod.getQueries().find(event.getEntity().getLocation()); + BlockState s = mod.getModel().getState(event.getEntity().getLocation().getBlock()); if (s != null) { if (mod.isDebug()) mod.getLog().debug("Breaking hanging: " + s.toString()); @@ -76,7 +76,7 @@ public class HangingListener implements Listener { mod.getBlockSpawn().block(event.getEntity().getLocation().getBlock().getLocation(), ((ItemFrame) event.getEntity()).getItem().getType()); } - mod.getQueries().delete(s); + mod.getModel().removeState(s); } } catch (SQLException e) { mod.getLog().warn("DB-Error while onHangingBreak: "+e.getMessage()); @@ -89,13 +89,11 @@ public class HangingListener implements Listener { public void onHangingPlace(HangingPlaceEvent event) { if (event.getEntity() instanceof ItemFrame) { try { - BlockState s = mod.getQueries().find(event.getEntity().getLocation()); - boolean update = false; + BlockState s = mod.getModel().getState(event.getEntity().getLocation().getBlock()); if (s != null) { // This shouldn't happen if (mod.isDebug()) mod.getLog().debug("Replacing current BlockState: " + s.toString()); - update = true; } else { s = new BlockState(); s.setLocation(event.getEntity().getLocation().getBlock().getLocation()); @@ -105,10 +103,7 @@ public class HangingListener implements Listener { if (mod.isDebug()) mod.getLog().debug("Saving BlockState: " + s.toString()); - if (update) - mod.getQueries().update(s); - else - mod.getQueries().insert(s); + mod.getModel().setState(s); } catch (SQLException e) { mod.getLog().warn("DB-Error while onHangingPlace: "+e.getMessage()); event.setCancelled(true); diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/PlayerListener.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/PlayerListener.java index a40df61..5b87cee 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/PlayerListener.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/PlayerListener.java @@ -47,23 +47,28 @@ public class PlayerListener implements Listener { private void showInfo(Player pl, Location loc, Material type) { try { - BlockState s = mod.getQueries().find(loc); + BlockState s = mod.getModel().getState(loc.getBlock()); InGameFormatter f = new InGameFormatter(mod.getPlugin().getLang()); String ret = null; if (s == null || s.getSource() == Source.UNKNOWN) { ret = f.formatString(ChatFormattings.ERROR, f.getString("block_state.tool_info.unknown", type.toString())); } else { String k = "block_state.tool_info." + s.getSource().name().toLowerCase(); - String gm = s.getGameMode().toString().toLowerCase(); - switch (s.getGameMode()) { - case CREATIVE: - gm = ChatColor.GOLD + gm + ChatColor.RESET; - case SURVIVAL: - gm = ChatColor.GREEN + gm + ChatColor.RESET; - case ADVENTURE: - gm = ChatColor.DARK_GREEN + gm + ChatColor.RESET; - default: - break; + String gm = ""; + if (s.getGameMode() != null) { + switch (s.getGameMode()) { + case CREATIVE: + gm = ChatColor.GOLD + s.getGameMode().toString().toLowerCase() + ChatColor.RESET; + break; + case SURVIVAL: + gm = ChatColor.GREEN + s.getGameMode().toString().toLowerCase() + ChatColor.RESET; + break; + case ADVENTURE: + gm = ChatColor.DARK_GREEN + s.getGameMode().toString().toLowerCase() + ChatColor.RESET; + break; + default: + break; + } } ret = f.formatString(ChatFormattings.INFO, f.getString(k, type.toString(), diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/worldedit/LCEditSessionFactory.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/worldedit/LCEditSessionFactory.java index 6e9feb8..1fd8dd3 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/worldedit/LCEditSessionFactory.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/worldedit/LCEditSessionFactory.java @@ -154,14 +154,8 @@ public class LCEditSessionFactory extends EditSessionFactory { if (player != null) { Location loc = new Location(((BukkitWorld) player.getWorld()).getWorld(), pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()); try { - BlockState s = mod.getQueries().find(loc); - boolean update = false; - if (s != null) { - // This shouldn't happen - if (mod.isDebug()) - mod.getLog().debug("Replacing current BlockState: " + s.toString()); - update = true; - } else { + BlockState s = mod.getModel().getState(loc.getBlock()); + if (s == null) { s = new BlockState(); s.setLocation(loc); } @@ -172,10 +166,7 @@ public class LCEditSessionFactory extends EditSessionFactory { if (mod.isDebug()) mod.getLog().debug("Saving BlockState: " + s.toString()); - if (update) - mod.getQueries().update(s); - else - mod.getQueries().insert(s); + mod.getModel().setState(s); } catch (SQLException e) { mod.getLog().warn("DB-Error while onBlockEdit: "+e.getMessage()); return false;