From c5e0c2321b3e54ccd3661787a35d09fab772eb4c Mon Sep 17 00:00:00 2001 From: arumford Date: Wed, 7 Feb 2018 14:22:38 -0600 Subject: [PATCH 01/12] typo in docstring. --- evennia/comms/channelhandler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evennia/comms/channelhandler.py b/evennia/comms/channelhandler.py index 02c9e1929..058b7d9ba 100644 --- a/evennia/comms/channelhandler.py +++ b/evennia/comms/channelhandler.py @@ -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 From 11c9d60111076d7b44ae44d4baf2121136dc66c4 Mon Sep 17 00:00:00 2001 From: Nicholas Matlaga Date: Tue, 13 Feb 2018 12:49:55 -0500 Subject: [PATCH 02/12] Change if statement to better handle objects; move options dict before at_msg_receive call to allow channels to be known in hook --- evennia/comms/models.py | 4 +--- evennia/objects/objects.py | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/evennia/comms/models.py b/evennia/comms/models.py index b1a5a37ed..c358cf352 100644 --- a/evennia/comms/models.py +++ b/evennia/comms/models.py @@ -584,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 diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index 5531b7f85..b55cd0962 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -519,6 +519,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 @@ -526,7 +527,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 From fad008d66024267e683e14d16e1c8358d3287622 Mon Sep 17 00:00:00 2001 From: Nicholas Matlaga Date: Tue, 13 Feb 2018 12:54:03 -0500 Subject: [PATCH 03/12] add in is_connected property to base objects --- evennia/objects/objects.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index b55cd0962..d4ce39097 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -206,6 +206,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): """ From 9d3d627e220ad054e728884b36038bd3d5014b2d Mon Sep 17 00:00:00 2001 From: Griatch Date: Wed, 21 Feb 2018 20:18:33 +0100 Subject: [PATCH 04/12] Catch the case of a prematurely deleted guest account. Resolves #1500. --- evennia/typeclasses/attributes.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/evennia/typeclasses/attributes.py b/evennia/typeclasses/attributes.py index 84a21c0c2..3f8b4cd74 100644 --- a/evennia/typeclasses/attributes.py +++ b/evennia/typeclasses/attributes.py @@ -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 From 6101ee0a1cc83db86be155ddfbfe4a92fb07a41b Mon Sep 17 00:00:00 2001 From: Griatch Date: Wed, 21 Feb 2018 20:34:29 +0100 Subject: [PATCH 05/12] Add warning if Favico.js library is not reachable --- evennia/web/webclient/templates/webclient/base.html | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/evennia/web/webclient/templates/webclient/base.html b/evennia/web/webclient/templates/webclient/base.html index 373ff0f35..f5f47b230 100644 --- a/evennia/web/webclient/templates/webclient/base.html +++ b/evennia/web/webclient/templates/webclient/base.html @@ -25,7 +25,7 @@ JQuery available. @@ -57,6 +57,12 @@ JQuery available. {% endblock %} + + From 5b96b09bcafd682542def7b14824dc5f63578251 Mon Sep 17 00:00:00 2001 From: Griatch Date: Thu, 1 Mar 2018 20:13:36 +0100 Subject: [PATCH 06/12] Fix bug in accessing attribute through manager --- evennia/typeclasses/managers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/evennia/typeclasses/managers.py b/evennia/typeclasses/managers.py index 11a84f275..ed61154e7 100644 --- a/evennia/typeclasses/managers.py +++ b/evennia/typeclasses/managers.py @@ -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,7 +58,7 @@ 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: From aa9663024c7880f7354ecaf81b41448224128cb3 Mon Sep 17 00:00:00 2001 From: Griatch Date: Thu, 1 Mar 2018 20:23:18 +0100 Subject: [PATCH 07/12] Make desc/set abide by edit/control locks --- evennia/commands/default/building.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/evennia/commands/default/building.py b/evennia/commands/default/building.py index ebd8f6687..c87ffaaed 100644 --- a/evennia/commands/default/building.py +++ b/evennia/commands/default/building.py @@ -568,6 +568,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, @@ -597,7 +600,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: @@ -1581,6 +1584,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.") @@ -1601,12 +1608,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 From 1f1b3552634b9cd1cc8a3b517a0b1b142e853f70 Mon Sep 17 00:00:00 2001 From: Griatch Date: Thu, 1 Mar 2018 20:53:20 +0100 Subject: [PATCH 08/12] Don't allow those with 'edit' access to obj to change the 'control' lock. --- evennia/commands/default/building.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/evennia/commands/default/building.py b/evennia/commands/default/building.py index c87ffaaed..7085ce2f9 100644 --- a/evennia/commands/default/building.py +++ b/evennia/commands/default/building.py @@ -1853,9 +1853,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: From 047e9f619a303b7b8db8a2248a74731044150f07 Mon Sep 17 00:00:00 2001 From: Griatch Date: Thu, 1 Mar 2018 21:56:40 +0100 Subject: [PATCH 09/12] Make get_attribute/tag manager methods return querysets --- evennia/typeclasses/managers.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/evennia/typeclasses/managers.py b/evennia/typeclasses/managers.py index ed61154e7..358066e3f 100644 --- a/evennia/typeclasses/managers.py +++ b/evennia/typeclasses/managers.py @@ -68,7 +68,9 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager): elif value: # strvalue and value are mutually exclusive 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): """ @@ -190,7 +192,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): """ From 71b6e6cdeaa610fb58ebc6e4101f5c60e11aa899 Mon Sep 17 00:00:00 2001 From: Griatch Date: Thu, 1 Mar 2018 22:21:22 +0100 Subject: [PATCH 10/12] Remove mutual exclusivity between value/strvalue when searching for Attributes with manager --- evennia/typeclasses/managers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evennia/typeclasses/managers.py b/evennia/typeclasses/managers.py index 358066e3f..e6ef778eb 100644 --- a/evennia/typeclasses/managers.py +++ b/evennia/typeclasses/managers.py @@ -65,8 +65,8 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager): 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 Attribute.objects.filter( pk__in=self.model.db_attributes.through.objects.filter( From 223648782fd55d6f9bcf3564514e8046fabf1aa0 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sat, 3 Mar 2018 10:12:34 +0100 Subject: [PATCH 11/12] Allow nick command to list individual nicks --- evennia/commands/default/general.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/evennia/commands/default/general.py b/evennia/commands/default/general.py index ff377119f..2f4c51a22 100644 --- a/evennia/commands/default/general.py +++ b/evennia/commands/default/general.py @@ -145,8 +145,9 @@ class CmdNick(COMMAND_DEFAULT_CLASS): 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 []) + @@ -197,6 +198,28 @@ class CmdNick(COMMAND_DEFAULT_CLASS): nicktypestr, old_nickstring, old_replstring)) 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]") return From bbe4a6925abe850c82295c9b4bfbc579806c40d9 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sat, 3 Mar 2018 18:30:48 +0100 Subject: [PATCH 12/12] Fix a teleport example missing = --- evennia/commands/default/building.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/evennia/commands/default/building.py b/evennia/commands/default/building.py index 7085ce2f9..0afeea8fe 100644 --- a/evennia/commands/default/building.py +++ b/evennia/commands/default/building.py @@ -2331,7 +2331,7 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS): Examples: @tel Limbo - @tel/quiet box Limbo + @tel/quiet box = Limbo @tel/tonone box Switches: @@ -2347,7 +2347,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" locks = "cmd:perm(teleport) or perm(Builder)"