summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDico200 <dico.karssiens@gmail.com>2016-05-30 15:45:05 +0200
committerDico200 <dico.karssiens@gmail.com>2016-05-30 15:45:05 +0200
commitd00301ccc3de42c6b66bf986e79ce84ca2c09d07 (patch)
tree48d36c7c4d4445e078664be5cfb239d768c07b4a
parent4e4acc6b3d26fe7b00231dc220b69f55dae34367 (diff)
Updated damnspam, made block breaking check attached levers and buttons, denied clicking now mentions timeout left, tweaked command slightly to perceive setting the timeout to 0 as removing it.
-rw-r--r--damnspam.py165
1 files changed, 108 insertions, 57 deletions
diff --git a/damnspam.py b/damnspam.py
index e9f9b84..a72c254 100644
--- a/damnspam.py
+++ b/damnspam.py
@@ -1,12 +1,15 @@
#pylint: disable = F0401
from helpers import *
from time import time as now
-import org.bukkit.event.block.BlockBreakEvent as BlockBreakEvent
+import org.bukkit.Material as Material
+import org.bukkit.block.BlockFace as BlockFace
inputs = open_json_file("damnspam", {}) # format "x;y;z;World"
accepted_inputs = ["WOOD_BUTTON", "STONE_BUTTON", "LEVER"]
changing_input = False
removing_input = False
+max_timeout = 240
+timeout_error_str = "&cThe timeout must be -1 or within 0 and %d" % max_timeout
def save_inputs():
@@ -26,29 +29,35 @@ def add_input(creator, block, timeout_off, timeout_on):
}
+def is_acceptable_timeout(timeout):
+ return (0 < timeout <= max_timeout) or timeout == -1
+
+
@hook.command("damnspam")
def on_dammnspam_command(sender, command, label, args):
- global changing_input
-
plugin_header(sender, "DamnSpam")
+
if not checkargs(sender, args, 1, 2):
msg(sender, "&c/damnspam <seconds> &e(Buttons/Levers)")
msg(sender, "&c/damnspam <seconds after off> <seconds after on> &e(Levers only)")
return True
#Gittestlol
if not is_creative(sender):
- msg(sender, "&cYou can only do this in Creative mode.")
+ msg(sender, "&cYou can only do this in Creative mode")
return True
# /damnspam <secs>
+ destroying_input = False # if both timeouts are 0, the plugin will attempt to remove the protection
if len(args) == 1:
timeout_on = args[0]
try:
timeout_on = round(float(timeout_on), 2)
- timeout_off = timeout_on
- if 60 >= timeout_on <= -2 or timeout_on == 0:
- msg(sender, "&cThe timeout must be within 0-60 or -1.")
+ if timeout_on == 0:
+ destroying_input = True
+ elif not is_acceptable_timeout(timeout_on):
+ msg(sender, "&cThe timeout must be -1 or within 0 and %d" % max_timeout)
return True
+ timeout_off = timeout_on
except ValueError:
msg(sender, "&cThe timeout must be a number")
return True
@@ -60,12 +69,10 @@ def on_dammnspam_command(sender, command, label, args):
try:
timeout_on = round(float(timeout_on), 2)
timeout_off = round(float(timeout_off), 2)
- if 60 >= timeout_on <= -2 or timeout_on == 0:
- timeout_on = False
- if 60 >= timeout_off <= -2 or timeout_off == 0:
- timeout_off = False
- if timeout_on == False or timeout_off == False:
- msg(sender, "&cThe timeout must be within 0-60 or -1.")
+ if timeout_on == 0 and timeout_off == 0:
+ destroying_input = True
+ elif not (is_acceptable_timeout(timeout_on) and is_acceptable_timeout(timeout_off)):
+ msg(sender, "&cThe timeout must be -1 or within 0 and %d" % max_timeout)
return True
except ValueError:
msg(sender, "&cThe timeout must be a number")
@@ -78,72 +85,116 @@ def on_dammnspam_command(sender, command, label, args):
msg(sender, "&cPlease look at a button or lever while executing this command!")
return True
- if location_str(target) in inputs:
+ global changing_input
+ target_loc_str = location_str(target)
+ if target_loc_str in inputs:
changing_input = True # this input already has a timeout
+
+ type_str = ttype.lower().replace("_", " ")
+
# test if player is allowed to build here
- test_event = BlockBreakEvent(target, sender)
- server.getPluginManager().callEvent(test_event)
+ build_check = can_build(sender, target)
changing_input = False
- if test_event.isCancelled():
- msg(sender, "&cYou are not allowed to modify this %s" % str(target.getType()).lower())
+ if not build_check:
+ msg(sender, "&cYou are not allowed to modify this %s" % type_str)
return True
# add block to inputs
- add_input(sender, target, timeout_off, timeout_on)
+ if destroying_input:
+ if target_loc_str not in inputs:
+ msg(sender, "&cThere is no timeout to remove on this %s (by setting the timeout to 0)" % type_str)
+ return True
+ del inputs[target_loc_str]
+ msg(sender, "&aSuccessfully removed the timeout for this %s" % type_str)
+ else:
+ add_input(sender, target, timeout_off, timeout_on)
+ msg(sender, "&aSuccessfully set a timeout for this %s" % type_str)
save_inputs()
- msg(sender, "&aSuccessfully set a timeout for this %s." % ttype.lower().replace("_", " "))
return True
-@hook.event("block.BlockBreakEvent", "normal")
-def on_block_break(event):
- global removing_input
-
- if removing_input:
+def check_block_break(break_event, block):
+ if str(block.getType()) not in accepted_inputs:
return
- sender = event.getPlayer()
- block = event.getBlock()
- btype = str(block.getType()).lower()
- if str(block.getType()) in accepted_inputs and not event.isCancelled():
- pos_str = location_str(block)
- if inputs.get(pos_str):
- if sender.isSneaking():
- # test if player is allowed to build here
- removing_input = True
- test_event = BlockBreakEvent(block, sender)
- server.getPluginManager().callEvent(test_event)
- removing_input = False
- if test_event.isCancelled():
- event.setCancelled(True)
- msg(sender, "&cYou are not allowed to remove this %s" % btype)
- return True
- inputs.pop(pos_str) # remove
- save_inputs()
- msg(sender, "&eSuccessfully removed this %s!" % btype)
- return True
- elif not changing_input:
- event.setCancelled(True)
- msg(sender, "&cYou cannot destroy this %s!" % btype)
- msg(sender, "&c&nSneak&c and break if you want to remove it.")
- return True
+ pos_str = location_str(block)
+ if pos_str not in inputs:
+ return
+ sender = break_event.getPlayer()
+ input_str = ("this %s" if block is break_event.getBlock() else "the %s attached to that block") % str(block.getType()).lower().replace("_", " ")
+ if not sender.isSneaking():
+ msg(sender, "&cYou cannot destroy " + input_str)
+ msg(sender, "&c&nSneak&c and break or set the timeout to 0 if you want to remove it.")
+ break_event.setCancelled(True)
+ return
+ global removing_input
+ removing_input = True
+ success = can_build(sender, block)
+ removing_input = False
+ if success:
+ del inputs[pos_str]
+ save_inputs()
+ msg(sender, "&aSuccessfully removed %s!" % input_str)
+ else:
+ msg(sender, "&cYou are not allowed to remove " + input_str)
+ break_event.setCancelled(True)
+
+
+# a dict for levers and buttons, with a tuple of tuples as value. The tuples in the tuple represent
+# the data values which the block must have if the block were placed towards the linked blockface to be affected.
+# The order is DOWN, UP, NORTH, SOUTH, WEST, EAST
+attached_blocks = {
+
+ Material.LEVER: ((0, 7, 8, 15), (5, 6, 13, 14), (4, 12), (3, 11), (2, 10), (1, 9)),
+ Material.STONE_BUTTON: ((0, 8), (5, 6, 7, 13, 14, 15), (4, 12), (3, 11), (2, 10), (1, 9)),
+ Material.WOOD_BUTTON: ((0, 8), (5, 6, 7, 13, 14, 15), (4, 12), (3, 11), (2, 10), (1, 9)),
+
+}
+
+# returns a generator containing the levers or buttons that would be broken if this block were broken
+def get_attached_blocks(block):
+ for i, face in ((0, BlockFace.DOWN), (1, BlockFace.UP), (2, BlockFace.NORTH), (3, BlockFace.SOUTH), (4, BlockFace.WEST), (5, BlockFace.EAST)):
+ side = block.getRelative(face)
+ dvalues = attached_blocks.get(side.getType())
+ if dvalues is not None and side.getData() in dvalues[i]:
+ yield side
+
+
+@hook.event("block.BlockBreakEvent", "highest")
+def on_block_break(event):
+ try:
+ if removing_input or changing_input or event.isCancelled():
+ return
+ block = event.getBlock()
+ check_block_break(event, event.getBlock())
+ for affected_block in get_attached_blocks(block):
+ check_block_break(event, affected_block)
+ except:
+ error(trace())
@hook.event("player.PlayerInteractEvent", "normal")
def on_interact(event):
if (str(event.getAction()) == "RIGHT_CLICK_BLOCK") and not event.isCancelled():
- sender = event.getPlayer()
+ sender = event.getPlayer()
+ if sender.isSneaking():
+ return
block = event.getClickedBlock()
- btype = str(block.getType()).lower()
- powered = (block.getData() & 0x8) == 0x8 if btype == "lever" else False # data > 7, but this is how bukkit does it
pos_str = location_str(block)
data = inputs.get(pos_str)
if data:
- checktime = data["timeout_on"] if powered else data["timeout_off"]
+ sender = event.getPlayer()
+ btype = str(block.getType()).lower().replace("_", " ")
+ if btype == "lever" and block.getData() < 8:
+ checktime = data["timeout_off"]
+ else:
+ checktime = data["timeout_on"]
+ time_left = data["last_time"] + checktime - now()
+
if checktime == -1:
event.setCancelled(True)
msg(sender, "&cThis %s is locked permanently by /damnspam." % (btype))
- elif data["last_time"] + checktime > now():
+ elif time_left > 0:
event.setCancelled(True)
- msg(sender, "&cThis %s has a damnspam timeout of %ss." % (btype, checktime))
+ msg(sender, "&cThis %s has a damnspam timeout of %.2fs, with %.2fs left." % (btype, checktime, time_left))
else:
- inputs[pos_str]["last_time"] = round(now(), 2)
+ data["last_time"] = round(now(), 2)