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
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)