mirror of
https://github.com/evennia/evennia.git
synced 2026-04-05 07:27:17 +02:00
Changed how Objects are searched, using proper Django Q objects instead of hack-y evals to build queries. This has lead to a number of changes to the ObjectDB manager search. Notably there is now no way to supply a "location" to either of the manager search methods anymore. Instead you can now supply the keyword "candidates", a list of objects which should be used to limit the search. This is much more generic than giving location. The higher-level search (like caller.search, reached from commands) have not changed its API, so commands should work the same unless you are using the manager backbone directly. This search function is now using location to create the "candidates" list. Some other things, like matching for "me" and "here" have also been moved up to a level were it can be easily overloaded. "me" and "here" etc were also moved under i18n.
As part of this overhaul I implemented the partial_matching algorithm originally asked for by user "Adam_ASE" over IRC. This will allow for (local-only) partial matching of objects. So "big black sword" will now be matched by "bi", "sword", "bi bla" and so on. The partial matcher sits in src.utils.utils.py if one wants to use it for something else.
This commit is contained in:
parent
cc6fa079b6
commit
c53a9b5770
7 changed files with 236 additions and 193 deletions
|
|
@ -23,7 +23,6 @@ from src.typeclasses.models import Attribute, TypedObject, TypeNick, TypeNickHan
|
|||
from src.typeclasses.models import _get_cache, _set_cache, _del_cache
|
||||
from src.typeclasses.typeclass import TypeClass
|
||||
from src.objects.manager import ObjectManager
|
||||
from src.players.models import PlayerDB
|
||||
from src.commands.cmdsethandler import CmdSetHandler
|
||||
from src.commands import cmdhandler
|
||||
from src.scripts.scripthandler import ScriptHandler
|
||||
|
|
@ -41,6 +40,11 @@ _GA = object.__getattribute__
|
|||
_SA = object.__setattr__
|
||||
_DA = object.__delattr__
|
||||
|
||||
_ME = _("me")
|
||||
_SELF = _("self")
|
||||
_HERE = _("here")
|
||||
|
||||
|
||||
def clean_content_cache(obj):
|
||||
"Clean obj's content cache"
|
||||
_SA(obj, "_contents_cache", None)
|
||||
|
|
@ -500,7 +504,8 @@ class ObjectDB(TypedObject):
|
|||
global_search=False,
|
||||
attribute_name=None,
|
||||
use_nicks=False, location=None,
|
||||
ignore_errors=False, player=False):
|
||||
player=False,
|
||||
ignore_errors=False, exact=False):
|
||||
"""
|
||||
Perform a standard object search in the database, handling
|
||||
multiple results and lack thereof gracefully.
|
||||
|
|
@ -509,17 +514,18 @@ class ObjectDB(TypedObject):
|
|||
Obs - To find a player, append * to the
|
||||
start of ostring.
|
||||
global_search: Search all objects, not just the current
|
||||
location/inventory
|
||||
attribute_name: (string) Which attribute to match
|
||||
(if None, uses default 'name')
|
||||
location/inventory. This is overruled if location keyword is given.
|
||||
attribute_name: (string) Which attribute to match (if None, uses default 'name')
|
||||
use_nicks : Use nickname replace (off by default)
|
||||
location : If None, use caller's current location
|
||||
player: return the Objects' controlling Player, instead, if available
|
||||
ignore_errors : Don't display any error messages even
|
||||
if there are none/multiple matches -
|
||||
just return the result as a list.
|
||||
player : Don't search for an Object but a Player.
|
||||
This will also find players that don't
|
||||
currently have a character.
|
||||
exact: Determines if the search must exactly match the key/alias of the
|
||||
given object or if partial matches the beginnings of one or more
|
||||
words in the name is enough. Exact matching is faster if using
|
||||
global search. Also, if attribute_name is set, matching is always exact.
|
||||
|
||||
Returns - a unique Object/Player match or None. All error
|
||||
messages are handled by system-commands and the parser-handlers
|
||||
|
|
@ -539,6 +545,12 @@ class ObjectDB(TypedObject):
|
|||
address the individual ball as '1-ball', '2-ball', '3-ball'
|
||||
etc.
|
||||
"""
|
||||
# handle some common self-references:
|
||||
if ostring == _HERE:
|
||||
return self.location
|
||||
if ostring in (_ME, _SELF, '*' + _ME, '*' + _SELF):
|
||||
return self
|
||||
|
||||
if use_nicks:
|
||||
if ostring.startswith('*') or player:
|
||||
# player nick replace
|
||||
|
|
@ -549,21 +561,32 @@ class ObjectDB(TypedObject):
|
|||
# object nick replace
|
||||
ostring = self.nicks.get(ostring, nick_type="object")
|
||||
|
||||
if player:
|
||||
if ostring in ("me", "self", "*me", "*self"):
|
||||
results = [self.player]
|
||||
else:
|
||||
results = PlayerDB.objects.player_search(ostring.lstrip('*'))
|
||||
candidates=None
|
||||
if global_search:
|
||||
# only allow exact matching if searching the entire database
|
||||
exact = True
|
||||
else:
|
||||
results = ObjectDB.objects.object_search(ostring, caller=self,
|
||||
global_search=global_search,
|
||||
attribute_name=attribute_name,
|
||||
location=location)
|
||||
# local search. Candidates are self.contents, self.location and self.location.contents
|
||||
if not location:
|
||||
location = self.location
|
||||
candidates = self.contents
|
||||
if location:
|
||||
candidates = candidates + [location] + location.contents
|
||||
else:
|
||||
candidates.append(self) # normally we are included in location.contents
|
||||
# db manager expects database objects
|
||||
candidates = [obj.dbobj for obj in candidates]
|
||||
|
||||
results = ObjectDB.objects.object_search(ostring, caller=self,
|
||||
attribute_name=attribute_name,
|
||||
candidates=candidates,
|
||||
exact=exact)
|
||||
if not ignore_errors:
|
||||
result = _AT_SEARCH_RESULT(self, ostring, results, global_search)
|
||||
if player and result:
|
||||
return result.player
|
||||
return result
|
||||
|
||||
if ignore_errors:
|
||||
return results
|
||||
# this import is cache after the first call.
|
||||
return _AT_SEARCH_RESULT(self, ostring, results, global_search)
|
||||
|
||||
#
|
||||
# Execution/action methods
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue