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.

This commit is contained in:
Dico200
2016-05-30 15:45:05 +02:00
parent 4e4acc6b3d
commit d00301ccc3

View File

@@ -1,12 +1,15 @@
#pylint: disable = F0401 #pylint: disable = F0401
from helpers import * from helpers import *
from time import time as now 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" inputs = open_json_file("damnspam", {}) # format "x;y;z;World"
accepted_inputs = ["WOOD_BUTTON", "STONE_BUTTON", "LEVER"] accepted_inputs = ["WOOD_BUTTON", "STONE_BUTTON", "LEVER"]
changing_input = False changing_input = False
removing_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(): 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") @hook.command("damnspam")
def on_dammnspam_command(sender, command, label, args): def on_dammnspam_command(sender, command, label, args):
global changing_input
plugin_header(sender, "DamnSpam") plugin_header(sender, "DamnSpam")
if not checkargs(sender, args, 1, 2): if not checkargs(sender, args, 1, 2):
msg(sender, "&c/damnspam <seconds> &e(Buttons/Levers)") msg(sender, "&c/damnspam <seconds> &e(Buttons/Levers)")
msg(sender, "&c/damnspam <seconds after off> <seconds after on> &e(Levers only)") msg(sender, "&c/damnspam <seconds after off> <seconds after on> &e(Levers only)")
return True return True
#Gittestlol #Gittestlol
if not is_creative(sender): 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 return True
# /damnspam <secs> # /damnspam <secs>
destroying_input = False # if both timeouts are 0, the plugin will attempt to remove the protection
if len(args) == 1: if len(args) == 1:
timeout_on = args[0] timeout_on = args[0]
try: try:
timeout_on = round(float(timeout_on), 2) timeout_on = round(float(timeout_on), 2)
timeout_off = timeout_on if timeout_on == 0:
if 60 >= timeout_on <= -2 or timeout_on == 0: destroying_input = True
msg(sender, "&cThe timeout must be within 0-60 or -1.") elif not is_acceptable_timeout(timeout_on):
msg(sender, "&cThe timeout must be -1 or within 0 and %d" % max_timeout)
return True return True
timeout_off = timeout_on
except ValueError: except ValueError:
msg(sender, "&cThe timeout must be a number") msg(sender, "&cThe timeout must be a number")
return True return True
@@ -60,12 +69,10 @@ def on_dammnspam_command(sender, command, label, args):
try: try:
timeout_on = round(float(timeout_on), 2) timeout_on = round(float(timeout_on), 2)
timeout_off = round(float(timeout_off), 2) timeout_off = round(float(timeout_off), 2)
if 60 >= timeout_on <= -2 or timeout_on == 0: if timeout_on == 0 and timeout_off == 0:
timeout_on = False destroying_input = True
if 60 >= timeout_off <= -2 or timeout_off == 0: elif not (is_acceptable_timeout(timeout_on) and is_acceptable_timeout(timeout_off)):
timeout_off = False msg(sender, "&cThe timeout must be -1 or within 0 and %d" % max_timeout)
if timeout_on == False or timeout_off == False:
msg(sender, "&cThe timeout must be within 0-60 or -1.")
return True return True
except ValueError: except ValueError:
msg(sender, "&cThe timeout must be a number") 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!") msg(sender, "&cPlease look at a button or lever while executing this command!")
return True 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 changing_input = True # this input already has a timeout
type_str = ttype.lower().replace("_", " ")
# test if player is allowed to build here # test if player is allowed to build here
test_event = BlockBreakEvent(target, sender) build_check = can_build(sender, target)
server.getPluginManager().callEvent(test_event)
changing_input = False changing_input = False
if test_event.isCancelled(): if not build_check:
msg(sender, "&cYou are not allowed to modify this %s" % str(target.getType()).lower()) msg(sender, "&cYou are not allowed to modify this %s" % type_str)
return True return True
# add block to inputs # 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() save_inputs()
msg(sender, "&aSuccessfully set a timeout for this %s." % ttype.lower().replace("_", " "))
return True return True
@hook.event("block.BlockBreakEvent", "normal") def check_block_break(break_event, block):
def on_block_break(event): if str(block.getType()) not in accepted_inputs:
global removing_input
if removing_input:
return return
sender = event.getPlayer() pos_str = location_str(block)
block = event.getBlock() if pos_str not in inputs:
btype = str(block.getType()).lower() return
if str(block.getType()) in accepted_inputs and not event.isCancelled(): sender = break_event.getPlayer()
pos_str = location_str(block) input_str = ("this %s" if block is break_event.getBlock() else "the %s attached to that block") % str(block.getType()).lower().replace("_", " ")
if inputs.get(pos_str): if not sender.isSneaking():
if sender.isSneaking(): msg(sender, "&cYou cannot destroy " + input_str)
# test if player is allowed to build here msg(sender, "&c&nSneak&c and break or set the timeout to 0 if you want to remove it.")
removing_input = True break_event.setCancelled(True)
test_event = BlockBreakEvent(block, sender) return
server.getPluginManager().callEvent(test_event) global removing_input
removing_input = False removing_input = True
if test_event.isCancelled(): success = can_build(sender, block)
event.setCancelled(True) removing_input = False
msg(sender, "&cYou are not allowed to remove this %s" % btype) if success:
return True del inputs[pos_str]
inputs.pop(pos_str) # remove save_inputs()
save_inputs() msg(sender, "&aSuccessfully removed %s!" % input_str)
msg(sender, "&eSuccessfully removed this %s!" % btype) else:
return True msg(sender, "&cYou are not allowed to remove " + input_str)
elif not changing_input: break_event.setCancelled(True)
event.setCancelled(True)
msg(sender, "&cYou cannot destroy this %s!" % btype)
msg(sender, "&c&nSneak&c and break if you want to remove it.") # a dict for levers and buttons, with a tuple of tuples as value. The tuples in the tuple represent
return True # 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") @hook.event("player.PlayerInteractEvent", "normal")
def on_interact(event): def on_interact(event):
if (str(event.getAction()) == "RIGHT_CLICK_BLOCK") and not event.isCancelled(): if (str(event.getAction()) == "RIGHT_CLICK_BLOCK") and not event.isCancelled():
sender = event.getPlayer() sender = event.getPlayer()
if sender.isSneaking():
return
block = event.getClickedBlock() 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) pos_str = location_str(block)
data = inputs.get(pos_str) data = inputs.get(pos_str)
if data: 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: if checktime == -1:
event.setCancelled(True) event.setCancelled(True)
msg(sender, "&cThis %s is locked permanently by /damnspam." % (btype)) msg(sender, "&cThis %s is locked permanently by /damnspam." % (btype))
elif data["last_time"] + checktime > now(): elif time_left > 0:
event.setCancelled(True) 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: else:
inputs[pos_str]["last_time"] = round(now(), 2) data["last_time"] = round(now(), 2)