From e7a794add75c61e8b619fc0d5fc33d4cce415434 Mon Sep 17 00:00:00 2001 From: Jascha Starke Date: Sat, 27 Jul 2013 17:44:30 +0200 Subject: [PATCH] WorldEdit Intergration for remember BlockState (Should work with LogBlock, untested) --- pom.xml | 14 +- .../limitedcreative/ModBlockStates.java | 9 + .../blockstate/BlockListener.java | 11 +- .../blockstate/BlockState.java | 4 +- .../limitedcreative/blockstate/DBQueries.java | 32 ++- .../blockstate/DependencyListener.java | 28 +++ .../blockstate/worldedit/LCEditSession.java | 33 +++ .../worldedit/LCEditSessionFactory.java | 189 ++++++++++++++++++ .../worldedit/LCEditSession_LogBlock.java | 35 ++++ src/main/resources/lang/messages.properties | 2 +- 10 files changed, 346 insertions(+), 11 deletions(-) create mode 100644 src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/DependencyListener.java create mode 100644 src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/worldedit/LCEditSession.java create mode 100644 src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/worldedit/LCEditSessionFactory.java create mode 100644 src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/worldedit/LCEditSession_LogBlock.java diff --git a/pom.xml b/pom.xml index 74e635c..b3581cd 100644 --- a/pom.xml +++ b/pom.xml @@ -68,6 +68,12 @@ plib ${plib.version} + + + org.bukkit + bukkit + 1.6.2-R0.1-SNAPSHOT + com.sk89q @@ -93,10 +99,10 @@ 2.0.26 - - org.bukkit - bukkit - 1.6.2-R0.1-SNAPSHOT + + de.diddiz + logblock + 1.70 diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModBlockStates.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModBlockStates.java index 3261e42..baa7dea 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModBlockStates.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModBlockStates.java @@ -4,7 +4,9 @@ import de.jaschastarke.bukkit.lib.CoreModule; import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockListener; import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockStateConfig; import de.jaschastarke.minecraft.limitedcreative.blockstate.DBQueries; +import de.jaschastarke.minecraft.limitedcreative.blockstate.DependencyListener; import de.jaschastarke.minecraft.limitedcreative.blockstate.PlayerListener; +import de.jaschastarke.minecraft.limitedcreative.blockstate.worldedit.LCEditSessionFactory; import de.jaschastarke.modularize.IModule; import de.jaschastarke.modularize.ModuleEntry; import de.jaschastarke.modularize.ModuleEntry.ModuleState; @@ -35,6 +37,7 @@ public class ModBlockStates extends CoreModule { listeners.addListener(new BlockListener(this)); listeners.addListener(new PlayerListener(this)); + listeners.addListener(new DependencyListener(this)); } @Override public void onEnable() { @@ -48,6 +51,12 @@ public class ModBlockStates extends CoreModule { return; } super.onEnable(); + try { + if (plugin.getServer().getPluginManager().isPluginEnabled("WorldEdit")) + LCEditSessionFactory.initFactory(this); + } catch (Exception e) { + getLog().warn(plugin.getLocale().trans("block_state.warning.worldedit_sessionfactory_failed", e.getMessage())); + } getLog().info(plugin.getLocale().trans("basic.loaded.module")); } 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 2963ec3..3b82eae 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockListener.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockListener.java @@ -11,6 +11,7 @@ import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; import de.jaschastarke.minecraft.limitedcreative.ModBlockStates; +import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source; public class BlockListener implements Listener { private ModBlockStates mod; @@ -29,7 +30,7 @@ public class BlockListener implements Listener { if (mod.isDebug()) mod.getLog().debug("Breaking bad, err.. block: " + s.toString()); - if (s.getGameMode() == GameMode.CREATIVE && event.getPlayer().getGameMode() != GameMode.CREATIVE) { + if ((s.getGameMode() == GameMode.CREATIVE || s.getSource() == Source.EDIT) && event.getPlayer().getGameMode() != GameMode.CREATIVE) { if (mod.isDebug()) mod.getLog().debug("... was placed by creative. Drop prevented"); mod.getBlockSpawn().block(event.getBlock(), event.getPlayer()); @@ -49,10 +50,12 @@ public class BlockListener implements Listener { try { BlockState s = mod.getQueries().find(event.getBlock().getLocation()); + boolean update = false; 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()); @@ -61,7 +64,11 @@ public class BlockListener implements Listener { s.setDate(new Date()); if (mod.isDebug()) mod.getLog().debug("Saving BlockState: " + s.toString()); - mod.getQueries().insert(s); + + if (update) + mod.getQueries().update(s); + else + mod.getQueries().insert(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 46160ce..d0dff67 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockState.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockState.java @@ -98,8 +98,8 @@ public class BlockState { } public void setSource(Source source) { - if (source != Source.PLAYER) - setPlayer(null); + if (source != Source.PLAYER && source != Source.EDIT) + setPlayerName(null); this.source = source; } 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 394647c..6ca7097 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/DBQueries.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/DBQueries.java @@ -3,6 +3,7 @@ package de.jaschastarke.minecraft.limitedcreative.blockstate; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Types; import org.bukkit.GameMode; import org.bukkit.Location; @@ -50,6 +51,31 @@ public class DBQueries { delete.setString(4, s.getLocation().getWorld().getUID().toString()); return delete.executeUpdate() > 0; } + + private PreparedStatement update = null; + public boolean update(BlockState s) throws SQLException { + if (update == null) { + update = db.prepare("UPDATE lc_block_state SET gm = ?, player = ?, cdate = ?, source = ?"+ + "WHERE x = ? AND y = ? AND z = ? AND world = ? "); + } + if (s.getGameMode() == null) + update.setNull(5, Types.INTEGER); + else if (db.getType() == Type.MySQL) + update.setString(1, s.getGameMode().name()); + else + update.setInt(1, s.getGameMode().getValue()); + update.setString(2, s.getPlayerName()); + update.setTimestamp(3, new java.sql.Timestamp(s.getDate().getTime())); + if (db.getType() == Type.MySQL) + update.setString(4, s.getSource().name()); + else + update.setInt(4, s.getSource().ordinal()); + update.setInt(5, s.getLocation().getBlockX()); + update.setInt(6, s.getLocation().getBlockY()); + update.setInt(7, s.getLocation().getBlockZ()); + update.setString(8, s.getLocation().getWorld().getUID().toString()); + return update.executeUpdate() > 0; + } private PreparedStatement insert = null; public boolean insert(BlockState s) throws SQLException { @@ -61,7 +87,9 @@ public class DBQueries { insert.setInt(2, s.getLocation().getBlockY()); insert.setInt(3, s.getLocation().getBlockZ()); insert.setString(4, s.getLocation().getWorld().getUID().toString()); - if (db.getType() == Type.MySQL) + if (s.getGameMode() == null) + insert.setNull(5, Types.INTEGER); + else if (db.getType() == Type.MySQL) insert.setString(5, s.getGameMode().name()); else insert.setInt(5, s.getGameMode().getValue()); @@ -139,7 +167,7 @@ public class DBQueries { "gm ENUM('CREATIVE', 'SURVIVAL', 'ADVENTURE'),"+ "player VARCHAR(255),"+ "cdate TIMESTAMP NOT NULL,"+ - "source ENUM('SEED','PLAYER','EDIT','UNKNOWN'),"+ + "source ENUM('SEED','PLAYER','EDIT','UNKNOWN') NOT NULL,"+ "PRIMARY KEY (x, y, z, world)"+ ")" ); diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/DependencyListener.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/DependencyListener.java new file mode 100644 index 0000000..1da1d24 --- /dev/null +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/DependencyListener.java @@ -0,0 +1,28 @@ +package de.jaschastarke.minecraft.limitedcreative.blockstate; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.server.PluginEnableEvent; + +import de.jaschastarke.minecraft.limitedcreative.ModBlockStates; +import de.jaschastarke.minecraft.limitedcreative.blockstate.worldedit.LCEditSessionFactory; + +public class DependencyListener implements Listener { + private ModBlockStates mod; + + public DependencyListener(ModBlockStates mod) { + this.mod = mod; + } + + @EventHandler + public void onPluginLoaded(PluginEnableEvent event) { + if (event.getPlugin().getName().equals("LogBlock") || event.getPlugin().getName().equals("WorldEdit")) { + try { + if (mod.getPlugin().getServer().getPluginManager().isPluginEnabled("WorldEdit")) + LCEditSessionFactory.initFactory(mod); + } catch (Exception e) { + mod.getLog().warn(mod.getPlugin().getLocale().trans("block_state.warning.worldedit_sessionfactory_failed", e.getMessage())); + } + } + } +} diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/worldedit/LCEditSession.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/worldedit/LCEditSession.java new file mode 100644 index 0000000..203d5eb --- /dev/null +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/worldedit/LCEditSession.java @@ -0,0 +1,33 @@ +package de.jaschastarke.minecraft.limitedcreative.blockstate.worldedit; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.bags.BlockBag; +import com.sk89q.worldedit.blocks.BaseBlock; + +public class LCEditSession extends EditSession { + private LCEditSessionFactory factory; + private LocalPlayer player; + + public LCEditSession(LCEditSessionFactory factory, LocalWorld world, int maxBlocks, BlockBag blockBag, LocalPlayer player) { + super(world, maxBlocks, blockBag); + this.factory = factory; + this.player = player; + } + + public LCEditSession(LCEditSessionFactory factory, LocalWorld world, int maxBlocks, LocalPlayer player) { + super(world, maxBlocks); + this.factory = factory; + this.player = player; + } + + @Override + public boolean rawSetBlock(Vector pt, BaseBlock block) { + boolean success = super.rawSetBlock(pt, block); + if (success) + factory.onBlockEdit(player, pt, block); + return success; + } +} 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 new file mode 100644 index 0000000..9b3e9e1 --- /dev/null +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/worldedit/LCEditSessionFactory.java @@ -0,0 +1,189 @@ +package de.jaschastarke.minecraft.limitedcreative.blockstate.worldedit; + +import java.lang.reflect.InvocationTargetException; +import java.sql.SQLException; +import java.util.Date; + +import org.bukkit.Location; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.EditSessionFactory; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bags.BlockBag; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.bukkit.BukkitWorld; + +import de.jaschastarke.minecraft.limitedcreative.ModBlockStates; +import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState; +import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source; + +public class LCEditSessionFactory extends EditSessionFactory { + private ModBlockStates mod; + private EditSessionParent parent; + + static enum EditSessionParent { + WORLDEDIT, + LOGBLOCK("de.jaschastarke.minecraft.limitedcreative.blockstate.worldedit.LCEditSession_LogBlock"); + + private String cls = null; + EditSessionParent() { + } + EditSessionParent(String cls) { + this.cls = cls; + } + public EditSession createInstance(LCEditSessionFactory factory, LocalWorld world, int maxBlocks, LocalPlayer player) { + if (this.cls != null) { + try { + @SuppressWarnings("unchecked") + Class sessClass = (Class) Class.forName(cls); + return sessClass.getConstructor(LCEditSessionFactory.class, LocalWorld.class, int.class, LocalPlayer.class) + .newInstance(factory, world, maxBlocks, player); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (SecurityException e) { + e.printStackTrace(); + } + } + return new LCEditSession(factory, world, maxBlocks, player); + } + + public EditSession createInstance(LCEditSessionFactory factory, LocalWorld world, int maxBlocks, BlockBag blockBag, LocalPlayer player) { + if (this.cls != null) { + try { + @SuppressWarnings("unchecked") + Class sessClass = (Class) Class.forName(cls); + return sessClass.getConstructor(LCEditSessionFactory.class, LocalWorld.class, int.class, LocalPlayer.class) + .newInstance(factory, world, maxBlocks, player); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (SecurityException e) { + e.printStackTrace(); + } + } + return new LCEditSession(factory, world, maxBlocks, player); + } + } + + public ModBlockStates getLimitedCreativeModule() { + return mod; + } + + public LCEditSessionFactory(ModBlockStates mod, EditSessionParent parent) { + this.mod = mod; + this.parent = parent; + } + + @Override + public EditSession getEditSession(LocalWorld world, int maxBlocks, LocalPlayer player) { + return parent.createInstance(this, world, maxBlocks, player); + /*switch (parent) { + case LOGBLOCK: + return new LCEditSession_LogBlock(this, world, maxBlocks, player); + default: + return new LCEditSession(this, world, maxBlocks, player); + }*/ + } + + // Without Player, the world isn't know, so we can't opporate + /*@Override + public EditSession getEditSession(LocalWorld world, int maxBlocks) { + return new LCEditSession(this, world, maxBlocks, null); + }*/ + + @Override + public EditSession getEditSession(LocalWorld world, int maxBlocks, BlockBag blockBag, LocalPlayer player) { + return parent.createInstance(this, world, maxBlocks, blockBag, player); + /*switch (parent) { + case LOGBLOCK: + return new LCEditSession_LogBlock(this, world, maxBlocks, blockBag, player); + default: + return new LCEditSession(this, world, maxBlocks, blockBag, player); + }*/ + } + + /*@Override + public EditSession getEditSession(LocalWorld world, int maxBlocks, BlockBag blockBag) { + return new LCEditSession(this, world, maxBlocks, blockBag, null); + }*/ + + public static void initFactory(ModBlockStates mod) throws Exception { + EditSessionFactory currentEditSessionFactory = WorldEdit.getInstance().getEditSessionFactory(); + if (currentEditSessionFactory instanceof LCEditSessionFactory) { + if (mod.isDebug()) + mod.getLog().debug("WorlEdit-SessionFactory is already hooked"); + } else if (currentEditSessionFactory.getClass().equals(EditSessionFactory.class)) { // not overridden + if (mod.isDebug()) + mod.getLog().debug("Replacing WorldEdits SessionFactory"); + WorldEdit.getInstance().setEditSessionFactory(new LCEditSessionFactory(mod, EditSessionParent.WORLDEDIT)); + } else if (currentEditSessionFactory.getClass().getName().equals("de.diddiz.worldedit.LogBlockEditSessionFactory")) { + if (mod.isDebug()) + mod.getLog().debug("Replacing LogBlocks WorldEdit-SessionFactory"); + WorldEdit.getInstance().setEditSessionFactory(new LCEditSessionFactory(mod, EditSessionParent.LOGBLOCK)); + } else { + throw new Exception("WorldEdit-SessionFactory is hooked by an unknown another Plugin."); + } + } + + /*public void onBlockEdit(Vector pt, BaseBlock block) { + this.onBlockEdit(null, pt, block); + }*/ + public boolean onBlockEdit(LocalPlayer player, Vector pt, BaseBlock block) { + 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 { + s = new BlockState(); + s.setLocation(loc); + } + s.setGameMode(null); + s.setPlayerName(player.getName()); + s.setDate(new Date()); + s.setSource(Source.EDIT); + if (mod.isDebug()) + mod.getLog().debug("Saving BlockState: " + s.toString()); + + if (update) + mod.getQueries().update(s); + else + mod.getQueries().insert(s); + } catch (SQLException e) { + mod.getLog().warn("DB-Error while onBlockEdit: "+e.getMessage()); + return false; + } + return true; + } else { + return false; + } + } + +} diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/worldedit/LCEditSession_LogBlock.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/worldedit/LCEditSession_LogBlock.java new file mode 100644 index 0000000..d5f0d39 --- /dev/null +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/worldedit/LCEditSession_LogBlock.java @@ -0,0 +1,35 @@ +package de.jaschastarke.minecraft.limitedcreative.blockstate.worldedit; + +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.bags.BlockBag; +import com.sk89q.worldedit.blocks.BaseBlock; + +import de.diddiz.LogBlock.LogBlock; +import de.diddiz.worldedit.LogBlockEditSession; + +public class LCEditSession_LogBlock extends LogBlockEditSession { + private LCEditSessionFactory factory; + private LocalPlayer player; + + public LCEditSession_LogBlock(LCEditSessionFactory factory, LocalWorld world, int maxBlocks, BlockBag blockBag, LocalPlayer player) { + super(world, maxBlocks, blockBag, player, LogBlock.getInstance()); + this.factory = factory; + this.player = player; + } + + public LCEditSession_LogBlock(LCEditSessionFactory factory, LocalWorld world, int maxBlocks, LocalPlayer player) { + super(world, maxBlocks, player, LogBlock.getInstance()); + this.factory = factory; + this.player = player; + } + + @Override + public boolean rawSetBlock(Vector pt, BaseBlock block) { + boolean success = super.rawSetBlock(pt, block); + if (success) + factory.onBlockEdit(player, pt, block); + return success; + } +} diff --git a/src/main/resources/lang/messages.properties b/src/main/resources/lang/messages.properties index 4010789..93394a0 100644 --- a/src/main/resources/lang/messages.properties +++ b/src/main/resources/lang/messages.properties @@ -47,6 +47,6 @@ blocked.region.piston_in: Moving {0} block into creative area was blocked at {1} block_state.tool_info.seed: This {0}-Block is generated by the god who created this world block_state.tool_info.player: This {0}-Block was created by ''{1}'' in {2}-mode on {3} -block_state.tool_info.edit: This {0}-Block was modified by the tool ''{1}'' or such at {3} +block_state.tool_info.edit: This {0}-Block was modified with WorldEdit by ''{1}'' on {3} block_state.tool_info.unknown: The origin of this {0}-Block is unknown block_state.error.sql_connection_failed: Failed to connect to Database. Check bukkit.yml \ No newline at end of file