From 6684771a390d9927acb733c6093a757d609de333 Mon Sep 17 00:00:00 2001 From: Jonny D Date: Wed, 21 Mar 2012 01:52:29 +0000 Subject: [PATCH 1/3] added solution for dynamite bug (issue #1) to BlockListener Class, added methods to CitadelDao Class, uploaded config.yml file, uploaded Coordinate class --- plugins/citadel-paper/config.yml | 16 +++ .../untamedears/Citadel/BlockListener.java | 100 ++++++++++++++++++ .../com/untamedears/Citadel/Coordinate.java | 13 +++ .../untamedears/Citadel/dao/CitadelDao.java | 35 ++++++ 4 files changed, 164 insertions(+) create mode 100644 plugins/citadel-paper/config.yml create mode 100644 plugins/citadel-paper/src/com/untamedears/Citadel/Coordinate.java diff --git a/plugins/citadel-paper/config.yml b/plugins/citadel-paper/config.yml new file mode 100644 index 000000000..00c52d36b --- /dev/null +++ b/plugins/citadel-paper/config.yml @@ -0,0 +1,16 @@ +materials: + strengths: + keys: + - 264 + - 265 + - 5 + - 4 + strengths: + - 1000 + - 100 + - 5 + - 10 + requirements: + - 1 + - 2 + - 1 \ No newline at end of file diff --git a/plugins/citadel-paper/src/com/untamedears/Citadel/BlockListener.java b/plugins/citadel-paper/src/com/untamedears/Citadel/BlockListener.java index bc83d8dd0..67fba3bdf 100644 --- a/plugins/citadel-paper/src/com/untamedears/Citadel/BlockListener.java +++ b/plugins/citadel-paper/src/com/untamedears/Citadel/BlockListener.java @@ -3,6 +3,7 @@ package com.untamedears.Citadel; import com.untamedears.Citadel.dao.CitadelDao; import org.bukkit.ChatColor; import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -10,6 +11,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockRedstoneEvent; +import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerQuitEvent; @@ -17,7 +19,11 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.material.Door; import org.bukkit.plugin.java.JavaPlugin; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.HashMap; +import java.util.List; import java.util.logging.Logger; public class BlockListener implements Listener { @@ -94,6 +100,100 @@ public class BlockListener implements Listener { bbe.setCancelled(true); } } + + @EventHandler + public void checkForExplosion(EntityExplodeEvent event){ + + if(event.isCancelled()){ + return; + } + + //Store blocks that are inside explosion's blast radius + List blastRadiusBlocks = event.blockList(); + + //If explosion occurs in mid air it returns 0 so no need to go any + //further since there are no blocks inside the explosions radius + if(blastRadiusBlocks.size() < 1){ + return; + } + + HashMap affectedBlocks = new HashMap(); + + //Initialize min & max X,Y,Z coordinates + int smallestX = blastRadiusBlocks.get(0).getX(); + int largestX = smallestX; + int smallestY = blastRadiusBlocks.get(0).getY(); + int largestY = smallestY; + int smallestZ = blastRadiusBlocks.get(0).getZ(); + int largestZ = smallestZ; + + //World Name + String worldName = blastRadiusBlocks.get(0).getWorld().getName(); + World world = this.myPlugin.getServer().getWorld(worldName); + + //Find min & max X,Y,Z coordinates + for(int i = 0; i < blastRadiusBlocks.size(); i++){ + Block block = blastRadiusBlocks.get(i); + int blockX = block.getX(); + int blockY = block.getY(); + int blockZ = block.getZ(); + + if(blockX < smallestX){ + smallestX = blockX; + } + + if(blockX > largestX){ + largestX = blockX; + } + + if(blockY < smallestY){ + smallestY = blockY; + } + + if(blockY > largestY){ + largestY = blockY; + } + + if(blockZ < smallestZ){ + smallestZ = blockZ; + } + + if(blockZ > largestZ){ + largestZ = blockZ; + } + + //Instantiate Coordinate class passing in parameters + Coordinate coordinate = new Coordinate(world, blockX, blockY, blockZ); + //Put a new entry of type Coordinate as key and type Block as value + affectedBlocks.put(coordinate, block); + } + + //Query database for any reinforced blocks that may be in the blast radius + //Reinforced blocks should have a durability > 0 (aka >= 1) + ResultSet result = dao.selectReinforcements(worldName, smallestX, largestX, smallestY, largestY, smallestZ, largestZ); + + //If there was some found, loop through each one + try { + while(result.next()){ + //Get X,Y,Z coords of reinforced block + int x = result.getInt(1); + int y = result.getInt(2); + int z = result.getInt(3); + + //Pass in x, y, z of reinforced block into affectedBlocks HashMap to instantiate a Block + Block protectedBlock = affectedBlocks.get(new Coordinate(world, x, y, z)); + //Then remove the protectedBlock from explosion list + event.blockList().remove(protectedBlock); + } + } catch (SQLException e) { + System.err.println("Citadel - explosion error"); + } + + //Update reinforcements to set durability of blocks that are within blast radius + //Explosion should decrement durability by 1 + dao.updateReinforcements(worldName, smallestX, largestX, smallestY, largestY, smallestZ, largestZ); + } + @EventHandler public void controlAccess(PlayerInteractEvent pie) { diff --git a/plugins/citadel-paper/src/com/untamedears/Citadel/Coordinate.java b/plugins/citadel-paper/src/com/untamedears/Citadel/Coordinate.java new file mode 100644 index 000000000..11f01a8f3 --- /dev/null +++ b/plugins/citadel-paper/src/com/untamedears/Citadel/Coordinate.java @@ -0,0 +1,13 @@ +package com.untamedears.Citadel; + +import org.bukkit.Location; +import org.bukkit.World; + + public class Coordinate extends Location { + + public Coordinate(World world, double x, double y, double z) { + super(world, x, y, z); + // TODO Auto-generated constructor stub + } + + } diff --git a/plugins/citadel-paper/src/com/untamedears/Citadel/dao/CitadelDao.java b/plugins/citadel-paper/src/com/untamedears/Citadel/dao/CitadelDao.java index c2de2fe85..97aeb7402 100644 --- a/plugins/citadel-paper/src/com/untamedears/Citadel/dao/CitadelDao.java +++ b/plugins/citadel-paper/src/com/untamedears/Citadel/dao/CitadelDao.java @@ -27,6 +27,9 @@ public class CitadelDao { private static final String SELECT_REINFORCEMENT = "SELECT DURABILITY FROM REINFORCEMENTS WHERE x=? AND y=? AND z=? AND world=?;"; private static final String DELETE_REINFORCEMENT = "DELETE FROM REINFORCEMENTS WHERE x=:x AND y=? AND z=? AND world=?;"; + private static final String SELECT_REINFORCEMENTS = "SELECT X, Y, Z FROM REINFORCEMENTS WHERE DURABILITY >= 1 AND x<=? AND x>=? AND y<=? AND y>=? AND z<=? AND z>=? AND world=?"; + private static final String UPDATE_REINFORCEMENTS = "UPDATE REINFORCEMENTS SET DURABILITY = DURABILITY - 1 WHERE DURABILITY >= 1 AND x<=? AND x>=? AND y<=? AND y>=? AND z<=? AND z>=? AND world=?"; + private static final String INSERT_REGISTRY = "INSERT INTO REGISTRY (x,y,z,world,grp) VALUES (?,?,?,?,?)"; private static final String SELECT_REGISTRY = "SELECT grp FROM REGISTRY WHERE x=? AND y=? AND z=? AND world=?"; @@ -138,6 +141,38 @@ public class CitadelDao { throw new RuntimeException(e); } } + + public ResultSet selectReinforcements(String worldName, Integer smallestX, Integer largestX, + Integer smallestY, Integer largestY, Integer smallestZ, Integer largestZ){ + try { + PreparedStatement tmp = conn.prepareStatement(SELECT_REINFORCEMENTS); + tmp.setString(1, worldName); + tmp.setInt(2, largestX); + tmp.setInt(3, smallestX); + tmp.setInt(4, largestY); + tmp.setInt(5, smallestY); + tmp.execute(); + ResultSet result = tmp.getResultSet(); + return result; + } catch (SQLException e){ + throw new RuntimeException(e); + } + } + + public void updateReinforcements(String worldName, Integer smallestX, Integer largestX, + Integer smallestY, Integer largestY, Integer smallestZ, Integer largestZ){ + try { + PreparedStatement tmp = conn.prepareStatement(UPDATE_REINFORCEMENTS); + tmp.setString(1, worldName); + tmp.setInt(2, largestX); + tmp.setInt(3, smallestX); + tmp.setInt(4, largestY); + tmp.setInt(5, smallestY); + tmp.execute(); + } catch (SQLException e){ + throw new RuntimeException(e); + } + } public void addRegisteredGroup(Block block, String group) { try { From e8afe028159630874ac92eba48659af40b2b0616 Mon Sep 17 00:00:00 2001 From: Jonny D Date: Wed, 21 Mar 2012 07:26:50 +0000 Subject: [PATCH 2/3] enhanced solution to dynamite bug --- .../untamedears/Citadel/BlockListener.java | 49 +++++++---------- .../untamedears/Citadel/dao/CitadelDao.java | 55 ++++++++++++++----- 2 files changed, 62 insertions(+), 42 deletions(-) diff --git a/plugins/citadel-paper/src/com/untamedears/Citadel/BlockListener.java b/plugins/citadel-paper/src/com/untamedears/Citadel/BlockListener.java index 67fba3bdf..32c71c7a5 100644 --- a/plugins/citadel-paper/src/com/untamedears/Citadel/BlockListener.java +++ b/plugins/citadel-paper/src/com/untamedears/Citadel/BlockListener.java @@ -19,9 +19,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.material.Door; import org.bukkit.plugin.java.JavaPlugin; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.logging.Logger; @@ -104,10 +102,6 @@ public class BlockListener implements Listener { @EventHandler public void checkForExplosion(EntityExplodeEvent event){ - if(event.isCancelled()){ - return; - } - //Store blocks that are inside explosion's blast radius List blastRadiusBlocks = event.blockList(); @@ -117,6 +111,7 @@ public class BlockListener implements Listener { return; } + List reinforcedBlocks = new ArrayList(); HashMap affectedBlocks = new HashMap(); //Initialize min & max X,Y,Z coordinates @@ -170,44 +165,40 @@ public class BlockListener implements Listener { //Query database for any reinforced blocks that may be in the blast radius //Reinforced blocks should have a durability > 0 (aka >= 1) - ResultSet result = dao.selectReinforcements(worldName, smallestX, largestX, smallestY, largestY, smallestZ, largestZ); - + reinforcedBlocks = dao.selectReinforcements(worldName, smallestX, largestX, smallestY, largestY, smallestZ, largestZ); + System.out.println(reinforcedBlocks.get(0)); + + if(reinforcedBlocks.size() < 1){ + return; + } + //If there was some found, loop through each one - try { - while(result.next()){ - //Get X,Y,Z coords of reinforced block - int x = result.getInt(1); - int y = result.getInt(2); - int z = result.getInt(3); - - //Pass in x, y, z of reinforced block into affectedBlocks HashMap to instantiate a Block - Block protectedBlock = affectedBlocks.get(new Coordinate(world, x, y, z)); - //Then remove the protectedBlock from explosion list - event.blockList().remove(protectedBlock); - } - } catch (SQLException e) { - System.err.println("Citadel - explosion error"); + for(int i = 0; i < reinforcedBlocks.size(); i++){ + Coordinate reinforcedBlock = reinforcedBlocks.get(i); + //Then remove it from explosion + event.blockList().remove(affectedBlocks.get(reinforcedBlock)); } //Update reinforcements to set durability of blocks that are within blast radius //Explosion should decrement durability by 1 dao.updateReinforcements(worldName, smallestX, largestX, smallestY, largestY, smallestZ, largestZ); } - @EventHandler - public void controlAccess(PlayerInteractEvent pie) { - if (!pie.hasBlock()) return; + public void onPlayerInteract(PlayerInteractEvent event) { + if (!event.hasBlock()) return; + if(event.isCancelled()) return; - Block block = pie.getClickedBlock(); + Block block = event.getClickedBlock(); + Material matl = block.getType(); - Player p = pie.getPlayer(); + Player p = event.getPlayer(); if ((matl == Material.CHEST) || (matl == Material.WOODEN_DOOR) || (matl == Material.IRON_DOOR)) { String group = dao.getRegisteredGroup(block); if (group != null && !dao.isPlayerInGroup(group, p.getDisplayName())) { p.sendMessage(ChatColor.RED + "That door/chest is locked."); - pie.setCancelled(true); + event.setCancelled(true); } } } diff --git a/plugins/citadel-paper/src/com/untamedears/Citadel/dao/CitadelDao.java b/plugins/citadel-paper/src/com/untamedears/Citadel/dao/CitadelDao.java index 97aeb7402..f740f335c 100644 --- a/plugins/citadel-paper/src/com/untamedears/Citadel/dao/CitadelDao.java +++ b/plugins/citadel-paper/src/com/untamedears/Citadel/dao/CitadelDao.java @@ -1,11 +1,16 @@ package com.untamedears.Citadel.dao; import com.untamedears.Citadel.Citadel; +import com.untamedears.Citadel.Coordinate; import com.untamedears.Citadel.DelayedReinforcement; import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.block.Block; +import org.bukkit.plugin.java.JavaPlugin; import java.sql.*; +import java.util.ArrayList; +import java.util.List; /** * Created by IntelliJ IDEA. @@ -34,6 +39,7 @@ public class CitadelDao { private static final String SELECT_REGISTRY = "SELECT grp FROM REGISTRY WHERE x=? AND y=? AND z=? AND world=?"; private Connection conn; + private JavaPlugin myPlugin; public CitadelDao() throws ClassNotFoundException { Class.forName("org.sqlite.JDBC"); @@ -142,18 +148,38 @@ public class CitadelDao { } } - public ResultSet selectReinforcements(String worldName, Integer smallestX, Integer largestX, + public List selectReinforcements(String worldName, Integer smallestX, Integer largestX, Integer smallestY, Integer largestY, Integer smallestZ, Integer largestZ){ + + List reinforcedBlocks = new ArrayList(); + World world = myPlugin.getServer().getWorld(worldName); + try { PreparedStatement tmp = conn.prepareStatement(SELECT_REINFORCEMENTS); - tmp.setString(1, worldName); - tmp.setInt(2, largestX); - tmp.setInt(3, smallestX); - tmp.setInt(4, largestY); - tmp.setInt(5, smallestY); + tmp.setInt(1, largestX); + tmp.setInt(2, smallestX); + tmp.setInt(3, largestY); + tmp.setInt(4, smallestY); + tmp.setInt(5, largestZ); + tmp.setInt(6, smallestZ); + tmp.setString(7, worldName); tmp.execute(); ResultSet result = tmp.getResultSet(); - return result; + + while(result.next()){ + //Get X,Y,Z coords of reinforced block + int x = result.getInt(1); + int y = result.getInt(2); + int z = result.getInt(3); + + //Pass in x, y, z of reinforced block into affectedBlocks HashMap to instantiate a Block + reinforcedBlocks.add(new Coordinate(world, x, y, z)); + } + + tmp.close(); + result.close(); + + return reinforcedBlocks; } catch (SQLException e){ throw new RuntimeException(e); } @@ -163,13 +189,16 @@ public class CitadelDao { Integer smallestY, Integer largestY, Integer smallestZ, Integer largestZ){ try { PreparedStatement tmp = conn.prepareStatement(UPDATE_REINFORCEMENTS); - tmp.setString(1, worldName); - tmp.setInt(2, largestX); - tmp.setInt(3, smallestX); - tmp.setInt(4, largestY); - tmp.setInt(5, smallestY); + tmp.setInt(1, largestX); + tmp.setInt(2, smallestX); + tmp.setInt(3, largestY); + tmp.setInt(4, smallestY); + tmp.setInt(5, largestZ); + tmp.setInt(6, smallestZ); + tmp.setString(7, worldName); tmp.execute(); - } catch (SQLException e){ + tmp.close(); + } catch (SQLException e){ throw new RuntimeException(e); } } From 2f35b7f8cee81b79234d10bad02a109d4e1b41fa Mon Sep 17 00:00:00 2001 From: Jonny D Date: Wed, 21 Mar 2012 08:13:23 +0000 Subject: [PATCH 3/3] enhanced solution to dynamite bug --- .../untamedears/Citadel/BlockListener.java | 15 ++++--- .../src/com/untamedears/Citadel/Citadel.java | 45 ++++++++++++++++--- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/plugins/citadel-paper/src/com/untamedears/Citadel/BlockListener.java b/plugins/citadel-paper/src/com/untamedears/Citadel/BlockListener.java index 32c71c7a5..d47a98226 100644 --- a/plugins/citadel-paper/src/com/untamedears/Citadel/BlockListener.java +++ b/plugins/citadel-paper/src/com/untamedears/Citadel/BlockListener.java @@ -111,7 +111,7 @@ public class BlockListener implements Listener { return; } - List reinforcedBlocks = new ArrayList(); + List reinforcedBlocksCoords = new ArrayList(); HashMap affectedBlocks = new HashMap(); //Initialize min & max X,Y,Z coordinates @@ -165,18 +165,19 @@ public class BlockListener implements Listener { //Query database for any reinforced blocks that may be in the blast radius //Reinforced blocks should have a durability > 0 (aka >= 1) - reinforcedBlocks = dao.selectReinforcements(worldName, smallestX, largestX, smallestY, largestY, smallestZ, largestZ); - System.out.println(reinforcedBlocks.get(0)); + reinforcedBlocksCoords = dao.selectReinforcements(worldName, smallestX, largestX, smallestY, largestY, smallestZ, largestZ); - if(reinforcedBlocks.size() < 1){ + if(reinforcedBlocksCoords.size() < 1){ return; } //If there was some found, loop through each one - for(int i = 0; i < reinforcedBlocks.size(); i++){ - Coordinate reinforcedBlock = reinforcedBlocks.get(i); + for(int i = 0; i < reinforcedBlocksCoords.size(); i++){ + Coordinate rbCoords = reinforcedBlocksCoords.get(i); + Block reinforcedBlock = affectedBlocks.get(rbCoords); + //Then remove it from explosion - event.blockList().remove(affectedBlocks.get(reinforcedBlock)); + event.blockList().remove(reinforcedBlock); } //Update reinforcements to set durability of blocks that are within blast radius diff --git a/plugins/citadel-paper/src/com/untamedears/Citadel/Citadel.java b/plugins/citadel-paper/src/com/untamedears/Citadel/Citadel.java index edc4a655e..16ccde3e8 100644 --- a/plugins/citadel-paper/src/com/untamedears/Citadel/Citadel.java +++ b/plugins/citadel-paper/src/com/untamedears/Citadel/Citadel.java @@ -9,6 +9,9 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.logging.Logger; @@ -19,6 +22,7 @@ public class Citadel extends JavaPlugin { public HashMap playerPlacementState; public CitadelDao dao; public Logger log; + public Connection connection; public void onEnable() { log = this.getLogger(); @@ -46,14 +50,41 @@ public class Citadel extends JavaPlugin { materialRequirements.put(Material.getMaterial(keys[i]), requirements[i]); } - try { - dao = new CitadelDao(); + try + { + Class.forName("org.sqlite.JDBC"); + + this.connection = DriverManager.getConnection("jdbc:sqlite:plugins/Citadel/Citadel.db"); + this.connection.createStatement().execute( + "CREATE TABLE IF NOT EXISTS REINFORCEMENTS (x INTEGER,y INTEGER,z INTEGER,world TEXT,durability INTEGER);"); + + this.connection.createStatement().execute( + "CREATE TABLE IF NOT EXISTS GROUPS (grpName TEXT,member TEXT);"); + + this.connection.createStatement().execute( + "CREATE TABLE IF NOT EXISTS REGISTRY (x INTEGER,y INTEGER,z INTEGER,world TEXT,grp TEXT);"); + + Bukkit.getServer().getPluginManager().registerEvents(new BlockListener(this), this); + } + catch (SQLException e) + { + System.err.println("sorry there was some sort of sql exception:"); + System.err.println(e.toString()); + System.err.println(e.getSQLState()); + return; + } + catch (ClassNotFoundException e) + { + System.err.println("sorry we couldn't find the sqlite driver:"); + System.err.println(e.toString()); + return; + } + catch (Exception e) + { + System.err.println("Other weird error when enabling Citadel: "); + System.err.println(e.toString()); + } - Bukkit.getServer().getPluginManager().registerEvents(new BlockListener(this), this); - log.info("Citadel - Hi folks, Citadel is now on :D."); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } } public void onDisable() {