mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Merge branch 'confirm_destroy' of git://github.com/vlegoff/evennia into vlegoff-confirm_destroy
This commit is contained in:
commit
0dedda35e8
2 changed files with 61 additions and 14 deletions
|
|
@ -614,35 +614,37 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
|
|||
switches:
|
||||
override - The @destroy command will usually avoid accidentally
|
||||
destroying account objects. This switch overrides this safety.
|
||||
force - destroy without confirmation.
|
||||
examples:
|
||||
@destroy house, roof, door, 44-78
|
||||
@destroy 5-10, flower, 45
|
||||
@destroy/force north
|
||||
|
||||
Destroys one or many objects. If dbrefs are used, a range to delete can be
|
||||
given, e.g. 4-10. Also the end points will be deleted.
|
||||
given, e.g. 4-10. Also the end points will be deleted. This command
|
||||
displays a confirmation before destroying, to make sure of your choice.
|
||||
You can specify the /force switch to bypass this confirmation.
|
||||
"""
|
||||
|
||||
key = "@destroy"
|
||||
aliases = ["@delete", "@del"]
|
||||
locks = "cmd:perm(destroy) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
confirm = True # set to False to always bypass confirmation
|
||||
|
||||
def func(self):
|
||||
"Implements the command."
|
||||
|
||||
caller = self.caller
|
||||
delete = True
|
||||
|
||||
if not self.args or not self.lhslist:
|
||||
caller.msg("Usage: @destroy[/switches] [obj, obj2, obj3, [dbref-dbref],...]")
|
||||
return ""
|
||||
delete = False
|
||||
|
||||
def delobj(objname, byref=False):
|
||||
def delobj(obj):
|
||||
# helper function for deleting a single object
|
||||
string = ""
|
||||
obj = caller.search(objname)
|
||||
if not obj:
|
||||
self.caller.msg(" (Objects to destroy must either be local or specified with a unique #dbref.)")
|
||||
return ""
|
||||
objname = obj.name
|
||||
if not (obj.access(caller, "control") or obj.access(caller, 'delete')):
|
||||
return "\nYou don't have permission to delete %s." % objname
|
||||
|
|
@ -668,21 +670,55 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
|
|||
string += " Objects inside %s were moved to their homes." % objname
|
||||
return string
|
||||
|
||||
result = []
|
||||
objs = []
|
||||
for objname in self.lhslist:
|
||||
if not delete:
|
||||
continue
|
||||
|
||||
if '-' in objname:
|
||||
# might be a range of dbrefs
|
||||
dmin, dmax = [utils.dbref(part, reqhash=False)
|
||||
for part in objname.split('-', 1)]
|
||||
if dmin and dmax:
|
||||
for dbref in range(int(dmin), int(dmax + 1)):
|
||||
result.append(delobj("#" + str(dbref), True))
|
||||
obj = caller.search("#" + str(dbref))
|
||||
if obj:
|
||||
objs.append(obj)
|
||||
continue
|
||||
else:
|
||||
result.append(delobj(objname))
|
||||
obj = caller.search(objname)
|
||||
else:
|
||||
result.append(delobj(objname, True))
|
||||
if result:
|
||||
caller.msg("".join(result).strip())
|
||||
obj = caller.search(objname)
|
||||
|
||||
if obj is None:
|
||||
self.caller.msg(" (Objects to destroy must either be local or specified with a unique #dbref.)")
|
||||
elif obj not in objs:
|
||||
objs.append(obj)
|
||||
|
||||
if objs and ("force" not in self.switches and type(self).confirm):
|
||||
confirm = "Are you sure you want to destroy "
|
||||
if len(objs) == 1:
|
||||
confirm += objs[0].get_display_name(caller)
|
||||
elif len(objs) < 5:
|
||||
confirm += ", ".join([obj.get_display_name(caller) for obj in objs])
|
||||
else:
|
||||
confirm += ", ".join(["#{}".format(obj.id) for obj in objs])
|
||||
confirm += " (yes/no)?"
|
||||
answer = yield(confirm)
|
||||
while answer.strip().lower() not in ("y", "yes", "n", "no"):
|
||||
answer = yield(confirm)
|
||||
|
||||
if answer.strip().lower() in ("n", "no"):
|
||||
caller.msg("Cancelled: no object was destroyed.")
|
||||
delete = False
|
||||
|
||||
if delete:
|
||||
results = []
|
||||
for obj in objs:
|
||||
results.append(delobj(obj))
|
||||
|
||||
if results:
|
||||
caller.msg("".join(results).strip())
|
||||
|
||||
|
||||
class CmdDig(ObjManipCommand):
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ main test suite started with
|
|||
"""
|
||||
|
||||
import re
|
||||
import types
|
||||
|
||||
from django.conf import settings
|
||||
from mock import Mock
|
||||
|
|
@ -73,8 +74,12 @@ class CommandTest(EvenniaTest):
|
|||
receiver.msg = Mock()
|
||||
cmdobj.at_pre_cmd()
|
||||
cmdobj.parse()
|
||||
cmdobj.func()
|
||||
ret = cmdobj.func()
|
||||
if isinstance(ret, types.GeneratorType):
|
||||
ret.next()
|
||||
cmdobj.at_post_cmd()
|
||||
except StopIteration:
|
||||
pass
|
||||
except InterruptCommand:
|
||||
pass
|
||||
finally:
|
||||
|
|
@ -250,7 +255,10 @@ class TestBuilding(CommandTest):
|
|||
self.call(building.CmdDesc(), "Obj2=TestDesc", "The description was set on Obj2(#5).")
|
||||
|
||||
def test_wipe(self):
|
||||
confirm = building.CmdDestroy.confirm
|
||||
building.CmdDestroy.confirm = False
|
||||
self.call(building.CmdDestroy(), "Obj", "Obj was destroyed.")
|
||||
building.CmdDestroy.confirm = confirm
|
||||
|
||||
def test_dig(self):
|
||||
self.call(building.CmdDig(), "TestRoom1=testroom;tr,back;b", "Created room TestRoom1")
|
||||
|
|
@ -330,7 +338,10 @@ class TestBatchProcess(CommandTest):
|
|||
# cannot test batchcode here, it must run inside the server process
|
||||
self.call(batchprocess.CmdBatchCommands(), "example_batch_cmds", "Running Batchcommand processor Automatic mode for example_batch_cmds")
|
||||
# we make sure to delete the button again here to stop the running reactor
|
||||
confirm = building.CmdDestroy.confirm
|
||||
building.CmdDestroy.confirm = False
|
||||
self.call(building.CmdDestroy(), "button", "button was destroyed.")
|
||||
building.CmdDestroy.confirm = confirm
|
||||
|
||||
|
||||
class CmdInterrupt(Command):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue