mirror of
https://github.com/evennia/evennia.git
synced 2026-03-25 09:16:32 +01:00
Merge branch 'develop' into develop-muxcommand
This commit is contained in:
commit
111b1c5136
10 changed files with 149 additions and 41 deletions
|
|
@ -594,6 +594,9 @@ class CmdDesc(COMMAND_DEFAULT_CLASS):
|
|||
if not obj:
|
||||
return
|
||||
|
||||
if not (obj.access(self.caller, 'control') or obj.access(self.caller, 'edit')):
|
||||
self.caller.msg("You don't have permission to edit the description of %s." % obj.key)
|
||||
|
||||
self.caller.db.evmenu_target = obj
|
||||
# launch the editor
|
||||
EvEditor(self.caller, loadfunc=_desc_load, savefunc=_desc_save,
|
||||
|
|
@ -623,7 +626,7 @@ class CmdDesc(COMMAND_DEFAULT_CLASS):
|
|||
if not obj:
|
||||
return
|
||||
desc = self.args
|
||||
if obj.access(caller, "edit"):
|
||||
if (obj.access(self.caller, 'control') or obj.access(self.caller, 'edit')):
|
||||
obj.db.desc = desc
|
||||
caller.msg("The description was set on %s." % obj.get_display_name(caller))
|
||||
else:
|
||||
|
|
@ -1646,6 +1649,10 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
result = []
|
||||
if "edit" in self.switches:
|
||||
# edit in the line editor
|
||||
if not (obj.access(self.caller, 'control') or obj.access(self.caller, 'edit')):
|
||||
caller.msg("You don't have permission to edit %s." % obj.key)
|
||||
return
|
||||
|
||||
if len(attrs) > 1:
|
||||
caller.msg("The Line editor can only be applied "
|
||||
"to one attribute at a time.")
|
||||
|
|
@ -1666,12 +1673,18 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
return
|
||||
else:
|
||||
# deleting the attribute(s)
|
||||
if not (obj.access(self.caller, 'control') or obj.access(self.caller, 'edit')):
|
||||
caller.msg("You don't have permission to edit %s." % obj.key)
|
||||
return
|
||||
for attr in attrs:
|
||||
if not self.check_attr(obj, attr):
|
||||
continue
|
||||
result.append(self.rm_attr(obj, attr))
|
||||
else:
|
||||
# setting attribute(s). Make sure to convert to real Python type before saving.
|
||||
if not (obj.access(self.caller, 'control') or obj.access(self.caller, 'edit')):
|
||||
caller.msg("You don't have permission to edit %s." % obj.key)
|
||||
return
|
||||
for attr in attrs:
|
||||
if not self.check_attr(obj, attr):
|
||||
continue
|
||||
|
|
@ -1905,9 +1918,16 @@ class CmdLock(ObjManipCommand):
|
|||
obj = caller.search(objname)
|
||||
if not obj:
|
||||
return
|
||||
if not (obj.access(caller, 'control') or obj.access(caller, "edit")):
|
||||
has_control_access = obj.access(caller, 'control')
|
||||
if access_type == 'control' and not has_control_access:
|
||||
# only allow to change 'control' access if you have 'control' access already
|
||||
caller.msg("You need 'control' access to change this type of lock.")
|
||||
return
|
||||
|
||||
if not has_control_access or obj.access(caller, "edit"):
|
||||
caller.msg("You are not allowed to do that.")
|
||||
return
|
||||
|
||||
lockdef = obj.locks.get(access_type)
|
||||
|
||||
if lockdef:
|
||||
|
|
@ -2386,7 +2406,7 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Examples:
|
||||
@tel Limbo
|
||||
@tel/quiet box Limbo
|
||||
@tel/quiet box = Limbo
|
||||
@tel/tonone box
|
||||
|
||||
Switches:
|
||||
|
|
@ -2402,7 +2422,8 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS):
|
|||
loc - teleport object to the target's location instead of its contents
|
||||
|
||||
Teleports an object somewhere. If no object is given, you yourself
|
||||
is teleported to the target location. """
|
||||
is teleported to the target location.
|
||||
"""
|
||||
key = "@tel"
|
||||
aliases = "@teleport"
|
||||
options = ("quiet", "intoexit", "tonone", "loc")
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ command method rather than caller.msg().
|
|||
|
||||
from evennia.commands.cmdset import CmdSet
|
||||
from evennia.commands.default import help, comms, admin, system
|
||||
from evennia.commands.default import building, account
|
||||
from evennia.commands.default import building, account, general
|
||||
|
||||
|
||||
class AccountCmdSet(CmdSet):
|
||||
|
|
@ -39,6 +39,9 @@ class AccountCmdSet(CmdSet):
|
|||
self.add(account.CmdColorTest())
|
||||
self.add(account.CmdQuell())
|
||||
|
||||
# nicks
|
||||
self.add(general.CmdNick())
|
||||
|
||||
# testing
|
||||
self.add(building.CmdExamine())
|
||||
|
||||
|
|
|
|||
|
|
@ -143,14 +143,14 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
return re.sub(r"(\$[0-9]+|\*|\?|\[.+?\])", r"|Y\1|n", string)
|
||||
|
||||
caller = self.caller
|
||||
account = self.caller.account or caller
|
||||
switches = self.switches
|
||||
nicktypes = [switch for switch in switches if switch in (
|
||||
"object", "account", "inputline")] or ["inputline"]
|
||||
nicktypes = [switch for switch in switches if switch in ("object", "account", "inputline")]
|
||||
specified_nicktype = bool(nicktypes)
|
||||
nicktypes = nicktypes if specified_nicktype else ["inputline"]
|
||||
|
||||
nicklist = (utils.make_iter(caller.nicks.get(category="inputline", return_obj=True) or []) +
|
||||
utils.make_iter(caller.nicks.get(category="object", return_obj=True) or []) +
|
||||
utils.make_iter(account.nicks.get(category="account", return_obj=True) or []))
|
||||
utils.make_iter(caller.nicks.get(category="account", return_obj=True) or []))
|
||||
|
||||
if 'list' in switches or self.cmdstring in ("nicks", "@nicks"):
|
||||
|
||||
|
|
@ -173,29 +173,99 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
if 'delete' in switches or 'del' in switches:
|
||||
if not self.args or not self.lhs:
|
||||
caller.msg("usage nick/delete #num ('nicks' for list)")
|
||||
caller.msg("usage nick/delete <nick> or <#num> ('nicks' for list)")
|
||||
return
|
||||
# see if a number was given
|
||||
arg = self.args.lstrip("#")
|
||||
oldnicks = []
|
||||
if arg.isdigit():
|
||||
# we are given a index in nicklist
|
||||
delindex = int(arg)
|
||||
if 0 < delindex <= len(nicklist):
|
||||
oldnick = nicklist[delindex - 1]
|
||||
_, _, old_nickstring, old_replstring = oldnick.value
|
||||
oldnicks.append(nicklist[delindex - 1])
|
||||
else:
|
||||
caller.msg("Not a valid nick index. See 'nicks' for a list.")
|
||||
return
|
||||
nicktype = oldnick.category
|
||||
nicktypestr = "%s-nick" % nicktype.capitalize()
|
||||
else:
|
||||
if not specified_nicktype:
|
||||
nicktypes = ("object", "account", "inputline")
|
||||
for nicktype in nicktypes:
|
||||
oldnicks.append(caller.nicks.get(arg, category=nicktype, return_obj=True))
|
||||
|
||||
if nicktype == "account":
|
||||
account.nicks.remove(old_nickstring, category=nicktype)
|
||||
else:
|
||||
oldnicks = [oldnick for oldnick in oldnicks if oldnick]
|
||||
if oldnicks:
|
||||
for oldnick in oldnicks:
|
||||
nicktype = oldnick.category
|
||||
nicktypestr = "%s-nick" % nicktype.capitalize()
|
||||
_, _, old_nickstring, old_replstring = oldnick.value
|
||||
caller.nicks.remove(old_nickstring, category=nicktype)
|
||||
caller.msg("%s removed: '|w%s|n' -> |w%s|n." % (
|
||||
nicktypestr, old_nickstring, old_replstring))
|
||||
return
|
||||
caller.msg("%s removed: '|w%s|n' -> |w%s|n." % (
|
||||
nicktypestr, old_nickstring, old_replstring))
|
||||
else:
|
||||
caller.msg("No matching nicks to remove.")
|
||||
return
|
||||
|
||||
if not self.rhs and self.lhs:
|
||||
# check what a nick is set to
|
||||
strings = []
|
||||
if not specified_nicktype:
|
||||
nicktypes = ("object", "account", "inputline")
|
||||
for nicktype in nicktypes:
|
||||
nicks = utils.make_iter(caller.nicks.get(category=nicktype, return_obj=True))
|
||||
for nick in nicks:
|
||||
_, _, nick, repl = nick.value
|
||||
if nick.startswith(self.lhs):
|
||||
strings.append("{}-nick: '{}' -> '{}'".format(
|
||||
nicktype.capitalize(), nick, repl))
|
||||
if strings:
|
||||
caller.msg("\n".join(strings))
|
||||
else:
|
||||
caller.msg("No nicks found matching '{}'".format(self.lhs))
|
||||
return
|
||||
|
||||
if not self.rhs and self.lhs:
|
||||
# check what a nick is set to
|
||||
strings = []
|
||||
if not specified_nicktype:
|
||||
nicktypes = ("object", "account", "inputline")
|
||||
for nicktype in nicktypes:
|
||||
if nicktype == "account":
|
||||
obj = account
|
||||
else:
|
||||
obj = caller
|
||||
nicks = utils.make_iter(obj.nicks.get(category=nicktype, return_obj=True))
|
||||
for nick in nicks:
|
||||
_, _, nick, repl = nick.value
|
||||
if nick.startswith(self.lhs):
|
||||
strings.append("{}-nick: '{}' -> '{}'".format(
|
||||
nicktype.capitalize(), nick, repl))
|
||||
if strings:
|
||||
caller.msg("\n".join(strings))
|
||||
else:
|
||||
caller.msg("No nicks found matching '{}'".format(self.lhs))
|
||||
return
|
||||
|
||||
if not self.rhs and self.lhs:
|
||||
# check what a nick is set to
|
||||
strings = []
|
||||
if not specified_nicktype:
|
||||
nicktypes = ("object", "account", "inputline")
|
||||
for nicktype in nicktypes:
|
||||
if nicktype == "account":
|
||||
obj = account
|
||||
else:
|
||||
obj = caller
|
||||
nicks = utils.make_iter(obj.nicks.get(category=nicktype, return_obj=True))
|
||||
for nick in nicks:
|
||||
_, _, nick, repl = nick.value
|
||||
if nick.startswith(self.lhs):
|
||||
strings.append("{}-nick: '{}' -> '{}'".format(
|
||||
nicktype.capitalize(), nick, repl))
|
||||
if strings:
|
||||
caller.msg("\n".join(strings))
|
||||
else:
|
||||
caller.msg("No nicks found matching '{}'".format(self.lhs))
|
||||
return
|
||||
|
||||
if not self.args or not self.lhs:
|
||||
caller.msg("Usage: nick[/switches] nickname = [realname]")
|
||||
|
|
@ -214,16 +284,11 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
errstring = ""
|
||||
string = ""
|
||||
for nicktype in nicktypes:
|
||||
if nicktype == "account":
|
||||
obj = account
|
||||
else:
|
||||
obj = caller
|
||||
|
||||
nicktypestr = "%s-nick" % nicktype.capitalize()
|
||||
old_nickstring = None
|
||||
old_replstring = None
|
||||
|
||||
oldnick = obj.nicks.get(key=nickstring, category=nicktype, return_obj=True)
|
||||
oldnick = caller.nicks.get(key=nickstring, category=nicktype, return_obj=True)
|
||||
if oldnick:
|
||||
_, _, old_nickstring, old_replstring = oldnick.value
|
||||
if replstring:
|
||||
|
|
@ -238,7 +303,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
else:
|
||||
string += "\n%s '|w%s|n' mapped to '|w%s|n'." % (nicktypestr, nickstring, replstring)
|
||||
try:
|
||||
obj.nicks.add(nickstring, replstring, category=nicktype)
|
||||
caller.nicks.add(nickstring, replstring, category=nicktype)
|
||||
except NickTemplateInvalid:
|
||||
caller.msg("You must use the same $-markers both in the nick and in the replacement.")
|
||||
return
|
||||
|
|
|
|||
|
|
@ -132,8 +132,8 @@ class TestGeneral(CommandTest):
|
|||
self.call(general.CmdNick(), "/object testalias = testaliasedstring3",
|
||||
"Objectnick 'testalias' mapped to 'testaliasedstring3'.")
|
||||
self.assertEqual(u"testaliasedstring1", self.char1.nicks.get("testalias"))
|
||||
self.assertEqual(None, self.char1.nicks.get("testalias", category="account"))
|
||||
self.assertEqual(u"testaliasedstring2", self.char1.account.nicks.get("testalias", category="account"))
|
||||
self.assertEqual(u"testaliasedstring2", self.char1.nicks.get("testalias", category="account"))
|
||||
self.assertEqual(None, self.char1.account.nicks.get("testalias", category="account"))
|
||||
self.assertEqual(u"testaliasedstring3", self.char1.nicks.get("testalias", category="object"))
|
||||
|
||||
def test_get_and_drop(self):
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ class ChannelHandler(object):
|
|||
"""
|
||||
The ChannelHandler manages all active in-game channels and
|
||||
dynamically creates channel commands for users so that they can
|
||||
just give the channek's key or alias to write to it. Whenever a
|
||||
just give the channel's key or alias to write to it. Whenever a
|
||||
new channel is created in the database, the update() method on
|
||||
this handler must be called to sync it with the database (this is
|
||||
done automatically if creating the channel with
|
||||
|
|
|
|||
|
|
@ -527,7 +527,6 @@ class SubscriptionHandler(object):
|
|||
for subscriber in make_iter(entity):
|
||||
if subscriber:
|
||||
clsname = subscriber.__dbclass__.__name__
|
||||
print("subscriber:", subscriber, clsname) # DEBUG
|
||||
# chooses the right type
|
||||
if clsname == "ObjectDB":
|
||||
self.obj.db_object_subscriptions.add(subscriber)
|
||||
|
|
@ -585,9 +584,7 @@ class SubscriptionHandler(object):
|
|||
for obj in self.all():
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
try:
|
||||
if hasattr(obj, 'account'):
|
||||
if not obj.account:
|
||||
continue
|
||||
if hasattr(obj, 'account') and obj.account:
|
||||
obj = obj.account
|
||||
if not obj.is_connected:
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -210,6 +210,14 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
def sessions(self):
|
||||
return ObjectSessionHandler(self)
|
||||
|
||||
@property
|
||||
def is_connected(self):
|
||||
# we get an error for objects subscribed to channels without this
|
||||
if self.account: # seems sane to pass on the account
|
||||
return self.account.is_connected
|
||||
else:
|
||||
return False
|
||||
|
||||
@property
|
||||
def has_account(self):
|
||||
"""
|
||||
|
|
@ -553,6 +561,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
obj.at_msg_send(text=text, to_obj=self, **kwargs)
|
||||
except Exception:
|
||||
logger.log_trace()
|
||||
kwargs["options"] = options
|
||||
try:
|
||||
if not self.at_msg_receive(text=text, **kwargs):
|
||||
# if at_msg_receive returns false, we abort message to this object
|
||||
|
|
@ -560,7 +569,6 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
except Exception:
|
||||
logger.log_trace()
|
||||
|
||||
kwargs["options"] = options
|
||||
|
||||
if text and not (isinstance(text, basestring) or isinstance(text, tuple)):
|
||||
# sanitize text before sending across the wire
|
||||
|
|
|
|||
|
|
@ -282,6 +282,8 @@ class AttributeHandler(object):
|
|||
"attribute__db_attrtype": self._attrtype,
|
||||
"attribute__db_key__iexact": key.lower(),
|
||||
"attribute__db_category__iexact": category.lower() if category else None}
|
||||
if not self.obj.pk:
|
||||
return []
|
||||
conn = getattr(self.obj, self._m2m_fieldname).through.objects.filter(**query)
|
||||
if conn:
|
||||
attr = conn[0].attribute
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import shlex
|
|||
from django.db.models import Q
|
||||
from evennia.utils import idmapper
|
||||
from evennia.utils.utils import make_iter, variable_from_module, to_unicode
|
||||
from evennia.typeclasses.attributes import Attribute
|
||||
from evennia.typeclasses.tags import Tag
|
||||
|
||||
__all__ = ("TypedObjectManager", )
|
||||
_GA = object.__getattribute__
|
||||
|
|
@ -56,17 +58,19 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
dbmodel = self.model.__dbclass__.__name__.lower()
|
||||
query = [("attribute__db_attrtype", attrtype), ("attribute__db_model", dbmodel)]
|
||||
if obj:
|
||||
query.append(("%s__id" % self.model.__name__.lower(), obj.id))
|
||||
query.append(("%s__id" % self.model.__dbclass__.__name__.lower(), obj.id))
|
||||
if key:
|
||||
query.append(("attribute__db_key", key))
|
||||
if category:
|
||||
query.append(("attribute__db_category", category))
|
||||
if strvalue:
|
||||
query.append(("attribute__db_strvalue", strvalue))
|
||||
elif value:
|
||||
# strvalue and value are mutually exclusive
|
||||
if value:
|
||||
# no reason to make strvalue/value mutually exclusive at this level
|
||||
query.append(("attribute__db_value", value))
|
||||
return [th.attribute for th in self.model.db_attributes.through.objects.filter(**dict(query))]
|
||||
return Attribute.objects.filter(
|
||||
pk__in=self.model.db_attributes.through.objects.filter(
|
||||
**dict(query)).values_list("attribute_id", flat=True))
|
||||
|
||||
def get_nick(self, key=None, category=None, value=None, strvalue=None, obj=None):
|
||||
"""
|
||||
|
|
@ -189,7 +193,9 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
query.append(("tag__db_key", key))
|
||||
if category:
|
||||
query.append(("tag__db_category", category))
|
||||
return [th.tag for th in self.model.db_tags.through.objects.filter(**dict(query))]
|
||||
return Tag.objects.filter(
|
||||
pk__in=self.model.db_tags.through.objects.filter(
|
||||
**dict(query)).values_list("tag_id", flat=True))
|
||||
|
||||
def get_permission(self, key=None, category=None, obj=None):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ JQuery available.
|
|||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
if(!window.jQuery) {
|
||||
document.write("<div class='err'>jQuery library not found or the online version could not be reached.</div>");
|
||||
document.write("<div class='err'>jQuery library not found or the online version could not be reached. Check so Javascript is not blocked in your browser.</div>");
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
@ -57,6 +57,12 @@ JQuery available.
|
|||
{% endblock %}
|
||||
|
||||
<script src="https://cdn.rawgit.com/ejci/favico.js/master/favico-0.3.10.min.js" language="javascript" type="text/javascript" charset="utf-8"></script>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
if(!window.Favico) {
|
||||
document.write("<div class='err'>Favico.js library not found or the online version could not be reached. Check so Javascript is not blocked in your browser.</div>");
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue