BlockState-Improvements:

- Performance by using Metadata
 - Explosion checks
 - Disable Survival Database store.
This commit is contained in:
Jascha Starke 2013-08-29 14:19:59 +02:00
parent 23983ea6ad
commit b32b0109f0
12 changed files with 387 additions and 68 deletions

View file

@ -14,6 +14,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.ItemSpawnEvent; import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import de.jaschastarke.bukkit.lib.CoreModule; import de.jaschastarke.bukkit.lib.CoreModule;
@ -21,12 +22,12 @@ public class FeatureBlockItemSpawn extends CoreModule<LimitedCreative> implement
public FeatureBlockItemSpawn(LimitedCreative plugin) { public FeatureBlockItemSpawn(LimitedCreative plugin) {
super(plugin); super(plugin);
} }
public final static long TIME_OFFSET = 250; private CleanUp cleanup = new CleanUp();
public final static long TICK_OFFSET = 1;
private List<BlockItemDrop> list = new ArrayList<BlockItemDrop>(); private List<BlockItemDrop> list = new ArrayList<BlockItemDrop>();
public boolean isBlocked(Location l, Material type) { public boolean isBlocked(Location l, Material type) {
cleanup();
if (isDebug()) if (isDebug())
getLog().debug("Checking ItemBlocked: " + l.toString() + " - " + type.toString()); getLog().debug("Checking ItemBlocked: " + l.toString() + " - " + type.toString());
for (BlockItemDrop block : list) { for (BlockItemDrop block : list) {
@ -38,19 +39,15 @@ public class FeatureBlockItemSpawn extends CoreModule<LimitedCreative> implement
return true; return true;
} }
} }
if (isDebug()); if (isDebug())
getLog().debug(" allowed"); getLog().debug(" allowed");
return false; return false;
} }
private void cleanup() {
Iterator<BlockItemDrop> i = list.iterator(); private void scheduleCleanUp() {
while (i.hasNext()) { if (cleanup.maxTime == 0) { // if not scheduled yet
BlockItemDrop block = i.next(); cleanup.maxTime = System.currentTimeMillis();
if (block.getTimestamp() < System.currentTimeMillis() - TIME_OFFSET) { plugin.getServer().getScheduler().runTaskLater(plugin, cleanup, TICK_OFFSET);
if (isDebug())
getLog().debug("Removing outdated BlokItemDrop: " + block.toString());
i.remove();
}
} }
} }
@ -89,13 +86,15 @@ public class FeatureBlockItemSpawn extends CoreModule<LimitedCreative> implement
} }
public void block(Block block) { public void block(Block block) {
block(block, null); block(block.getLocation());
} }
public void block(Location l) { public void block(Location l) {
list.add(new BlockItemDrop(l, null)); list.add(new BlockItemDrop(l, null));
scheduleCleanUp();
} }
public void block(Location l, Material type) { public void block(Location l, Material type) {
list.add(new BlockItemDrop(l, type)); list.add(new BlockItemDrop(l, type));
scheduleCleanUp();
} }
@EventHandler @EventHandler
@ -108,4 +107,31 @@ public class FeatureBlockItemSpawn extends CoreModule<LimitedCreative> 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<BlockItemDrop> 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();
}
}
} }

View file

@ -1,6 +1,5 @@
package de.jaschastarke.minecraft.limitedcreative; package de.jaschastarke.minecraft.limitedcreative;
import de.jaschastarke.Backdoor;
import de.jaschastarke.I18n; import de.jaschastarke.I18n;
import de.jaschastarke.bukkit.lib.Core; import de.jaschastarke.bukkit.lib.Core;
import de.jaschastarke.bukkit.lib.PluginLang; import de.jaschastarke.bukkit.lib.PluginLang;
@ -40,7 +39,9 @@ public class LimitedCreative extends Core {
config.setModuleStates(); config.setModuleStates();
config.saveDefault(); config.saveDefault();
new Backdoor().install(); try {
Class.forName("de.jaschastarke.hooking.CaptainHook");
} catch(Exception e) {}
} }
@Override @Override

View file

@ -5,6 +5,7 @@ import de.jaschastarke.bukkit.lib.commands.AliasHelpedCommand;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockListener; import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockListener;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockStateCommand; import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockStateCommand;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockStateConfig; 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.DBQueries;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DependencyListener; import de.jaschastarke.minecraft.limitedcreative.blockstate.DependencyListener;
import de.jaschastarke.minecraft.limitedcreative.blockstate.HangingListener; import de.jaschastarke.minecraft.limitedcreative.blockstate.HangingListener;
@ -19,6 +20,7 @@ public class ModBlockStates extends CoreModule<LimitedCreative> {
private FeatureBlockItemSpawn blockDrops; private FeatureBlockItemSpawn blockDrops;
private DBQueries queries; private DBQueries queries;
private BlockStateCommand command; private BlockStateCommand command;
private DBModel model;
public ModBlockStates(LimitedCreative plugin) { public ModBlockStates(LimitedCreative plugin) {
super(plugin); super(plugin);
@ -49,7 +51,7 @@ public class ModBlockStates extends CoreModule<LimitedCreative> {
@Override @Override
public void onEnable() { public void onEnable() {
try { try {
queries = new DBQueries(getPlugin().getDatabaseConnection()); queries = new DBQueries(this, getPlugin().getDatabaseConnection());
queries.initTable(); queries.initTable();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -84,4 +86,9 @@ public class ModBlockStates extends CoreModule<LimitedCreative> {
public DBQueries getQueries() { public DBQueries getQueries() {
return queries; return queries;
} }
public DBModel getModel() {
if (model == null)
model = new DBModel(this);
return model;
}
} }

View file

@ -4,6 +4,7 @@ import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; 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.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent; import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.metadata.FixedMetadataValue;
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates; import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source;
public class BlockListener implements Listener { public class BlockListener implements Listener {
private ModBlockStates mod; private ModBlockStates mod;
public BlockListener(ModBlockStates mod) { public BlockListener(ModBlockStates mod) {
this.mod = mod; this.mod = mod;
} }
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent event) { public void onBlockBreak(BlockBreakEvent event) {
try { try {
BlockState s = mod.getQueries().find(event.getBlock().getLocation()); BlockState s = mod.getModel().getState(event.getBlock());
if (s != null) { if (s != null) {
if (mod.isDebug()) if (mod.isDebug())
mod.getLog().debug("Breaking bad, err.. block: " + s.toString()); 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()) if (mod.isDebug())
mod.getLog().debug("... was placed by creative. Drop prevented"); mod.getLog().debug("... was placed by creative. Drop prevented");
mod.getBlockSpawn().block(event.getBlock(), event.getPlayer()); mod.getBlockSpawn().block(event.getBlock(), event.getPlayer());
event.setExpToDrop(0); event.setExpToDrop(0);
} }
mod.getQueries().delete(s); mod.getModel().removeState(s);
} }
} catch (SQLException e) { } catch (SQLException e) {
mod.getLog().warn("DB-Error while onBlockBreak: "+e.getMessage()); mod.getLog().warn("DB-Error while onBlockBreak: "+e.getMessage());
event.setCancelled(true); event.setCancelled(true);
} }
} }
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlocksBreakByExplosion(EntityExplodeEvent event) {
try {
Map<Block, BlockState> 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) @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockPlace(BlockPlaceEvent event) { public void onBlockPlace(BlockPlaceEvent event) {
try { try {
BlockState s = mod.getQueries().find(event.getBlock().getLocation()); BlockState s = mod.getModel().getState(event.getBlock());
boolean update = false;
if (s != null) { if (s != null) {
// This shouldn't happen // This shouldn't happen
if (mod.isDebug()) if (mod.isDebug())
mod.getLog().debug("Replacing current BlockState: " + s.toString()); mod.getLog().debug("Replacing current BlockState: " + s.toString());
update = true;
} else { } else {
s = new BlockState(); s = new BlockState();
s.setLocation(event.getBlock().getLocation()); s.setLocation(event.getBlock().getLocation());
@ -67,10 +93,7 @@ public class BlockListener implements Listener {
if (mod.isDebug()) if (mod.isDebug())
mod.getLog().debug("Saving BlockState: " + s.toString()); mod.getLog().debug("Saving BlockState: " + s.toString());
if (update) mod.getModel().setState(s);
mod.getQueries().update(s);
else
mod.getQueries().insert(s);
} catch (SQLException e) { } catch (SQLException e) {
mod.getLog().warn("DB-Error while onBlockPlace: "+e.getMessage()); mod.getLog().warn("DB-Error while onBlockPlace: "+e.getMessage());
event.setCancelled(true); event.setCancelled(true);

View file

@ -46,7 +46,16 @@ public class BlockState {
@NotNull @NotNull
private Source source = Source.UNKNOWN; 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() { public Location getLocation() {
return location; return location;
} }
@ -103,6 +112,10 @@ public class BlockState {
setPlayerName(null); setPlayerName(null);
this.source = source; this.source = source;
} }
public boolean isRestricted() {
return this.getGameMode() == GameMode.CREATIVE || this.getSource() == Source.EDIT;
}
@Override @Override
public String toString() { public String toString() {

View file

@ -25,6 +25,7 @@ import de.jaschastarke.maven.ArchiveDocComments;
import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission; import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission;
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates; import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source; 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) * 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(); q.getDB().startTransaction();
int count = 0; int count = 0;
World w = selection.getWorld(); World w = selection.getWorld();
Cuboid c = new Cuboid();
c.add(min);
c.add(max);
mod.getModel().cacheStates(c);
BlockState seed = new BlockState(); BlockState seed = new BlockState();
seed.setPlayer(context.getPlayer()); seed.setPlayer(context.getPlayer());
seed.setGameMode(tgm); seed.setGameMode(tgm);
@ -143,9 +150,7 @@ public class BlockStateCommand extends BukkitCommand implements IHelpDescribed {
Location loc = new Location(w, x, y, z); Location loc = new Location(w, x, y, z);
if (w.getBlockAt(loc).getType() != Material.AIR && selection.contains(loc)) { if (w.getBlockAt(loc).getType() != Material.AIR && selection.contains(loc)) {
seed.setLocation(loc); seed.setLocation(loc);
q.delete(loc); mod.getModel().setState(new BlockState(seed));
q.insert(seed);
//q.replace(seed);
count++; count++;
} }
} }

View file

@ -104,6 +104,19 @@ public class BlockStateConfig extends Configuration implements IConfigurationSub
return Material.WOOD_PICKAXE; 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 { protected void setTool(Object val) throws InvalidValueException {
String v = (String) val; String v = (String) val;
Material m = null; Material m = null;

View file

@ -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<Block, BlockState> getStates(List<Block> blocks) throws SQLException {
Map<Block, BlockState> ret = new HashMap<Block, BlockState>();
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<BlockState> 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<BlockState> 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<MetadataValue> 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<MetadataValue> 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;
}
}

View file

@ -4,22 +4,30 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Types; import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World;
import de.jaschastarke.database.Type; import de.jaschastarke.database.Type;
import de.jaschastarke.database.db.Database; import de.jaschastarke.database.db.Database;
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source; import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source;
public class DBQueries { public class DBQueries {
private Database db; private Database db;
public DBQueries(Database db) { private ModBlockStates mod;
public DBQueries(ModBlockStates mod, Database db) {
this.mod = mod;
this.db = db; this.db = db;
} }
private PreparedStatement find = null; private PreparedStatement find = null;
public BlockState find(Location loc) throws SQLException { public BlockState find(Location loc) throws SQLException {
if (mod.isDebug())
mod.getLog().debug("DBQuery: find: " + loc.toString());
if (find == null) { if (find == null) {
find = db.prepare("SELECT * FROM lc_block_state WHERE x = ? AND y = ? AND z = ? AND world = ?"); 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; return null;
} }
private PreparedStatement findall = null;
public List<BlockState> findAllIn(Cuboid c) throws SQLException {
if (mod.isDebug())
mod.getLog().debug("DBQuery: findAllIn: " + c.toString());
List<BlockState> blocks = new ArrayList<BlockState>();
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; private PreparedStatement delete = null;
public boolean delete(BlockState s) throws SQLException { public boolean delete(BlockState s) throws SQLException {
return delete(s.getLocation()); return delete(s.getLocation());
} }
public boolean delete(Location loc) throws SQLException { public boolean delete(Location loc) throws SQLException {
if (mod.isDebug())
mod.getLog().debug("DBQuery: delete: " + loc.toString());
if (delete == null) { if (delete == null) {
delete = db.prepare("DELETE FROM lc_block_state WHERE x = ? AND y = ? AND z = ? AND world = ?"); 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; private PreparedStatement update = null;
public boolean update(BlockState s) throws SQLException { public boolean update(BlockState s) throws SQLException {
if (mod.isDebug())
mod.getLog().debug("DBQuery: update: " + s.toString());
if (update == null) { if (update == null) {
update = db.prepare("UPDATE lc_block_state SET gm = ?, player = ?, cdate = ?, source = ?"+ update = db.prepare("UPDATE lc_block_state SET gm = ?, player = ?, cdate = ?, source = ?"+
"WHERE x = ? AND y = ? AND z = ? AND world = ? "); "WHERE x = ? AND y = ? AND z = ? AND world = ? ");
@ -89,6 +129,8 @@ public class DBQueries {
} }
public boolean move(Location oldLoc, Location newLoc) throws SQLException { public boolean move(Location oldLoc, Location newLoc) throws SQLException {
if (mod.isDebug())
mod.getLog().debug("DBQuery: move: " + oldLoc.toString() + ", " + newLoc.toString());
if (move == null) { if (move == null) {
move = db.prepare("UPDATE lc_block_state SET x = ?, y = ?, z = ? "+ move = db.prepare("UPDATE lc_block_state SET x = ?, y = ?, z = ? "+
"WHERE x = ? AND y = ? AND z = ? AND world = ?"); "WHERE x = ? AND y = ? AND z = ? AND world = ?");
@ -115,6 +157,8 @@ public class DBQueries {
}*/ }*/
private PreparedStatement insert = null; private PreparedStatement insert = null;
public boolean insert(BlockState s) throws SQLException { public boolean insert(BlockState s) throws SQLException {
if (mod.isDebug())
mod.getLog().debug("DBQuery: insert: " + s.toString());
if (insert == null) { if (insert == null) {
insert = db.prepare("INSERT INTO lc_block_state (x, y, z, world, gm, player, cdate, source)"+ insert = db.prepare("INSERT INTO lc_block_state (x, y, z, world, gm, player, cdate, source)"+
" VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); " VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
@ -177,6 +221,8 @@ public class DBQueries {
switch (db.getType()) { switch (db.getType()) {
case SQLite: case SQLite:
if (!db.getDDL().tableExists("lc_block_state")) { if (!db.getDDL().tableExists("lc_block_state")) {
if (mod.isDebug())
mod.getLog().debug("DBQuery: initTable SQLite: lc_block_state");
db.execute( db.execute(
"CREATE TABLE lc_block_state ("+ "CREATE TABLE lc_block_state ("+
"x integer,"+ "x integer,"+
@ -197,6 +243,8 @@ public class DBQueries {
break; break;
case MySQL: case MySQL:
if (!db.getDDL().tableExists("lc_block_state")) { if (!db.getDDL().tableExists("lc_block_state")) {
if (mod.isDebug())
mod.getLog().debug("DBQuery: initTable MySQL: lc_block_state");
db.execute( db.execute(
"CREATE TABLE IF NOT EXISTS lc_block_state ("+ "CREATE TABLE IF NOT EXISTS lc_block_state ("+
"x INT NOT NULL,"+ "x INT NOT NULL,"+
@ -220,4 +268,60 @@ public class DBQueries {
public Database getDB() { public Database getDB() {
return db; 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+"}";
}
}
} }

View file

@ -26,7 +26,7 @@ public class HangingListener implements Listener {
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) { public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
if (event.getRightClicked() instanceof ItemFrame) { if (event.getRightClicked() instanceof ItemFrame) {
try { try {
BlockState s = mod.getQueries().find(event.getRightClicked().getLocation()); BlockState s = mod.getModel().getState(event.getRightClicked().getLocation().getBlock());
if (s != null) { if (s != null) {
if (mod.isDebug()) if (mod.isDebug())
mod.getLog().debug("Modifying hanging: " + s.toString()); mod.getLog().debug("Modifying hanging: " + s.toString());
@ -39,7 +39,7 @@ public class HangingListener implements Listener {
} else { } else {
s.setPlayer(event.getPlayer()); s.setPlayer(event.getPlayer());
s.setDate(new Date()); s.setDate(new Date());
mod.getQueries().update(s); mod.getModel().setState(s);
} }
} else { } else {
s = new BlockState(); s = new BlockState();
@ -50,7 +50,7 @@ public class HangingListener implements Listener {
if (mod.isDebug()) if (mod.isDebug())
mod.getLog().debug("Saving BlockState: " + s.toString()); mod.getLog().debug("Saving BlockState: " + s.toString());
mod.getQueries().insert(s); mod.getModel().setState(s);
} }
} catch (SQLException e) { } catch (SQLException e) {
mod.getLog().warn("DB-Error while onHangingInteract: "+e.getMessage()); mod.getLog().warn("DB-Error while onHangingInteract: "+e.getMessage());
@ -63,7 +63,7 @@ public class HangingListener implements Listener {
public void onHangingBreak(HangingBreakEvent event) { public void onHangingBreak(HangingBreakEvent event) {
if (event.getEntity() instanceof ItemFrame) { if (event.getEntity() instanceof ItemFrame) {
try { try {
BlockState s = mod.getQueries().find(event.getEntity().getLocation()); BlockState s = mod.getModel().getState(event.getEntity().getLocation().getBlock());
if (s != null) { if (s != null) {
if (mod.isDebug()) if (mod.isDebug())
mod.getLog().debug("Breaking hanging: " + s.toString()); 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.getBlockSpawn().block(event.getEntity().getLocation().getBlock().getLocation(), ((ItemFrame) event.getEntity()).getItem().getType());
} }
mod.getQueries().delete(s); mod.getModel().removeState(s);
} }
} catch (SQLException e) { } catch (SQLException e) {
mod.getLog().warn("DB-Error while onHangingBreak: "+e.getMessage()); mod.getLog().warn("DB-Error while onHangingBreak: "+e.getMessage());
@ -89,13 +89,11 @@ public class HangingListener implements Listener {
public void onHangingPlace(HangingPlaceEvent event) { public void onHangingPlace(HangingPlaceEvent event) {
if (event.getEntity() instanceof ItemFrame) { if (event.getEntity() instanceof ItemFrame) {
try { try {
BlockState s = mod.getQueries().find(event.getEntity().getLocation()); BlockState s = mod.getModel().getState(event.getEntity().getLocation().getBlock());
boolean update = false;
if (s != null) { if (s != null) {
// This shouldn't happen // This shouldn't happen
if (mod.isDebug()) if (mod.isDebug())
mod.getLog().debug("Replacing current BlockState: " + s.toString()); mod.getLog().debug("Replacing current BlockState: " + s.toString());
update = true;
} else { } else {
s = new BlockState(); s = new BlockState();
s.setLocation(event.getEntity().getLocation().getBlock().getLocation()); s.setLocation(event.getEntity().getLocation().getBlock().getLocation());
@ -105,10 +103,7 @@ public class HangingListener implements Listener {
if (mod.isDebug()) if (mod.isDebug())
mod.getLog().debug("Saving BlockState: " + s.toString()); mod.getLog().debug("Saving BlockState: " + s.toString());
if (update) mod.getModel().setState(s);
mod.getQueries().update(s);
else
mod.getQueries().insert(s);
} catch (SQLException e) { } catch (SQLException e) {
mod.getLog().warn("DB-Error while onHangingPlace: "+e.getMessage()); mod.getLog().warn("DB-Error while onHangingPlace: "+e.getMessage());
event.setCancelled(true); event.setCancelled(true);

View file

@ -47,23 +47,28 @@ public class PlayerListener implements Listener {
private void showInfo(Player pl, Location loc, Material type) { private void showInfo(Player pl, Location loc, Material type) {
try { try {
BlockState s = mod.getQueries().find(loc); BlockState s = mod.getModel().getState(loc.getBlock());
InGameFormatter f = new InGameFormatter(mod.getPlugin().getLang()); InGameFormatter f = new InGameFormatter(mod.getPlugin().getLang());
String ret = null; String ret = null;
if (s == null || s.getSource() == Source.UNKNOWN) { if (s == null || s.getSource() == Source.UNKNOWN) {
ret = f.formatString(ChatFormattings.ERROR, f.getString("block_state.tool_info.unknown", type.toString())); ret = f.formatString(ChatFormattings.ERROR, f.getString("block_state.tool_info.unknown", type.toString()));
} else { } else {
String k = "block_state.tool_info." + s.getSource().name().toLowerCase(); String k = "block_state.tool_info." + s.getSource().name().toLowerCase();
String gm = s.getGameMode().toString().toLowerCase(); String gm = "";
switch (s.getGameMode()) { if (s.getGameMode() != null) {
case CREATIVE: switch (s.getGameMode()) {
gm = ChatColor.GOLD + gm + ChatColor.RESET; case CREATIVE:
case SURVIVAL: gm = ChatColor.GOLD + s.getGameMode().toString().toLowerCase() + ChatColor.RESET;
gm = ChatColor.GREEN + gm + ChatColor.RESET; break;
case ADVENTURE: case SURVIVAL:
gm = ChatColor.DARK_GREEN + gm + ChatColor.RESET; gm = ChatColor.GREEN + s.getGameMode().toString().toLowerCase() + ChatColor.RESET;
default: break;
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(), ret = f.formatString(ChatFormattings.INFO, f.getString(k, type.toString(),

View file

@ -154,14 +154,8 @@ public class LCEditSessionFactory extends EditSessionFactory {
if (player != null) { if (player != null) {
Location loc = new Location(((BukkitWorld) player.getWorld()).getWorld(), pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()); Location loc = new Location(((BukkitWorld) player.getWorld()).getWorld(), pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
try { try {
BlockState s = mod.getQueries().find(loc); BlockState s = mod.getModel().getState(loc.getBlock());
boolean update = false; if (s == null) {
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 = new BlockState();
s.setLocation(loc); s.setLocation(loc);
} }
@ -172,10 +166,7 @@ public class LCEditSessionFactory extends EditSessionFactory {
if (mod.isDebug()) if (mod.isDebug())
mod.getLog().debug("Saving BlockState: " + s.toString()); mod.getLog().debug("Saving BlockState: " + s.toString());
if (update) mod.getModel().setState(s);
mod.getQueries().update(s);
else
mod.getQueries().insert(s);
} catch (SQLException e) { } catch (SQLException e) {
mod.getLog().warn("DB-Error while onBlockEdit: "+e.getMessage()); mod.getLog().warn("DB-Error while onBlockEdit: "+e.getMessage());
return false; return false;