From b823dc24a1b13462309966bfbacf0bfc098a28ce Mon Sep 17 00:00:00 2001 From: Jascha Starke Date: Sun, 28 Jul 2013 20:23:43 +0200 Subject: [PATCH] BlockState-Command BlockState loading fix BlockState piston bypass prevention Loading without WorldEdit dependency fix --- pom.xml | 2 + .../limitedcreative/FeatureMetrics.java | 9 + .../FeatureSwitchGameMode.java | 15 +- .../limitedcreative/ModBlockStates.java | 9 + .../minecraft/limitedcreative/ModRegions.java | 25 ++- .../blockstate/BlockListener.java | 74 +++++++- .../blockstate/BlockState.java | 3 +- .../blockstate/BlockStateCommand.java | 171 ++++++++++++++++++ .../blockstate/BlockStatePermissions.java | 10 + .../limitedcreative/blockstate/DBQueries.java | 58 +++++- .../blockstate/PlayerListener.java | 6 +- .../worldedit/LCEditSessionFactory.java | 2 +- .../regions/BlockListener.java | 2 +- .../regions/IWorldGuardIntegration.java | 9 + .../regions/RegionsCommand.java | 17 +- .../regions/WorldGuardIntegration.java | 34 ++++ .../worldguard/CustomRegionManager.java | 10 +- src/main/resources/lang/messages.properties | 12 +- 18 files changed, 415 insertions(+), 53 deletions(-) create mode 100644 src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockStateCommand.java create mode 100644 src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/IWorldGuardIntegration.java create mode 100644 src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/WorldGuardIntegration.java diff --git a/pom.xml b/pom.xml index b3581cd..2bbda4c 100644 --- a/pom.xml +++ b/pom.xml @@ -146,6 +146,7 @@ MultiInv Multiverse-Inventories Vault + LogBlock http://dev.bukkit.org/server-mods/limited-creative/ @@ -162,6 +163,7 @@ de.jaschastarke.minecraft.limitedcreative.MainCommand de.jaschastarke.minecraft.limitedcreative.regions.RegionsCommand + de.jaschastarke.minecraft.limitedcreative.blockstate.BlockStateCommand diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureMetrics.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureMetrics.java index 7177083..b3c3d11 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureMetrics.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureMetrics.java @@ -39,6 +39,15 @@ public class FeatureMetrics extends CoreModule implements Liste }); } } + Graph depGraph = mcstats.createGraph("Dependencies"); + for (final String dep : plugin.getDescription().getSoftDepend()) { + depGraph.addPlotter(new MCStatsMetrics.Plotter(dep) { + @Override + public int getValue() { + return plugin.getServer().getPluginManager().isPluginEnabled(dep) ? 1 : 0; + } + }); + } mcstats.start(); } catch (IOException e) { diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureSwitchGameMode.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureSwitchGameMode.java index 4e0b2ce..47c6c56 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureSwitchGameMode.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureSwitchGameMode.java @@ -25,8 +25,7 @@ import de.jaschastarke.bukkit.lib.commands.annotations.NeedsPermission; import de.jaschastarke.bukkit.lib.commands.annotations.Usages; import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission; import de.jaschastarke.minecraft.lib.permissions.IPermission; -import de.jaschastarke.minecraft.limitedcreative.regions.Flags; -import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.ApplicableRegions; +import de.jaschastarke.modularize.ModuleEntry.ModuleState; public class FeatureSwitchGameMode extends CoreModule { public FeatureSwitchGameMode(LimitedCreative plugin) { @@ -103,20 +102,14 @@ public class FeatureSwitchGameMode extends CoreModule { return true; } - protected GameMode getDefaultGameMode(World world) { + private GameMode getDefaultGameMode(World world) { return Hooks.DefaultWorldGameMode.get(world); } private boolean regionOptional(Player player, GameMode tgm) { ModRegions mod = plugin.getModule(ModRegions.class); - if (mod != null) { - ApplicableRegions rs = mod.getRegionManager().getRegionSet(player.getLocation()); - if (rs.allows(Flags.GAMEMODE_OPTIONAL)) { - if ((tgm == rs.getFlag(Flags.GAMEMODE, player)) || (tgm == this.getDefaultGameMode(player.getWorld()))) - return true; - } - } - return false; + return mod != null && mod.getModuleEntry().getState() == ModuleState.ENABLED + && mod.getWorldGuardIntegration().isRegionOptional(player, tgm); } @IsCommand("survival") diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModBlockStates.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModBlockStates.java index baa7dea..e3adfb9 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModBlockStates.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModBlockStates.java @@ -1,7 +1,9 @@ package de.jaschastarke.minecraft.limitedcreative; import de.jaschastarke.bukkit.lib.CoreModule; +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.DBQueries; import de.jaschastarke.minecraft.limitedcreative.blockstate.DependencyListener; @@ -15,6 +17,7 @@ public class ModBlockStates extends CoreModule { private BlockStateConfig config; private FeatureBlockItemSpawn blockDrops; private DBQueries queries; + private BlockStateCommand command; public ModBlockStates(LimitedCreative plugin) { super(plugin); @@ -38,6 +41,8 @@ public class ModBlockStates extends CoreModule { listeners.addListener(new BlockListener(this)); listeners.addListener(new PlayerListener(this)); listeners.addListener(new DependencyListener(this)); + + command = new BlockStateCommand(this); } @Override public void onEnable() { @@ -58,6 +63,10 @@ public class ModBlockStates extends CoreModule { getLog().warn(plugin.getLocale().trans("block_state.warning.worldedit_sessionfactory_failed", e.getMessage())); } + + plugin.getCommandHandler().registerCommand(command); + plugin.getMainCommand().registerCommand(new AliasHelpedCommand(command, "blockstate", new String[]{"bs"})); + getLog().info(plugin.getLocale().trans("basic.loaded.module")); } @Override diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModRegions.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModRegions.java index d442222..a6345e2 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModRegions.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModRegions.java @@ -4,19 +4,17 @@ import java.io.File; import org.bukkit.entity.Player; -import com.sk89q.worldguard.bukkit.WorldGuardPlugin; - import de.jaschastarke.bukkit.lib.CoreModule; import de.jaschastarke.bukkit.lib.commands.AliasHelpedCommand; import de.jaschastarke.minecraft.limitedcreative.regions.BlockListener; -import de.jaschastarke.minecraft.limitedcreative.regions.Flags; +import de.jaschastarke.minecraft.limitedcreative.regions.IWorldGuardIntegration; import de.jaschastarke.minecraft.limitedcreative.regions.PlayerData; import de.jaschastarke.minecraft.limitedcreative.regions.PlayerListener; import de.jaschastarke.minecraft.limitedcreative.regions.RegionConfig; import de.jaschastarke.minecraft.limitedcreative.regions.RegionListener; import de.jaschastarke.minecraft.limitedcreative.regions.RegionsCommand; +import de.jaschastarke.minecraft.limitedcreative.regions.WorldGuardIntegration; import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.CustomRegionManager; -import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.FlagList; import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.PlayerRegionListener; import de.jaschastarke.modularize.IModule; import de.jaschastarke.modularize.ModuleEntry; @@ -24,7 +22,7 @@ import de.jaschastarke.modularize.ModuleEntry.ModuleState; public class ModRegions extends CoreModule { private CustomRegionManager mgr; - private WorldGuardPlugin wg; + private IWorldGuardIntegration wg; private PlayerData pdata; private FeatureBlockItemSpawn blockDrops = null; private RegionConfig config; @@ -62,7 +60,14 @@ public class ModRegions extends CoreModule { listeners.addListener(new RegionListener(this)); listeners.addListener(new PlayerRegionListener(this)); // Fires Custom-Events listen by RegionListener - FlagList.addFlags(Flags.getList()); + getWorldGuardIntegration().initFlagList(); + } + + public IWorldGuardIntegration getWorldGuardIntegration() { + if (wg == null) { + wg = new WorldGuardIntegration(this); + } + return wg; } @Override @@ -70,9 +75,9 @@ public class ModRegions extends CoreModule { super.onEnable(); mgr = new CustomRegionManager(new File(plugin.getDataFolder(), "regions.yml"), this); - wg = (WorldGuardPlugin) plugin.getServer().getPluginManager().getPlugin("WorldGuard"); + /*wg = (WorldGuardPlugin) plugin.getServer().getPluginManager().getPlugin("WorldGuard"); if (wg == null) - throw new IllegalAccessError("Missing Plugin WorldGuard"); + throw new IllegalAccessError("Missing Plugin WorldGuard");*/ plugin.getCommandHandler().registerCommand(command); plugin.getMainCommand().registerCommand(new AliasHelpedCommand(command, "region", new String[]{"r"})); @@ -93,9 +98,9 @@ public class ModRegions extends CoreModule { return config; } - public WorldGuardPlugin getWorldGuard() { + /*public WorldGuardPlugin getWorldGuard() { return wg; - } + }*/ public CustomRegionManager getRegionManager() { return mgr; } 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 3b82eae..537fbbd 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockListener.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockListener.java @@ -1,14 +1,21 @@ package de.jaschastarke.minecraft.limitedcreative.blockstate; import java.sql.SQLException; +import java.util.ArrayList; import java.util.Date; +import java.util.List; import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.block.Block; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; 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.metadata.FixedMetadataValue; import de.jaschastarke.minecraft.limitedcreative.ModBlockStates; import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source; @@ -19,11 +26,8 @@ public class BlockListener implements Listener { this.mod = mod; } - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onBlockBreak(BlockBreakEvent event) { - if (event.isCancelled()) - return; - try { BlockState s = mod.getQueries().find(event.getBlock().getLocation()); if (s != null) { @@ -34,6 +38,7 @@ public class BlockListener implements Listener { 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); @@ -43,11 +48,8 @@ public class BlockListener implements Listener { event.setCancelled(true); } } - @EventHandler(priority = EventPriority.MONITOR) + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onBlockPlace(BlockPlaceEvent event) { - if (event.isCancelled()) - return; - try { BlockState s = mod.getQueries().find(event.getBlock().getLocation()); boolean update = false; @@ -74,4 +76,60 @@ public class BlockListener implements Listener { event.setCancelled(true); } } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPistionExtend(BlockPistonExtendEvent event) { + if (event.getBlock().getMetadata("LCBS_pistonIsAlreadyExtended").size() > 0) // Fixes long known Bukkit issue + return; + event.getBlock().setMetadata("LCBS_pistonIsAlreadyExtended", new FixedMetadataValue(mod.getPlugin(), new Boolean(true))); + + Block source = event.getBlock().getRelative(event.getDirection()); + /*if (mod.isDebug()) + mod.getLog().debug("PistonExtend "+source.getType()+" "+source.getLocation()+" "+event.getDirection());*/ + + List movedBlocks = new ArrayList(); + while (source != null && source.getType() != Material.AIR) { + movedBlocks.add(0, source); // put on top, so iterating the + source = source.getRelative(event.getDirection()); + } + + try { + if (movedBlocks.size() > 0) { + mod.getQueries().getDB().startTransaction(); + for (Block sblock : movedBlocks) { + Block dest = sblock.getRelative(event.getDirection()); + if (mod.isDebug()) + mod.getLog().debug("PistionExtend moves "+sblock.getType()+"-Block from "+sblock.getLocation()+" to "+dest.getLocation()); + + mod.getQueries().move(sblock.getLocation(), dest.getLocation()); + } + mod.getQueries().getDB().endTransaction(); + } + } catch (SQLException e) { + try { + mod.getQueries().getDB().revertTransaction(); + } catch (SQLException e1) { + } + mod.getLog().warn("DB-Error while onBlockMove (extend): "+e.getMessage()); + //event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPistionRetract(BlockPistonRetractEvent event) { + event.getBlock().removeMetadata("LCBS_pistonIsAlreadyExtended", mod.getPlugin()); + + Block dest = event.getBlock().getRelative(event.getDirection()); + Block source = dest.getRelative(event.getDirection()); + if (event.isSticky() && source.getType() != Material.AIR) { + try { + if (mod.isDebug()) + mod.getLog().debug("PistionRetract moves "+source.getType()+"-Block from "+source.getLocation()+" to "+dest.getLocation()); + mod.getQueries().move(source.getLocation(), source.getRelative(event.getDirection().getOppositeFace()).getLocation()); + } catch (SQLException e) { + mod.getLog().warn("DB-Error while onBlockMove (retract): "+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 d0dff67..769d302 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockState.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockState.java @@ -27,6 +27,7 @@ public class BlockState { SEED, // There is no way to determine this source, but lets be prepared for miracles ;) PLAYER, EDIT, // WorldEdit or MCEdit or such, we also can't determine that. But I keep believing in miracles + COMMAND, // Manual Databse-Change via. BlockState-Command UNKNOWN } @@ -98,7 +99,7 @@ public class BlockState { } public void setSource(Source source) { - if (source != Source.PLAYER && source != Source.EDIT) + if (source != Source.PLAYER && source != Source.EDIT && source != Source.COMMAND) setPlayerName(null); this.source = source; } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockStateCommand.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockStateCommand.java new file mode 100644 index 0000000..9786fa0 --- /dev/null +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockStateCommand.java @@ -0,0 +1,171 @@ +package de.jaschastarke.minecraft.limitedcreative.blockstate; + +import java.sql.SQLException; +import java.util.Date; + +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.scheduler.BukkitRunnable; + +import com.sk89q.worldedit.bukkit.WorldEditPlugin; +import com.sk89q.worldedit.bukkit.selections.Selection; + +import de.jaschastarke.LocaleString; +import de.jaschastarke.bukkit.lib.commands.BukkitCommand; +import de.jaschastarke.bukkit.lib.commands.CommandContext; +import de.jaschastarke.bukkit.lib.commands.CommandException; +import de.jaschastarke.bukkit.lib.commands.HelpCommand; +import de.jaschastarke.bukkit.lib.commands.IHelpDescribed; +import de.jaschastarke.bukkit.lib.commands.MissingPermissionCommandException; +import de.jaschastarke.bukkit.lib.commands.annotations.IsCommand; +import de.jaschastarke.bukkit.lib.commands.annotations.Usages; +import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission; +import de.jaschastarke.minecraft.limitedcreative.ModBlockStates; +import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source; + +/** + * LimitedCreative-BlockState-Command: modify blockstate database to prevent drops of selected blocks (requires WorldEdit) + * @usage / - displays Regions-Command-Help + * @permission limitedcreative.blockstate.command + */ +public class BlockStateCommand extends BukkitCommand implements IHelpDescribed { + private ModBlockStates mod; + private HelpCommand help; + + public BlockStateCommand() { + this.help = this.getDefaultHelpCommand(); + } + public BlockStateCommand(ModBlockStates mod) { + this(); + this.mod = mod; + } + + @Override + public String getName() { + return "lcbs"; + } + + @Override + public String[] getAliases() { + return new String[]{}; + } + + /** + * @internal has no effect, as not tested by any command handler + * @see IHelpDescribed + */ + @Override + public IAbstractPermission[] getRequiredPermissions() { + return new IAbstractPermission[]{BlockStatePermissions.COMMAND}; + } + + @Override + public CharSequence[] getUsages() { + return null; + } + + @Override + public CharSequence getDescription() { + return new LocaleString("command.blockstate"); + } + + @Override + public CharSequence getPackageName() { + return mod.getPlugin().getName() + " - " + mod.getName(); + } + + /** + * Modifies the Block-GameMode-Database and sets all blocks in the selection to the provided gamemode. Set it + * to "creative" to disable drop of this block on destroying. Set it to "survival" to allow it. + * WorldEdit is required, because the selection Region is used. + * gamemode can be: survival / creative / adventure / s / c / a / 0 / 1 / 2 + * @throws MissingPermissionCommandException + */ + @IsCommand("set") + //@NeedsPermission("region") + @Usages("") + public boolean setGameMode(final CommandContext context, String... args) throws CommandException, MissingPermissionCommandException { + if (!mod.getPlugin().getServer().getPluginManager().isPluginEnabled("WorldEdit")) { + help.execute(context, new String[]{"set"}); + context.response(L("command.blockstate.requires_worldedit")); + return true; + } + if (!context.isPlayer()) { + context.response(L("cmdblock.blocked.not_console")); + return true; + } + if (args.length < 1) {// doesn't count parameters + return false; + } + String gm = args[0].toLowerCase(); + final GameMode tgm; + if (gm.equals("0") || gm.equals("s") || gm.equals("survival")) + tgm = GameMode.SURVIVAL; + else if (gm.equals("1") || gm.equals("c") || gm.equals("creative")) + tgm = GameMode.CREATIVE; + else if (gm.equals("2") || gm.equals("a") || gm.equals("adventure")) + tgm = GameMode.ADVENTURE; + else { + return false; + } + + WorldEditPlugin we = (WorldEditPlugin) mod.getPlugin().getServer().getPluginManager().getPlugin("WorldEdit"); + final Selection selection = we.getSelection(context.getPlayer()); + + if (selection == null) { + context.response(L("command.blockstate.worledit_selection_empty")); + return true; + } + + final Location min = selection.getMinimumPoint(); + final Location max = selection.getMaximumPoint(); + + mod.getPlugin().getServer().getScheduler().runTaskAsynchronously(mod.getPlugin(), new BukkitRunnable() { + @Override + public void run() { + DBQueries q = mod.getQueries(); + try { + q.getDB().startTransaction(); + int count = 0; + World w = selection.getWorld(); + BlockState seed = new BlockState(); + seed.setPlayer(context.getPlayer()); + seed.setGameMode(tgm); + seed.setSource(Source.COMMAND); + seed.setDate(new Date()); + for (int x = min.getBlockX(); x <= max.getBlockX(); x++) { + for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { + for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { + 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); + count++; + } + } + } + } + q.getDB().endTransaction(); + + context.response(L("command.blockstate.command_updated", count)); + } catch (SQLException e) { + try { + q.getDB().revertTransaction(); + } catch (SQLException e1) { + } + mod.getLog().warn("Failed to update blocks in region: " + e.getMessage()); + context.response(L("command.blockstate.command_failed")); + } + } + }); + return true; + } + + private String L(String msg, Object... args) { + return mod.getPlugin().getLocale().trans(msg, args); + } +} diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockStatePermissions.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockStatePermissions.java index 4a1f5f6..51d394d 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockStatePermissions.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/BlockStatePermissions.java @@ -40,4 +40,14 @@ public class BlockStatePermissions extends SimplePermissionContainerNode { * Grants ability to use the configured tool to get info about placed blocks. */ public static final IPermission TOOL = new BasicPermission(PARENT, "tool", PermissionDefault.OP); + + /** + * Grants access to the blockstate admin command to modify the database. + */ + public static final IPermission COMMAND = new BasicPermission(PARENT, "command", PermissionDefault.OP); + + /** + * Allows to get drops even if a block was created from a creative player or WorldEdit. + */ + public static final IPermission BYPASS = new BasicPermission(PARENT, "bypass", PermissionDefault.FALSE); } 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 6ca7097..122e428 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/DBQueries.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/DBQueries.java @@ -31,7 +31,7 @@ public class DBQueries { if (rs.next()) { BlockState bs = new BlockState(); bs.setLocation(loc); - bs.setDate(rs.getDate("cdate")); + bs.setDate(rs.getTimestamp("cdate")); bs.setGameMode(getGameMode(rs)); bs.setPlayerName(rs.getString("player")); bs.setSource(getSource(rs)); @@ -42,13 +42,16 @@ public class DBQueries { private PreparedStatement delete = null; public boolean delete(BlockState s) throws SQLException { + return delete(s.getLocation()); + } + public boolean delete(Location loc) throws SQLException { if (delete == null) { delete = db.prepare("DELETE FROM lc_block_state WHERE x = ? AND y = ? AND z = ? AND world = ?"); } - delete.setInt(1, s.getLocation().getBlockX()); - delete.setInt(2, s.getLocation().getBlockY()); - delete.setInt(3, s.getLocation().getBlockZ()); - delete.setString(4, s.getLocation().getWorld().getUID().toString()); + delete.setInt(1, loc.getBlockX()); + delete.setInt(2, loc.getBlockY()); + delete.setInt(3, loc.getBlockZ()); + delete.setString(4, loc.getWorld().getUID().toString()); return delete.executeUpdate() > 0; } @@ -76,13 +79,49 @@ public class DBQueries { update.setString(8, s.getLocation().getWorld().getUID().toString()); return update.executeUpdate() > 0; } - + + private PreparedStatement move = null; + public boolean move(BlockState s, Location newLoc) throws SQLException { + boolean r = move(s.getLocation(), newLoc); + if (r) + s.setLocation(newLoc); + return r; + } + + public boolean move(Location oldLoc, Location newLoc) throws SQLException { + if (move == null) { + move = db.prepare("UPDATE lc_block_state SET x = ?, y = ?, z = ? "+ + "WHERE x = ? AND y = ? AND z = ? AND world = ?"); + } + + move.setInt(1, newLoc.getBlockX()); + move.setInt(2, newLoc.getBlockY()); + move.setInt(3, newLoc.getBlockZ()); + move.setInt(4, oldLoc.getBlockX()); + move.setInt(5, oldLoc.getBlockY()); + move.setInt(6, oldLoc.getBlockZ()); + move.setString(7, oldLoc.getWorld().getUID().toString()); + + return move.executeUpdate() > 0; + } + + /*private PreparedStatement replace = null; + public boolean replace(BlockState s) throws SQLException { + if (replace == null) { + replace = db.prepare("INSERT OR REPLACE INTO lc_block_state (x, y, z, world, gm, player, cdate, source)"+ + " VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); + } + return this._executeInsert(replace, s); + }*/ private PreparedStatement insert = null; public boolean insert(BlockState s) throws SQLException { if (insert == null) { insert = db.prepare("INSERT INTO lc_block_state (x, y, z, world, gm, player, cdate, source)"+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); } + return this._executeInsert(insert, s); + } + private boolean _executeInsert(PreparedStatement insert, BlockState s) throws SQLException { insert.setInt(1, s.getLocation().getBlockX()); insert.setInt(2, s.getLocation().getBlockY()); insert.setInt(3, s.getLocation().getBlockZ()); @@ -150,7 +189,7 @@ public class DBQueries { "source integer not null,"+ "primary key (x, y, z, world),"+ "constraint ck_lc_block_state_gm check (gm in (0,1,2)),"+ - "constraint ck_lc_block_state_source check (source in (0,1,2,3))"+ + "constraint ck_lc_block_state_source check (source in (0,1,2,3,4))"+ ")" ); db.getLogger().info("Created SQLite-Table: lc_block_state"); @@ -167,7 +206,7 @@ public class DBQueries { "gm ENUM('CREATIVE', 'SURVIVAL', 'ADVENTURE'),"+ "player VARCHAR(255),"+ "cdate TIMESTAMP NOT NULL,"+ - "source ENUM('SEED','PLAYER','EDIT','UNKNOWN') NOT NULL,"+ + "source ENUM('SEED','PLAYER','EDIT','COMMAND','UNKNOWN') NOT NULL,"+ "PRIMARY KEY (x, y, z, world)"+ ")" ); @@ -178,4 +217,7 @@ public class DBQueries { throw new RuntimeException("Currently only SQLite is supported."); } } + public Database getDB() { + return db; + } } 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 40fae9c..2528e78 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/PlayerListener.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/blockstate/PlayerListener.java @@ -23,11 +23,9 @@ public class PlayerListener implements Listener { @EventHandler(priority = EventPriority.HIGH) public void onInteract(PlayerInteractEvent event) { - if (event.isCancelled()) - return; - if (event.getAction() == Action.RIGHT_CLICK_BLOCK && mod.getPlugin().getPermManager().hasPermission(event.getPlayer(), BlockStatePermissions.TOOL)) { + if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { Block b = event.getClickedBlock(); - if (b != null && event.getPlayer().getItemInHand().getType().equals(mod.getConfig().getTool())) { + if (b != null && event.getPlayer().getItemInHand().getType().equals(mod.getConfig().getTool()) && mod.getPlugin().getPermManager().hasPermission(event.getPlayer(), BlockStatePermissions.TOOL)) { try { BlockState s = mod.getQueries().find(b.getLocation()); InGameFormatter f = new InGameFormatter(mod.getPlugin().getLang()); 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 9b3e9e1..6e9feb8 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 @@ -143,7 +143,7 @@ public class LCEditSessionFactory extends EditSessionFactory { 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."); + throw new Exception("WorldEdit-SessionFactory is hooked by an unknown another Plugin (" + currentEditSessionFactory.getClass().getName() + ")."); } } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/BlockListener.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/BlockListener.java index 3baa30b..fe4bfbb 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/BlockListener.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/BlockListener.java @@ -120,7 +120,7 @@ public class BlockListener extends Listener { Block dest = source.getRelative(event.getDirection().getOppositeFace()); if (mod.isDebug()) mod.getLog().debug("PistonRetract "+source.getType()+" "+event.getDirection() + " " + event.isSticky()); - if (event.isSticky() && source.getType() != Material.AIR) { + if (event.isSticky() && source.getType() != Material.AIR) { if (mod.isDebug()) mod.getLog().debug("dest "+dest.getType()); if (regionSet(source).getFlag(Flags.GAMEMODE) == GameMode.CREATIVE) { diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/IWorldGuardIntegration.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/IWorldGuardIntegration.java new file mode 100644 index 0000000..c34a237 --- /dev/null +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/IWorldGuardIntegration.java @@ -0,0 +1,9 @@ +package de.jaschastarke.minecraft.limitedcreative.regions; + +import org.bukkit.GameMode; +import org.bukkit.entity.Player; + +public interface IWorldGuardIntegration { + public void initFlagList(); + public boolean isRegionOptional(Player player, GameMode tgm); +} diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/RegionsCommand.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/RegionsCommand.java index d64d57c..708591b 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/RegionsCommand.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/RegionsCommand.java @@ -4,6 +4,7 @@ import org.apache.commons.lang.StringUtils; import org.bukkit.ChatColor; import org.bukkit.World; +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.protection.ApplicableRegionSet; import com.sk89q.worldguard.protection.flags.Flag; import com.sk89q.worldguard.protection.flags.InvalidFlagFormat; @@ -38,13 +39,15 @@ import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.Region; public class RegionsCommand extends BukkitCommand implements IHelpDescribed { private ModRegions mod; private HelpCommand help; + private WorldGuardPlugin wg; public RegionsCommand() { this.help = this.getDefaultHelpCommand(); } public RegionsCommand(ModRegions mod) { + this(); this.mod = mod; - this.help = this.getDefaultHelpCommand(); + this.wg = (WorldGuardPlugin) mod.getPlugin().getServer().getPluginManager().getPlugin("WorldGaurd"); } @Override @@ -108,7 +111,7 @@ public class RegionsCommand extends BukkitCommand implements IHelpDescribed { if (w == null) throw new CommandException(L("command.worldguard.world_not_found")); - RegionManager mgr = mod.getWorldGuard().getGlobalRegionManager().get(w); + RegionManager mgr = getWorldGuard().getGlobalRegionManager().get(w); ProtectedRegion region = mgr.getRegion(params.getArgument(0)); if (region == null && params.getArgument(0).equalsIgnoreCase("__global__")) { region = new GlobalProtectedRegion(params.getArgument(0)); @@ -129,7 +132,7 @@ public class RegionsCommand extends BukkitCommand implements IHelpDescribed { String value = params.getValue(); try { if (value != null) { - reg.setFlag(flag, flag.parseInput(mod.getWorldGuard(), context.getSender(), value)); + reg.setFlag(flag, flag.parseInput(getWorldGuard(), context.getSender(), value)); } else { reg.setFlag(flag, null); } @@ -165,14 +168,14 @@ public class RegionsCommand extends BukkitCommand implements IHelpDescribed { ProtectedRegion region = null; if (params.getArgumentCount() == 0 && context.isPlayer()) { - RegionManager mgr = mod.getWorldGuard().getGlobalRegionManager().get(context.getPlayer().getWorld()); + RegionManager mgr = getWorldGuard().getGlobalRegionManager().get(context.getPlayer().getWorld()); ApplicableRegionSet set = mgr.getApplicableRegions(context.getPlayer().getLocation()); if (set.size() > 0) { region = set.iterator().next(); } } else { int rpc = params.getArgumentCount() > 1 ? 1 : 0; - RegionManager mgr = mod.getWorldGuard().getGlobalRegionManager().get(w); + RegionManager mgr = getWorldGuard().getGlobalRegionManager().get(w); region = mgr.getRegion(params.getArgument(rpc)); if (region == null && params.getArgument(rpc).equalsIgnoreCase("__global__")) { region = new GlobalProtectedRegion(params.getArgument(rpc)); @@ -200,4 +203,8 @@ public class RegionsCommand extends BukkitCommand implements IHelpDescribed { private String L(String msg, Object... args) { return mod.getPlugin().getLocale().trans(msg, args); } + + private WorldGuardPlugin getWorldGuard() { + return wg; + } } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/WorldGuardIntegration.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/WorldGuardIntegration.java new file mode 100644 index 0000000..779ed3f --- /dev/null +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/WorldGuardIntegration.java @@ -0,0 +1,34 @@ +package de.jaschastarke.minecraft.limitedcreative.regions; + +import org.bukkit.GameMode; +import org.bukkit.entity.Player; + +import de.jaschastarke.minecraft.limitedcreative.Hooks; +import de.jaschastarke.minecraft.limitedcreative.ModRegions; +import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.ApplicableRegions; +import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.FlagList; + +public class WorldGuardIntegration implements IWorldGuardIntegration { + private ModRegions mod; + + public WorldGuardIntegration(ModRegions mod) { + this.mod = mod; + } + + @Override + public void initFlagList() { + FlagList.addFlags(Flags.getList()); + } + + @Override + + public boolean isRegionOptional(Player player, GameMode tgm) { + ApplicableRegions rs = mod.getRegionManager().getRegionSet(player.getLocation()); + if (rs.allows(Flags.GAMEMODE_OPTIONAL)) { + if ((tgm == rs.getFlag(Flags.GAMEMODE, player)) || (tgm == Hooks.DefaultWorldGameMode.get(player.getWorld()))) + return true; + } + return false; + } + +} diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/worldguard/CustomRegionManager.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/worldguard/CustomRegionManager.java index bc4a3cc..5e5612e 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/worldguard/CustomRegionManager.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/worldguard/CustomRegionManager.java @@ -148,15 +148,19 @@ public class CustomRegionManager { } public WorldGuardPlugin getWorldGuard() { - return mod.getWorldGuard(); + return CustomRegionManager.this.getWorldGuard(); } } + + private WorldGuardPlugin getWorldGuard() { + return ((WorldGuardPlugin) mod.getPlugin().getServer().getPluginManager().getPlugin("WorldGuard")); + } public GlobalRegionManager getWGGlobalManager() { - return mod.getWorldGuard().getGlobalRegionManager(); + return getWorldGuard().getGlobalRegionManager(); } public RegionManager getWGManager(World world) { - return mod.getWorldGuard().getRegionManager(world); + return getWorldGuard().getRegionManager(world); } public String getRegionsHash(Location loc) { diff --git a/src/main/resources/lang/messages.properties b/src/main/resources/lang/messages.properties index 93394a0..ade321c 100644 --- a/src/main/resources/lang/messages.properties +++ b/src/main/resources/lang/messages.properties @@ -21,9 +21,17 @@ command.worldguard.available_flags: Available flags: command.worldguard.region_not_found: Could not find a region by that ID command.worldguard.world_not_found: Could not find a world by that name command.worldguard.flag_set: "The flag {0} was set" -command.worldguard.additional_flags: Additional flags: +command.worldguard.additional_flags: Additional flags: + +command.blockstate: LimitedCreative-BlockState-Command: modify blockstate database to prevent drops of selected blocks (requires WorldEdit) +command.blockstate.requires_worldedit: This command requires WorldEdit-Plugin +command.blockstate.worledit_selection_empty: Select a region with WorldEdit first +command.blockstate.command_updated: Successfully updated {0} blocks. +command.blockstate.command_failed: Failed to update blocks. See server.log for details. cmdblock.blocked: This command is blocked while in creative mode. +cmdblock.blocked.requires_worldedit: WorlEdit is required to use this command +cmdblock.blocked.not_console: This command can not be used from console exception.config.material_not_found: (Config) Material with name/id "{0}" was not found. exception.region.not_optional: You can not be {0} in that area @@ -45,8 +53,10 @@ blocked.break: You are not allowed to break this type of block blocked.region.piston: Moving {0} block out of creative area was blocked at {1} blocked.region.piston_in: Moving {0} block into creative area was blocked at {1} +block_state.warning.worldedit_sessionfactory_failed: Failed to hook into WorldEdit. WorldEdit-actions can't be traced. Error: 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 with WorldEdit by ''{1}'' on {3} +block_state.tool_info.command: This {0}-Block was manually set to {2}-mode via command 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