mirror of
https://github.com/evennia/evennia.git
synced 2026-03-27 10:16:32 +01:00
Merged. Still need to update some migrations.
This commit is contained in:
commit
c676c9965f
29 changed files with 821 additions and 401 deletions
|
|
@ -34,7 +34,6 @@ class ObjectManager(TypedObjectManager):
|
|||
get_dbref_range
|
||||
object_totals
|
||||
typeclass_search
|
||||
get_object_with_user
|
||||
get_object_with_player
|
||||
get_objs_with_key_and_typeclass
|
||||
get_objs_with_attr
|
||||
|
|
@ -52,29 +51,8 @@ class ObjectManager(TypedObjectManager):
|
|||
# ObjectManager Get methods
|
||||
#
|
||||
|
||||
# user/player related
|
||||
# player related
|
||||
|
||||
@returns_typeclass
|
||||
def get_object_with_user(self, user):
|
||||
"""
|
||||
Matches objects with obj.player.user matching the argument.
|
||||
A player<->user is a one-to-relationship, so this always
|
||||
returns just one result or None.
|
||||
|
||||
user - may be a user object or user id.
|
||||
"""
|
||||
dbref = self.dbref(user)
|
||||
if dbref:
|
||||
try:
|
||||
return self.get(db_player__user__id=dbref)
|
||||
except self.model.DoesNotExist:
|
||||
pass
|
||||
try:
|
||||
return self.get(db_player__user=user)
|
||||
except self.model.DoesNotExist:
|
||||
return None
|
||||
|
||||
# This returns typeclass since get_object_with_user and get_dbref does.
|
||||
@returns_typeclass
|
||||
def get_object_with_player(self, ostring, exact=True, candidates=None):
|
||||
"""
|
||||
|
|
@ -92,9 +70,9 @@ class ObjectManager(TypedObjectManager):
|
|||
# not a dbref. Search by name.
|
||||
cand_restriction = candidates and Q(pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q()
|
||||
if exact:
|
||||
return self.filter(cand_restriction & Q(db_player__user__username__iexact=ostring))
|
||||
return self.filter(cand_restriction & Q(db_player__username__iexact=ostring))
|
||||
else: # fuzzy matching
|
||||
ply_cands = self.filter(cand_restriction & Q(playerdb__user__username__istartswith=ostring)).values_list("db_key", flat=True)
|
||||
ply_cands = self.filter(cand_restriction & Q(playerdb__username__istartswith=ostring)).values_list("db_key", flat=True)
|
||||
if candidates:
|
||||
index_matches = string_partial_matching(ply_cands, ostring, ret_index=True)
|
||||
return [obj for ind, obj in enumerate(make_iter(candidates)) if ind in index_matches]
|
||||
|
|
@ -175,7 +153,8 @@ class ObjectManager(TypedObjectManager):
|
|||
if isinstance(property_value, basestring):
|
||||
property_value = to_unicode(property_value)
|
||||
if isinstance(property_name, basestring):
|
||||
property_name = "db_%s" % property_name.lstrip('db_')
|
||||
if not property_name.startswith('db_'):
|
||||
property_name = "db_%s" % property_name
|
||||
querykwargs = {property_name:property_value}
|
||||
cand_restriction = candidates and Q(pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q()
|
||||
type_restriction = typeclasses and Q(db_typeclass_path__in=make_iter(typeclasses)) or Q()
|
||||
|
|
@ -183,6 +162,10 @@ class ObjectManager(TypedObjectManager):
|
|||
return list(self.filter(cand_restriction & type_restriction & Q(**querykwargs)))
|
||||
except exceptions.FieldError:
|
||||
return []
|
||||
except ValueError:
|
||||
from src.utils import logger
|
||||
logger.log_errmsg("The property '%s' does not support search criteria of the type %s." % (property_name, type(property_value)))
|
||||
return []
|
||||
|
||||
@returns_typeclass_list
|
||||
def get_contents(self, location, excludeobj=None):
|
||||
|
|
@ -253,7 +236,8 @@ class ObjectManager(TypedObjectManager):
|
|||
By default (if not attribute_name is set), this will search object.key and object.aliases in order. Can also
|
||||
be on the form #dbref, which will, if exact=True be matched against primary key.
|
||||
attribute_name: (str): Use this named ObjectAttribute to match searchdata against, instead
|
||||
of the defaults.
|
||||
of the defaults. If this is the name of a database field (with or without the db_ prefix), that
|
||||
will be matched too.
|
||||
typeclass (str or TypeClass): restrict matches to objects having this typeclass. This will help
|
||||
speed up global searches.
|
||||
candidates (list obj ObjectDBs): If supplied, search will only be performed among the candidates
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class Migration(DataMigration):
|
|||
"Write your forwards methods here."
|
||||
|
||||
# we need to add a default lock string to all objects, then a separate set to Characters.
|
||||
|
||||
|
||||
lockstring1 = 'control:id(1);get:all();edit:perm(Wizards);examine:perm(Builders);call:true();puppet:id(#4) or perm(Immortals) or pperm(Immortals);delete:id(1) or perm(Wizards)'
|
||||
lockstring2 = 'control:id(#3) or perm(Immortals);get:perm(Wizards);edit:perm(Wizards);examine:perm(Builders);call:false();puppet:id(%i) or pid(%i) or perm(Immortals) or pperm(Immortals);delete:perm(Wizards)'
|
||||
|
||||
|
|
@ -21,10 +21,10 @@ class Migration(DataMigration):
|
|||
for obj in orm.ObjectDB.objects.filter(db_player__isnull=False):
|
||||
obj.db_lock_storage = lockstring2 % (obj.id, obj.db_player.id)
|
||||
obj.save()
|
||||
|
||||
|
||||
except utils.DatabaseError:
|
||||
# running from scatch. In this case we just ignore this.
|
||||
pass
|
||||
pass
|
||||
|
||||
def backwards(self, orm):
|
||||
"Write your backwards methods here."
|
||||
|
|
|
|||
|
|
@ -640,7 +640,7 @@ class ObjectDB(TypedObject):
|
|||
if searchdata == _HERE:
|
||||
return self.location
|
||||
if searchdata in (_ME, _SELF):
|
||||
return self
|
||||
return self.typeclass
|
||||
|
||||
if use_nicks:
|
||||
nick = None
|
||||
|
|
|
|||
|
|
@ -37,14 +37,14 @@ class Object(TypeClass):
|
|||
# __init__ is only defined here in order to present docstring to API.
|
||||
def __init__(self, dbobj):
|
||||
"""
|
||||
This is the root typeclass object representing all entities
|
||||
that has and actual presence in-game. Objects generally has a
|
||||
location, can be manipulated and looked at. Most game entities
|
||||
you define should inherit from Object at some distance.
|
||||
Important subclasses of Object are that Evennia defines by
|
||||
default for you are Characters, Exits and Rooms.
|
||||
This is the root typeclass object, representing all entities
|
||||
that have an actual presence in-game. Objects generally have a
|
||||
location. They can also be manipulated and looked at. Most
|
||||
game entities you define should inherit from Object at some distance.
|
||||
Evennia defines some important subclasses of Object by default, namely
|
||||
Characters, Exits and Rooms (see the bottom of this module).
|
||||
|
||||
Note that all Objects and its subclasses *must* always be
|
||||
Note that all new Objects and their subclasses *must* always be
|
||||
created using the ev.create_object() function. This is so the
|
||||
typeclass system can be correctly initiated behind the scenes.
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ class Object(TypeClass):
|
|||
* Available properties (only available on *initiated* typeclass objects)
|
||||
|
||||
key (string) - name of object
|
||||
name (string)- same as key
|
||||
name (string) - same as key
|
||||
aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings.
|
||||
dbref (int, read-only) - unique #id-number. Also "id" can be used.
|
||||
dbobj (Object, read-only) - link to database model. dbobj.typeclass points back to this class
|
||||
|
|
@ -465,12 +465,13 @@ class Object(TypeClass):
|
|||
"""
|
||||
pass
|
||||
|
||||
def at_pre_puppet(self, player):
|
||||
def at_pre_puppet(self, player, sessid=None):
|
||||
"""
|
||||
Called just before a Player connects to this object
|
||||
to puppet it.
|
||||
|
||||
player - connecting player object
|
||||
sessid - session id controlling the connection
|
||||
"""
|
||||
pass
|
||||
|
||||
|
|
@ -488,13 +489,14 @@ class Object(TypeClass):
|
|||
"""
|
||||
pass
|
||||
|
||||
def at_post_unpuppet(self, player):
|
||||
def at_post_unpuppet(self, player, sessid=None):
|
||||
"""
|
||||
Called just after the Player successfully disconnected
|
||||
from this object, severing all connections.
|
||||
|
||||
player - the player object that just disconnected from
|
||||
this object.
|
||||
sessid - session id controlling the connection
|
||||
"""
|
||||
pass
|
||||
|
||||
|
|
@ -755,7 +757,7 @@ class Object(TypeClass):
|
|||
return message
|
||||
|
||||
#
|
||||
# Base Player object
|
||||
# Base Character object
|
||||
#
|
||||
|
||||
class Character(Object):
|
||||
|
|
@ -793,7 +795,7 @@ class Character(Object):
|
|||
"Default is to look around after a move."
|
||||
self.execute_cmd('look')
|
||||
|
||||
def at_pre_puppet(self, player):
|
||||
def at_pre_puppet(self, player, sessid=None):
|
||||
"""
|
||||
This recovers the character again after having been "stoved away" at the unpuppet
|
||||
"""
|
||||
|
|
@ -809,7 +811,7 @@ class Character(Object):
|
|||
self.location.msg_contents("%s has entered the game." % self.name, exclude=[self])
|
||||
self.location.at_object_receive(self, self.location)
|
||||
else:
|
||||
player.msg("{r%s has no location and no home is set.{n" % self)
|
||||
player.msg("{r%s has no location and no home is set.{n" % self, sessid=sessid)
|
||||
|
||||
def at_post_puppet(self):
|
||||
"""
|
||||
|
|
@ -820,7 +822,7 @@ class Character(Object):
|
|||
if self.location:
|
||||
self.location.msg_contents("%s has entered the game." % self.name, exclude=[self])
|
||||
|
||||
def at_post_unpuppet(self, player):
|
||||
def at_post_unpuppet(self, player, sessid=None):
|
||||
"""
|
||||
We stove away the character when the player goes ooc/logs off, otherwise the character object will
|
||||
remain in the room also after the player logged off ("headless", so to say).
|
||||
|
|
@ -836,14 +838,13 @@ class Character(Object):
|
|||
|
||||
class Room(Object):
|
||||
"""
|
||||
This is the base room object. It's basically
|
||||
like any Object except its location is None.
|
||||
This is the base room object. It's just like any Object except its
|
||||
location is None.
|
||||
"""
|
||||
def basetype_setup(self):
|
||||
"""
|
||||
Simple setup, shown as an example
|
||||
(since default is None anyway)
|
||||
|
||||
"""
|
||||
|
||||
super(Room, self).basetype_setup()
|
||||
|
|
@ -852,19 +853,18 @@ class Room(Object):
|
|||
self.location = None
|
||||
|
||||
#
|
||||
# Exits
|
||||
# Base Exit object
|
||||
#
|
||||
|
||||
class Exit(Object):
|
||||
"""
|
||||
This is the base exit object - it connects a location to
|
||||
another. This is done by the exit assigning a "command" on itself
|
||||
with the same name as the exit object (to do this we need to
|
||||
remember to re-create the command when the object is cached since it must be
|
||||
This is the base exit object - it connects a location to another.
|
||||
This is done by the exit assigning a "command" on itself with the
|
||||
same name as the exit object (to do this we need to remember to
|
||||
re-create the command when the object is cached since it must be
|
||||
created dynamically depending on what the exit is called). This
|
||||
command (which has a high priority) will thus allow us to traverse exits
|
||||
simply by giving the exit-object's name on its own.
|
||||
|
||||
command (which has a high priority) will thus allow us to traverse
|
||||
exits simply by giving the exit-object's name on its own.
|
||||
"""
|
||||
|
||||
# Helper classes and methods to implement the Exit. These need not
|
||||
|
|
@ -909,13 +909,12 @@ class Exit(Object):
|
|||
self.obj.at_failed_traverse(self.caller)
|
||||
|
||||
# create an exit command.
|
||||
cmd = ExitCommand()
|
||||
cmd.key = exidbobj.db_key.strip().lower()
|
||||
cmd.obj = exidbobj
|
||||
cmd.aliases = exidbobj.aliases
|
||||
cmd.locks = str(exidbobj.locks)
|
||||
cmd.destination = exidbobj.db_destination
|
||||
cmd.auto_help = False
|
||||
cmd = ExitCommand(key=exidbobj.db_key.strip().lower(),
|
||||
aliases=exidbobj.aliases,
|
||||
locks=str(exidbobj.locks),
|
||||
auto_help=False,
|
||||
destination=exidbobj.db_destination,
|
||||
obj=exidbobj)
|
||||
# create a cmdset
|
||||
exit_cmdset = cmdset.CmdSet(None)
|
||||
exit_cmdset.key = '_exitset'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue