Added sign chest protection (needed it for my server). Just put [Lock] on the first line and names on the next three. The first name line must be the sign creator's, so you can track who made what. Friend lists are not yet supported. People with names longer than 15 characters (I believe 16 is the max.) are out of luck.

This commit is contained in:
sk89q 2011-04-11 10:13:42 -07:00
parent a5a5f7e24a
commit afd3cbd311
5 changed files with 232 additions and 0 deletions

View File

@ -0,0 +1,125 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
/**
* Utility class for sign chest protection.
*
* @author sk89q
*/
public class SignChestProtection {
public boolean isProtected(Block block, Player player) {
if (isChest(block.getType())) {
Block below = block.getRelative(0, -1, 0);
return isProtectedSignAround(below, player);
} else if (block.getType() == Material.SIGN_POST) {
return isProtectedSignAndChestBinary(block, player);
} else {
Block above = block.getRelative(0, 1, 0);
Boolean res = isProtectedSign(above, player);
if (res != null) return res;
return false;
}
}
private boolean isProtectedSignAround(Block searchBlock, Player player) {
Block side;
Boolean res;
side = searchBlock;
res = isProtectedSign(side, player);
if (res != null) return res;
side = searchBlock.getRelative(-1, 0, 0);
res = isProtectedSignAndChest(side, player);
if (res != null) return res;
side = searchBlock.getRelative(1, 0, 0);
res = isProtectedSignAndChest(side, player);
if (res != null) return res;
side = searchBlock.getRelative(0, 0, -1);
res = isProtectedSignAndChest(side, player);
if (res != null) return res;
side = searchBlock.getRelative(0, 0, 1);
res = isProtectedSignAndChest(side, player);
if (res != null) return res;
return false;
}
private Boolean isProtectedSign(Sign sign, Player player) {
if (sign.getLine(0).equalsIgnoreCase("[Lock]")) {
if (player == null) { // No player, no access
return true;
}
String name = player.getName();
if (name.equalsIgnoreCase(sign.getLine(1).trim())
|| name.equalsIgnoreCase(sign.getLine(2).trim())
|| name.equalsIgnoreCase(sign.getLine(3).trim())) {
return false;
}
// No access!
return true;
}
return null;
}
private Boolean isProtectedSign(Block block, Player player) {
BlockState state = block.getState();
if (state == null || !(state instanceof Sign)) {
return null;
}
return isProtectedSign((Sign) state, player);
}
private Boolean isProtectedSignAndChest(Block block, Player player) {
if (!isChest(block.getRelative(0, 1, 0).getType())) {
return null;
}
return isProtectedSign(block, player);
}
private boolean isProtectedSignAndChestBinary(Block block, Player player) {
Boolean res = isProtectedSignAndChest(block, player);
if (res == null || res == false) {
return false;
}
return true;
}
private boolean isChest(Material material) {
return material == Material.CHEST
|| material == Material.DISPENSER
|| material == Material.FURNACE
|| material == Material.BURNING_FURNACE;
}
}

View File

@ -31,7 +31,9 @@
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.block.Block;
import org.bukkit.entity.CreatureType;
import org.bukkit.entity.Player;
import org.bukkit.util.config.Configuration;
/**
@ -52,6 +54,7 @@ public class WorldConfiguration {
private File blacklistFile;
private Blacklist blacklist;
private SignChestProtection chestProtection = new SignChestProtection();
/* Configuration data start */
public boolean fireSpreadDisableToggle;
@ -97,6 +100,7 @@ public class WorldConfiguration {
public boolean claimOnlyInsideExistingRegions;
public int maxRegionCountPerPlayer;
public boolean antiWolfDumbness;
public boolean signChestProtection;
/* Configuration data end */
@ -169,6 +173,8 @@ private void loadConfiguration() {
disableSuffocationDamage = config.getBoolean("player-damage.disable-suffocation-damage", false);
disableContactDamage = config.getBoolean("player-damage.disable-contact-damage", false);
teleportOnSuffocation = config.getBoolean("player-damage.teleport-on-suffocation", false);
signChestProtection = config.getBoolean("chest-protection.enable", false);
useRegions = config.getBoolean("regions.enable", true);
highFreqFlags = config.getBoolean("regions.high-frequency-flags", false);
@ -288,5 +294,22 @@ public Blacklist getBlacklist() {
public String getWorldName() {
return this.worldName;
}
public boolean isChestProtected(Block block, Player player) {
if (!signChestProtection) {
return false;
}
if (plugin.hasPermission(player, "worldguard.chest-protection.override")) {
return false;
}
return chestProtection.isProtected(block, player);
}
public boolean isChestProtected(Block block) {
if (!signChestProtection) {
return false;
}
return chestProtection.isProtected(block, null);
}
}

View File

@ -25,6 +25,7 @@
import org.bukkit.plugin.PluginManager;
import org.bukkit.block.Block;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.World;
import org.bukkit.event.block.*;
@ -62,6 +63,7 @@ public void registerEvents() {
pm.registerEvent(Event.Type.BLOCK_PHYSICS, this, Priority.Normal, plugin);
pm.registerEvent(Event.Type.BLOCK_PLACE, this, Priority.High, plugin);
pm.registerEvent(Event.Type.BLOCK_BURN, this, Priority.High, plugin);
pm.registerEvent(Event.Type.SIGN_CHANGE, this, Priority.High, plugin);
pm.registerEvent(Event.Type.REDSTONE_CHANGE, this, Priority.High, plugin);
}
@ -116,6 +118,12 @@ public void onBlockBreak(BlockBreakEvent event) {
return;
}
}
if (wcfg.isChestProtected(event.getBlock(), player)) {
player.sendMessage(ChatColor.DARK_RED + "The chest is protected.");
event.setCancelled(true);
return;
}
}
/**
@ -449,6 +457,60 @@ public void onBlockRedstoneChange(BlockRedstoneEvent event) {
}
}
/**
* Called when a sign is changed.
*/
@Override
public void onSignChange(SignChangeEvent event) {
Player player = event.getPlayer();
WorldConfiguration wcfg = getWorldConfig(player);
if (wcfg.signChestProtection) {
if (event.getLine(0).equalsIgnoreCase("[Lock]")) {
if (event.getBlock().getType() != Material.SIGN_POST) {
player.sendMessage(ChatColor.RED
+ "The [Lock] sign must be a sign post, not a wall sign.");
dropSign(event.getBlock());
event.setCancelled(true);
return;
} else if (!event.getLine(1).equalsIgnoreCase(player.getName())) {
player.sendMessage(ChatColor.RED
+ "The first owner line must be your name.");
dropSign(event.getBlock());
event.setCancelled(true);
return;
} else {
event.setLine(1, "[Lock]");
player.sendMessage(ChatColor.YELLOW
+ "A chest or double chest above is now protected.");
}
}
} else {
if (event.getLine(0).equalsIgnoreCase("[Lock]")) {
player.sendMessage(ChatColor.RED
+ "WorldGuard's sign chest protection is disabled.");
dropSign(event.getBlock());
event.setCancelled(true);
return;
}
}
}
/**
* Drops a sign item and removes a sign.
*
* @param block
*/
private void dropSign(Block block) {
block.setTypeId(0);
block.getWorld().dropItemNaturally(block.getLocation(),
new ItemStack(Material.SIGN));
}
/**
* Remove water around a sponge.
*

View File

@ -20,6 +20,7 @@
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import org.bukkit.block.Block;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.Event;
import org.bukkit.plugin.PluginManager;
@ -324,6 +325,15 @@ public void onEntityExplode(EntityExplodeEvent event) {
}
}
}
if (wcfg.signChestProtection) {
for (Block block : event.blockList()) {
if (wcfg.isChestProtected(block)) {
event.setCancelled(true);
return;
}
}
}
}
@Override

View File

@ -243,6 +243,18 @@ public void handleBlockRightClick(PlayerInteractEvent event) {
}
}
if ((block.getType() == Material.CHEST
|| block.getType() == Material.DISPENSER
|| block.getType() == Material.FURNACE
|| block.getType() == Material.BURNING_FURNACE)) {
if (wcfg.isChestProtected(block, player)) {
player.sendMessage(ChatColor.DARK_RED + "The chest is protected.");
event.setCancelled(true);
return;
}
}
/*if (wcfg.useRegions && wcfg.useiConomy && cfg.getiConomy() != null
&& (type == Material.SIGN_POST || type == Material.SIGN || type == Material.WALL_SIGN)) {
BlockState block = blockClicked.getState();