mirror of
https://github.com/evennia/evennia.git
synced 2026-04-04 15:07:16 +02:00
Committin a 'working' checkpoint before I break more stuff.
This commit is contained in:
parent
ccf078b5c8
commit
d3808c1ea2
18 changed files with 494 additions and 444 deletions
11
apps/objects/exceptions.py
Normal file
11
apps/objects/exceptions.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
"""
|
||||
Exceptions for the object application.
|
||||
"""
|
||||
from src.exceptions_generic import GenericException
|
||||
|
||||
class ObjectNotExist(GenericException):
|
||||
"""
|
||||
Raised when an object is queried for but does not exist.
|
||||
"""
|
||||
def __str__(self):
|
||||
return repr("No such object: %s" % self.value)
|
||||
18
apps/objects/managers/attribute.py
Normal file
18
apps/objects/managers/attribute.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
"""
|
||||
Custom manager for Attribute objects.
|
||||
"""
|
||||
from django.db import models
|
||||
|
||||
import defines_global
|
||||
|
||||
class AttributeManager(models.Manager):
|
||||
def is_modifiable_attrib(self, attribname):
|
||||
"""
|
||||
Check to see if a particular attribute is modifiable.
|
||||
|
||||
attribname: (string) An attribute name to check.
|
||||
"""
|
||||
if attribname.upper() not in defines_global.NOSET_ATTRIBS:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
|
@ -1,8 +1,348 @@
|
|||
"""
|
||||
Custom manager for Object objects.
|
||||
"""
|
||||
import sets
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from django.db import models
|
||||
from django.db import connection
|
||||
from django.contrib.auth.models import User
|
||||
from django.db.models import Q
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
from apps.config.models import ConfigValue
|
||||
from apps.objects.exceptions import ObjectNotExist
|
||||
from apps.objects.util import object as util_object
|
||||
import defines_global
|
||||
|
||||
class ObjectManager(models.Manager):
|
||||
pass
|
||||
def num_total_players(self):
|
||||
"""
|
||||
Returns the total number of registered players.
|
||||
"""
|
||||
return User.objects.count()
|
||||
|
||||
def get_connected_players(self):
|
||||
"""
|
||||
Returns the a QuerySet containing the currently connected players.
|
||||
"""
|
||||
return self.filter(nosave_flags__contains="CONNECTED")
|
||||
|
||||
def get_recently_created_users(self, days=7):
|
||||
"""
|
||||
Returns a QuerySet containing the player User accounts that have been
|
||||
connected within the last <days> days.
|
||||
"""
|
||||
end_date = datetime.now()
|
||||
tdelta = timedelta(days)
|
||||
start_date = end_date - tdelta
|
||||
return User.objects.filter(date_joined__range=(start_date, end_date))
|
||||
|
||||
def get_recently_connected_users(self, days=7):
|
||||
"""
|
||||
Returns a QuerySet containing the player User accounts that have been
|
||||
connected within the last <days> days.
|
||||
"""
|
||||
end_date = datetime.now()
|
||||
tdelta = timedelta(days)
|
||||
start_date = end_date - tdelta
|
||||
return User.objects.filter(last_login__range=(start_date, end_date)).order_by('-last_login')
|
||||
|
||||
def get_nextfree_dbnum(self):
|
||||
"""
|
||||
Figure out what our next free database reference number is.
|
||||
|
||||
If we need to recycle a GARBAGE object, return the object to recycle
|
||||
Otherwise, return the first free dbref.
|
||||
"""
|
||||
# First we'll see if there's an object of type 6 (GARBAGE) that we
|
||||
# can recycle.
|
||||
nextfree = self.filter(type__exact=defines_global.OTYPE_GARBAGE)
|
||||
if nextfree:
|
||||
# We've got at least one garbage object to recycle.
|
||||
return nextfree.id
|
||||
else:
|
||||
# No garbage to recycle, find the highest dbnum and increment it
|
||||
# for our next free.
|
||||
return int(self.order_by('-id')[0].id + 1)
|
||||
|
||||
def global_object_name_search(self, ostring, exact_match=False):
|
||||
"""
|
||||
Searches through all objects for a name match.
|
||||
"""
|
||||
if exact_match:
|
||||
o_query = self.filter(name__iexact=ostring)
|
||||
else:
|
||||
o_query = self.filter(name__icontains=ostring)
|
||||
|
||||
return o_query.exclude(type=defines_global.OTYPE_GARBAGE)
|
||||
|
||||
def list_search_object_namestr(self, searchlist, ostring, dbref_only=False, limit_types=False, match_type="fuzzy"):
|
||||
"""
|
||||
Iterates through a list of objects and returns a list of
|
||||
name matches.
|
||||
searchlist: (List of Objects) The objects to perform name comparisons on.
|
||||
ostring: (string) The string to match against.
|
||||
dbref_only: (bool) Only compare dbrefs.
|
||||
limit_types: (list of int) A list of Object type numbers to filter by.
|
||||
"""
|
||||
if dbref_only:
|
||||
if limit_types:
|
||||
return [prospect for prospect in searchlist if prospect.dbref_match(ostring) and prospect.type in limit_types]
|
||||
else:
|
||||
return [prospect for prospect in searchlist if prospect.dbref_match(ostring)]
|
||||
else:
|
||||
if limit_types:
|
||||
return [prospect for prospect in searchlist if prospect.name_match(ostring, match_type=match_type) and prospect.type in limit_types]
|
||||
else:
|
||||
return [prospect for prospect in searchlist if prospect.name_match(ostring, match_type=match_type)]
|
||||
|
||||
|
||||
def standard_plr_objsearch(self, session, ostring, search_contents=True, search_location=True, dbref_only=False, limit_types=False):
|
||||
"""
|
||||
Perform a standard object search via a player session, handling multiple
|
||||
results and lack thereof gracefully.
|
||||
|
||||
session: (SessionProtocol) Reference to the player's session.
|
||||
ostring: (str) The string to match object names against.
|
||||
"""
|
||||
pobject = session.get_pobject()
|
||||
results = self.local_and_global_search(pobject, ostring, search_contents=search_contents, search_location=search_location, dbref_only=dbref_only, limit_types=limit_types)
|
||||
|
||||
if len(results) > 1:
|
||||
session.msg("More than one match found (please narrow target):")
|
||||
for result in results:
|
||||
session.msg(" %s" % (result.get_name(),))
|
||||
return False
|
||||
elif len(results) == 0:
|
||||
session.msg("I don't see that here.")
|
||||
return False
|
||||
else:
|
||||
return results[0]
|
||||
|
||||
def object_totals(self):
|
||||
"""
|
||||
Returns a dictionary with database object totals.
|
||||
"""
|
||||
dbtotals = {
|
||||
"objects": self.count(),
|
||||
"things": self.filter(type=defines_global.OTYPE_THING).count(),
|
||||
"exits": self.filter(type=defines_global.OTYPE_EXIT).count(),
|
||||
"rooms": self.filter(type=defines_global.OTYPE_ROOM).count(),
|
||||
"garbage": self.filter(type=defines_global.OTYPE_GARBAGE).count(),
|
||||
"players": self.filter(type=defines_global.OTYPE_PLAYER).count(),
|
||||
}
|
||||
return dbtotals
|
||||
|
||||
def player_alias_search(self, searcher, ostring):
|
||||
"""
|
||||
Search players by alias. Returns a list of objects whose "ALIAS" attribute
|
||||
exactly (not case-sensitive) matches ostring.
|
||||
|
||||
searcher: (Object) The object doing the searching.
|
||||
ostring: (string) The alias string to search for.
|
||||
"""
|
||||
search_query = ''.join(ostring)
|
||||
Attribute = ContentType.objects.get(app_label="objects", model="attribute").get_model()
|
||||
results = Attribute.objects.select_related().filter(attr_name__exact="ALIAS").filter(attr_value__iexact=ostring)
|
||||
return [prospect.get_object() for prospect in results if prospect.get_object().is_player()]
|
||||
|
||||
def player_name_search(self, search_string):
|
||||
"""
|
||||
Combines an alias and global search for a player's name. If there are
|
||||
no alias matches, do a global search limiting by type PLAYER.
|
||||
|
||||
search_string: (string) The name string to search for.
|
||||
"""
|
||||
# Handle the case where someone might have started the search_string
|
||||
# with a *
|
||||
if search_string.startswith('*') is True:
|
||||
search_string = search_string[1:]
|
||||
# Use Q objects to build complex OR query to look at either
|
||||
# the player name or ALIAS attribute
|
||||
player_filter = Q(name__iexact=search_string)
|
||||
alias_filter = Q(attribute__attr_name__exact="ALIAS") & \
|
||||
Q(attribute__attr_value__iexact=search_string)
|
||||
player_matches = self.filter(
|
||||
player_filter | alias_filter).filter(
|
||||
type=defines_global.OTYPE_PLAYER).distinct()
|
||||
try:
|
||||
return player_matches[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def dbref_search(self, dbref_string, limit_types=False):
|
||||
"""
|
||||
Searches for a given dbref.
|
||||
|
||||
dbref_number: (string) The dbref to search for
|
||||
limit_types: (list of int) A list of Object type numbers to filter by.
|
||||
"""
|
||||
if not util_object.is_dbref(dbref_string):
|
||||
return None
|
||||
dbref_string = dbref_string[1:]
|
||||
dbref_matches = self.filter(id=dbref_string).exclude(
|
||||
type=defines_global.OTYPE_GARBAGE)
|
||||
# Check for limiters
|
||||
if limit_types is not False:
|
||||
for limiter in limit_types:
|
||||
dbref_matches.filter(type=limiter)
|
||||
try:
|
||||
return dbref_matches[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def local_and_global_search(self, searcher, ostring, search_contents=True, search_location=True, dbref_only=False, limit_types=False):
|
||||
"""
|
||||
Searches an object's location then globally for a dbref or name match.
|
||||
|
||||
searcher: (Object) The object performing the search.
|
||||
ostring: (string) The string to compare names against.
|
||||
search_contents: (bool) While true, check the contents of the searcher.
|
||||
search_location: (bool) While true, check the searcher's surroundings.
|
||||
dbref_only: (bool) Only compare dbrefs.
|
||||
limit_types: (list of int) A list of Object type numbers to filter by.
|
||||
"""
|
||||
search_query = ''.join(ostring)
|
||||
|
||||
# This is a global dbref search. Not applicable if we're only searching
|
||||
# searcher's contents/locations, dbref comparisons for location/contents
|
||||
# searches are handled by list_search_object_namestr() below.
|
||||
if util_object.is_dbref(ostring):
|
||||
search_num = search_query[1:]
|
||||
dbref_match = dbref_search(search_num, limit_types)
|
||||
if dbref_match is not None:
|
||||
return [dbref_match]
|
||||
|
||||
# If the search string is one of the following, return immediately with
|
||||
# the appropriate result.
|
||||
if searcher.get_location().dbref_match(ostring) or ostring == 'here':
|
||||
return [searcher.get_location()]
|
||||
elif ostring == 'me' and searcher:
|
||||
return [searcher]
|
||||
|
||||
if search_query[0] == "*":
|
||||
# Player search- gotta search by name or alias
|
||||
search_target = search_query[1:]
|
||||
player_match = player_name_search(search_target)
|
||||
if player_match is not None:
|
||||
return [player_match]
|
||||
|
||||
local_matches = []
|
||||
# Handle our location/contents searches. list_search_object_namestr() does
|
||||
# name and dbref comparisons against search_query.
|
||||
if search_contents:
|
||||
local_matches += list_search_object_namestr(searcher.get_contents(), search_query, limit_types)
|
||||
if search_location:
|
||||
local_matches += list_search_object_namestr(searcher.get_location().get_contents(), search_query, limit_types=limit_types)
|
||||
return local_matches
|
||||
|
||||
def get_user_from_email(self, uemail):
|
||||
"""
|
||||
Returns a player's User object when given an email address.
|
||||
"""
|
||||
return User.objects.filter(email__iexact=uemail)
|
||||
|
||||
def get_object_from_dbref(self, dbref):
|
||||
"""
|
||||
Returns an object when given a dbref.
|
||||
"""
|
||||
try:
|
||||
return self.get(id=dbref)
|
||||
except self.model.DoesNotExist:
|
||||
raise ObjectNotExist(dbref)
|
||||
|
||||
def create_object(self, odat):
|
||||
"""
|
||||
Create a new object. odat is a dictionary that contains the following keys.
|
||||
REQUIRED KEYS:
|
||||
* type: Integer representing the object's type.
|
||||
* name: The name of the new object.
|
||||
* location: Reference to another object for the new object to reside in.
|
||||
* owner: The creator of the object.
|
||||
OPTIONAL KEYS:
|
||||
* home: Reference to another object to home to. If not specified, use
|
||||
location key for home.
|
||||
"""
|
||||
next_dbref = get_nextfree_dbnum()
|
||||
new_object = Object()
|
||||
|
||||
new_object.id = next_dbref
|
||||
new_object.type = odat["type"]
|
||||
new_object.set_name(odat["name"])
|
||||
|
||||
# If this is a player, we don't want him owned by anyone.
|
||||
# The get_owner() function will return that the player owns
|
||||
# himself.
|
||||
if odat["type"] == 1:
|
||||
new_object.owner = None
|
||||
new_object.zone = None
|
||||
else:
|
||||
new_object.owner = odat["owner"]
|
||||
|
||||
if new_object.get_owner().get_zone():
|
||||
new_object.zone = new_object.get_owner().get_zone()
|
||||
|
||||
# If we have a 'home' key, use that for our home value. Otherwise use
|
||||
# the location key.
|
||||
if odat.has_key("home"):
|
||||
new_object.home = odat["home"]
|
||||
else:
|
||||
if new_object.is_exit():
|
||||
new_object.home = None
|
||||
else:
|
||||
new_object.home = odat["location"]
|
||||
|
||||
new_object.save()
|
||||
|
||||
# Rooms have a NULL location.
|
||||
if not new_object.is_room():
|
||||
new_object.move_to(odat['location'])
|
||||
|
||||
return new_object
|
||||
|
||||
def create_user(self, cdat, uname, email, password):
|
||||
"""
|
||||
Handles the creation of new users.
|
||||
"""
|
||||
session = cdat['session']
|
||||
server = cdat['server']
|
||||
start_room = int(ConfigValue.objects.get_configvalue('player_dbnum_start'))
|
||||
start_room_obj = get_object_from_dbref(start_room)
|
||||
|
||||
# The user's entry in the User table must match up to an object
|
||||
# on the object table. The id's are the same, we need to figure out
|
||||
# the next free unique ID to use and make sure the two entries are
|
||||
# the same number.
|
||||
uid = get_nextfree_dbnum()
|
||||
print 'UID', uid
|
||||
|
||||
# If this is an object, we know to recycle it since it's garbage. We'll
|
||||
# pluck the user ID from it.
|
||||
if not str(uid).isdigit():
|
||||
uid = uid.id
|
||||
print 'UID2', uid
|
||||
|
||||
user = User.objects.create_user(uname, email, password)
|
||||
# It stinks to have to do this but it's the only trivial way now.
|
||||
user.save()
|
||||
|
||||
# We can't use the user model to change the id because of the way keys
|
||||
# are handled, so we actually need to fall back to raw SQL. Boo hiss.
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("UPDATE auth_user SET id=%d WHERE id=%d" % (uid, user.id))
|
||||
|
||||
# Grab the user object again since we've changed it and the old reference
|
||||
# is no longer valid.
|
||||
user = User.objects.get(id=uid)
|
||||
|
||||
# Create a player object of the same ID in the Objects table.
|
||||
odat = {"id": uid, "name": uname, "type": 1, "location": start_room_obj, "owner": None}
|
||||
user_object = create_object(odat)
|
||||
|
||||
# Activate the player's session and set them loose.
|
||||
session.login(user)
|
||||
print 'Registration: %s' % (session,)
|
||||
session.msg("Welcome to %s, %s.\n\r" % (
|
||||
ConfigValue.objects.get_configvalue('site_name'),
|
||||
session.get_pobject().get_name(show_dbref=False)))
|
||||
|
|
|
|||
|
|
@ -6,9 +6,12 @@ from django.contrib.auth.models import User, Group
|
|||
import scripthandler
|
||||
import defines_global
|
||||
import ansi
|
||||
import src.flags
|
||||
from apps.config.models import ConfigValue
|
||||
from apps.objects.util import object as util_object
|
||||
from apps.objects.managers.commchannel import CommChannelManager
|
||||
from apps.objects.managers.object import ObjectManager
|
||||
from apps.objects.managers.attribute import AttributeManager
|
||||
|
||||
class Attribute(models.Model):
|
||||
"""
|
||||
|
|
@ -24,6 +27,8 @@ class Attribute(models.Model):
|
|||
attr_hidden = models.BooleanField(default=0)
|
||||
attr_object = models.ForeignKey("Object")
|
||||
|
||||
objects = AttributeManager()
|
||||
|
||||
def __str__(self):
|
||||
return "%s(%s)" % (self.attr_name, self.id)
|
||||
|
||||
|
|
@ -550,7 +555,7 @@ class Object(models.Model):
|
|||
|
||||
if value == False and has_flag:
|
||||
# Clear the flag.
|
||||
if functions_db.is_unsavable_flag(flag):
|
||||
if src.flags.is_unsavable_flag(flag):
|
||||
# Not a savable flag (CONNECTED, etc)
|
||||
flags = self.nosave_flags.split()
|
||||
flags.remove(flag)
|
||||
|
|
@ -570,7 +575,7 @@ class Object(models.Model):
|
|||
pass
|
||||
else:
|
||||
# Setting a flag.
|
||||
if functions_db.is_unsavable_flag(flag):
|
||||
if src.flags.is_unsavable_flag(flag):
|
||||
# Not a savable flag (CONNECTED, etc)
|
||||
flags = str(self.nosave_flags).split()
|
||||
flags.append(flag)
|
||||
|
|
@ -707,7 +712,7 @@ class Object(models.Model):
|
|||
|
||||
oname: (str) Name to match against.
|
||||
"""
|
||||
if not functions_db.is_dbref(oname):
|
||||
if not util_object.is_dbref(oname):
|
||||
return False
|
||||
|
||||
try:
|
||||
|
|
@ -888,6 +893,5 @@ class CommChannelMessage(models.Model):
|
|||
class Admin:
|
||||
list_display = ('channel', 'message')
|
||||
|
||||
import functions_db
|
||||
import functions_general
|
||||
import session_mgr
|
||||
|
|
|
|||
0
apps/objects/util/__init__.py
Normal file
0
apps/objects/util/__init__.py
Normal file
19
apps/objects/util/object.py
Normal file
19
apps/objects/util/object.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
"""
|
||||
Utility functions for the Object class. These functions should not import
|
||||
any models or modify the database.
|
||||
"""
|
||||
def is_dbref(dbstring):
|
||||
"""
|
||||
Is the input a well-formed dbref number?
|
||||
"""
|
||||
try:
|
||||
number = int(dbstring[1:])
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
if not dbstring.startswith("#"):
|
||||
return False
|
||||
elif number < 1:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
|
@ -6,9 +6,9 @@ something.
|
|||
from traceback import format_exc
|
||||
import time
|
||||
|
||||
from apps.objects.models import Object
|
||||
import defines_global
|
||||
import cmdtable
|
||||
import functions_db
|
||||
import functions_general
|
||||
import functions_log
|
||||
import functions_comsys
|
||||
|
|
@ -23,7 +23,7 @@ def match_exits(pobject, searchstr):
|
|||
See if we can find an input match to exits.
|
||||
"""
|
||||
exits = pobject.get_location().get_contents(filter_type=4)
|
||||
return functions_db.list_search_object_namestr(exits, searchstr, match_type="exact")
|
||||
return Object.objects.list_search_object_namestr(exits, searchstr, match_type="exact")
|
||||
|
||||
def parse_command(command_string):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
"""
|
||||
Comsys command module. Pretty much every comsys command should go here for
|
||||
now.
|
||||
"""
|
||||
import time
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
import functions_general
|
||||
import functions_db
|
||||
import functions_comsys
|
||||
import defines_global
|
||||
import ansi
|
||||
"""
|
||||
Comsys command module. Pretty much every comsys command should go here for
|
||||
now.
|
||||
"""
|
||||
|
||||
def cmd_addcom(cdat):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ from django.conf import settings
|
|||
|
||||
from apps.config.models import ConfigValue
|
||||
from apps.helpsys.models import HelpEntry
|
||||
from apps.objects.models import Object
|
||||
import functions_general
|
||||
import functions_db
|
||||
import defines_global
|
||||
import session_mgr
|
||||
import ansi
|
||||
|
|
@ -110,7 +110,7 @@ def cmd_look(cdat):
|
|||
if len(args) == 0:
|
||||
target_obj = pobject.get_location()
|
||||
else:
|
||||
target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args))
|
||||
target_obj = Object.objects.standard_plr_objsearch(session, ' '.join(args))
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not target_obj:
|
||||
return
|
||||
|
|
@ -139,7 +139,7 @@ def cmd_get(cdat):
|
|||
session.msg("Get what?")
|
||||
return
|
||||
else:
|
||||
target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args), search_contents=False)
|
||||
target_obj = Object.objects.standard_plr_objsearch(session, ' '.join(args), search_contents=False)
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not target_obj:
|
||||
return
|
||||
|
|
@ -178,7 +178,7 @@ def cmd_drop(cdat):
|
|||
session.msg("Drop what?")
|
||||
return
|
||||
else:
|
||||
target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args), search_location=False)
|
||||
target_obj = Object.objects.standard_plr_objsearch(session, ' '.join(args), search_location=False)
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not target_obj:
|
||||
return
|
||||
|
|
@ -224,7 +224,7 @@ def cmd_examine(cdat):
|
|||
else:
|
||||
searchstr = ' '.join(args)
|
||||
|
||||
target_obj = functions_db.standard_plr_objsearch(session, searchstr)
|
||||
target_obj = Object.objects.standard_plr_objsearch(session, searchstr)
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not target_obj:
|
||||
return
|
||||
|
|
@ -302,9 +302,9 @@ def cmd_page(cdat):
|
|||
last_paged_dbref_list = [
|
||||
x.strip() for x in last_paged_dbrefs.split(',')]
|
||||
for dbref in last_paged_dbref_list:
|
||||
if not functions_db.is_dbref(dbref):
|
||||
if not Object.objects.is_dbref(dbref):
|
||||
raise ValueError
|
||||
last_paged_object = functions_db.dbref_search(dbref)
|
||||
last_paged_object = Object.objects.dbref_search(dbref)
|
||||
if last_paged_object is not None:
|
||||
last_paged_objects.append(last_paged_object)
|
||||
except ValueError:
|
||||
|
|
@ -332,7 +332,7 @@ def cmd_page(cdat):
|
|||
targets = dict([(target, 1) for target in last_paged_objects])
|
||||
else:
|
||||
# First try to match the entire target string against a single player
|
||||
full_target_match = functions_db.player_name_search(
|
||||
full_target_match = Object.objects.player_name_search(
|
||||
parsed_command['original_targets'])
|
||||
if full_target_match is not None:
|
||||
targets[full_target_match] = 1
|
||||
|
|
@ -341,9 +341,9 @@ def cmd_page(cdat):
|
|||
# it to the targets list
|
||||
for target in parsed_command['targets']:
|
||||
# If the target is a dbref, behave appropriately
|
||||
if functions_db.is_dbref(target):
|
||||
if Object.objects.is_dbref(target):
|
||||
session.msg("Is dbref.")
|
||||
matched_object = functions_db.dbref_search(target,
|
||||
matched_object = Object.objects.dbref_search(target,
|
||||
limit_types=[defines_global.OTYPE_PLAYER])
|
||||
if matched_object is not None:
|
||||
targets[matched_object] = 1
|
||||
|
|
@ -353,7 +353,7 @@ def cmd_page(cdat):
|
|||
target))
|
||||
else:
|
||||
# Not a dbref, so must be a username, treat it as such
|
||||
matched_object = functions_db.player_name_search(
|
||||
matched_object = Object.objects.player_name_search(
|
||||
target)
|
||||
if matched_object is not None:
|
||||
targets[matched_object] = 1
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ if not functions_general.host_os_is('nt'):
|
|||
# Don't import the resource module if the host OS is Windows.
|
||||
import resource
|
||||
|
||||
import functions_db
|
||||
from apps.objects.models import Object
|
||||
import scheduler
|
||||
import defines_global
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ def cmd_stats(cdat):
|
|||
4012 objects = 144 rooms, 212 exits, 613 things, 1878 players. (1165 garbage)
|
||||
"""
|
||||
session = cdat['session']
|
||||
stats_dict = functions_db.object_totals()
|
||||
stats_dict = Object.objects.object_totals()
|
||||
session.msg("%d objects = %d rooms, %d exits, %d things, %d players. (%d garbage)" % (stats_dict["objects"],
|
||||
stats_dict["rooms"],
|
||||
stats_dict["exits"],
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
"""
|
||||
These commands typically are to do with building or modifying Objects.
|
||||
"""
|
||||
from apps.objects.models import Object
|
||||
import src.flags
|
||||
import ansi
|
||||
import session_mgr
|
||||
import functions_db
|
||||
|
||||
def cmd_teleport(cdat):
|
||||
"""
|
||||
|
|
@ -23,12 +27,12 @@ def cmd_teleport(cdat):
|
|||
# a direct teleport, @tel <destination>.
|
||||
if len(eq_args) > 1:
|
||||
# Equal sign teleport.
|
||||
victim = functions_db.standard_plr_objsearch(session, eq_args[0])
|
||||
victim = Object.objects.standard_plr_objsearch(session, eq_args[0])
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not victim:
|
||||
return
|
||||
|
||||
destination = functions_db.standard_plr_objsearch(session, eq_args[1])
|
||||
destination = Object.objects.standard_plr_objsearch(session, eq_args[1])
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not destination:
|
||||
return
|
||||
|
|
@ -53,7 +57,7 @@ def cmd_teleport(cdat):
|
|||
|
||||
else:
|
||||
# Direct teleport (no equal sign)
|
||||
target_obj = functions_db.standard_plr_objsearch(session, search_str)
|
||||
target_obj = Object.objects.standard_plr_objsearch(session, search_str)
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not target_obj:
|
||||
return
|
||||
|
|
@ -71,7 +75,7 @@ def cmd_stats(cdat):
|
|||
4012 objects = 144 rooms, 212 exits, 613 things, 1878 players. (1165 garbage)
|
||||
"""
|
||||
session = cdat['session']
|
||||
stats_dict = functions_db.object_totals()
|
||||
stats_dict = Object.objects.object_totals()
|
||||
session.msg("%d objects = %d rooms, %d exits, %d things, %d players. (%d garbage)" % (stats_dict["objects"],
|
||||
stats_dict["rooms"],
|
||||
stats_dict["exits"],
|
||||
|
|
@ -98,13 +102,13 @@ def cmd_alias(cdat):
|
|||
session.msg("Alias missing.")
|
||||
return
|
||||
|
||||
target = functions_db.standard_plr_objsearch(session, eq_args[0])
|
||||
target = Object.objects.standard_plr_objsearch(session, eq_args[0])
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not target:
|
||||
session.msg("Alias whom?")
|
||||
return
|
||||
|
||||
duplicates = functions_db.alias_search(pobject, eq_args[1])
|
||||
duplicates = Object.objects.player_alias_search(pobject, eq_args[1])
|
||||
|
||||
if duplicates:
|
||||
session.msg("Alias '%s' already exists." % (eq_args[1],))
|
||||
|
|
@ -145,7 +149,7 @@ def cmd_wipe(cdat):
|
|||
else:
|
||||
searchstr = ' '.join(args)
|
||||
|
||||
target_obj = functions_db.standard_plr_objsearch(session, searchstr)
|
||||
target_obj = Object.objects.standard_plr_objsearch(session, searchstr)
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not target_obj:
|
||||
return
|
||||
|
|
@ -189,7 +193,7 @@ def cmd_set(cdat):
|
|||
session.msg("Set what?")
|
||||
return
|
||||
|
||||
victim = functions_db.standard_plr_objsearch(session, eq_args[0])
|
||||
victim = Object.objects.standard_plr_objsearch(session, eq_args[0])
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not victim:
|
||||
return
|
||||
|
|
@ -207,7 +211,7 @@ def cmd_set(cdat):
|
|||
attrib_value = eq_args[1][splicenum:]
|
||||
|
||||
# In global_defines.py, see NOSET_ATTRIBS for protected attribute names.
|
||||
if not functions_db.is_modifiable_attrib(attrib_name) and not pobject.is_superuser():
|
||||
if not src.flags.is_modifiable_attrib(attrib_name) and not pobject.is_superuser():
|
||||
session.msg("You can't modify that attribute.")
|
||||
return
|
||||
|
||||
|
|
@ -229,14 +233,14 @@ def cmd_set(cdat):
|
|||
if flag[0] == '!':
|
||||
# We're un-setting the flag.
|
||||
flag = flag[1:]
|
||||
if not functions_db.is_modifiable_flag(flag):
|
||||
if not src.flags.is_modifiable_flag(flag):
|
||||
session.msg("You can't set/unset the flag - %s." % (flag,))
|
||||
else:
|
||||
session.msg('%s - %s cleared.' % (victim.get_name(), flag.upper(),))
|
||||
victim.set_flag(flag, False)
|
||||
else:
|
||||
# We're setting the flag.
|
||||
if not functions_db.is_modifiable_flag(flag):
|
||||
if not src.flags.is_modifiable_flag(flag):
|
||||
session.msg("You can't set/unset the flag - %s." % (flag,))
|
||||
else:
|
||||
session.msg('%s - %s set.' % (victim.get_name(), flag.upper(),))
|
||||
|
|
@ -256,7 +260,7 @@ def cmd_find(cdat):
|
|||
session.msg("No search pattern given.")
|
||||
return
|
||||
|
||||
results = functions_db.global_object_name_search(searchstring)
|
||||
results = Object.objects.global_object_name_search(searchstring)
|
||||
|
||||
if len(results) > 0:
|
||||
session.msg("Name matches for: %s" % (searchstring,))
|
||||
|
|
@ -281,7 +285,7 @@ def cmd_create(cdat):
|
|||
else:
|
||||
# Create and set the object up.
|
||||
odat = {"name": thingname, "type": 3, "location": pobject, "owner": pobject}
|
||||
new_object = functions_db.create_object(odat)
|
||||
new_object = Object.objects.create_object(odat)
|
||||
|
||||
session.msg("You create a new thing: %s" % (new_object,))
|
||||
|
||||
|
|
@ -291,7 +295,7 @@ def cmd_nextfree(cdat):
|
|||
"""
|
||||
session = cdat['session']
|
||||
|
||||
nextfree = functions_db.get_nextfree_dbnum()
|
||||
nextfree = Object.objects.get_nextfree_dbnum()
|
||||
session.msg("Next free object number: #%s" % (nextfree,))
|
||||
|
||||
def cmd_open(cdat):
|
||||
|
|
@ -325,7 +329,7 @@ def cmd_open(cdat):
|
|||
if len(eq_args) > 1:
|
||||
# Opening an exit to another location via @open <Name>=<Dbref>[,<Name>].
|
||||
comma_split = eq_args[1].split(',')
|
||||
destination = functions_db.standard_plr_objsearch(session, comma_split[0])
|
||||
destination = Object.objects.standard_plr_objsearch(session, comma_split[0])
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not destination:
|
||||
return
|
||||
|
|
@ -335,20 +339,20 @@ def cmd_open(cdat):
|
|||
return
|
||||
|
||||
odat = {"name": exit_name, "type": 4, "location": pobject.get_location(), "owner": pobject, "home":destination}
|
||||
new_object = functions_db.create_object(odat)
|
||||
new_object = Object.objects.create_object(odat)
|
||||
|
||||
session.msg("You open the an exit - %s to %s" % (new_object.get_name(),destination.get_name()))
|
||||
|
||||
if len(comma_split) > 1:
|
||||
second_exit_name = ','.join(comma_split[1:])
|
||||
odat = {"name": second_exit_name, "type": 4, "location": destination, "owner": pobject, "home": pobject.get_location()}
|
||||
new_object = functions_db.create_object(odat)
|
||||
new_object = Object.objects.create_object(odat)
|
||||
session.msg("You open the an exit - %s to %s" % (new_object.get_name(),pobject.get_location().get_name()))
|
||||
|
||||
else:
|
||||
# Create an un-linked exit.
|
||||
odat = {"name": exit_name, "type": 4, "location": pobject.get_location(), "owner": pobject, "home":None}
|
||||
new_object = functions_db.create_object(odat)
|
||||
new_object = Object.objects.create_object(odat)
|
||||
|
||||
session.msg("You open an unlinked exit - %s" % (new_object,))
|
||||
|
||||
|
|
@ -377,7 +381,7 @@ def cmd_link(cdat):
|
|||
return
|
||||
|
||||
if len(eq_args) > 1:
|
||||
target_obj = functions_db.standard_plr_objsearch(session, target_name)
|
||||
target_obj = Object.objects.standard_plr_objsearch(session, target_name)
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not target_obj:
|
||||
return
|
||||
|
|
@ -392,7 +396,7 @@ def cmd_link(cdat):
|
|||
session.msg("You have unlinked %s." % (target_obj,))
|
||||
return
|
||||
|
||||
destination = functions_db.standard_plr_objsearch(session, dest_name)
|
||||
destination = Object.objects.standard_plr_objsearch(session, dest_name)
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not destination:
|
||||
return
|
||||
|
|
@ -417,7 +421,7 @@ def cmd_unlink(cdat):
|
|||
session.msg("Unlink what?")
|
||||
return
|
||||
else:
|
||||
target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args))
|
||||
target_obj = Object.objects.standard_plr_objsearch(session, ' '.join(args))
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not target_obj:
|
||||
return
|
||||
|
|
@ -443,7 +447,7 @@ def cmd_dig(cdat):
|
|||
else:
|
||||
# Create and set the object up.
|
||||
odat = {"name": roomname, "type": 2, "location": None, "owner": pobject}
|
||||
new_object = functions_db.create_object(odat)
|
||||
new_object = Object.objects.create_object(odat)
|
||||
|
||||
session.msg("You create a new room: %s" % (new_object,))
|
||||
|
||||
|
|
@ -462,7 +466,7 @@ def cmd_name(cdat):
|
|||
elif len(eq_args) < 2:
|
||||
session.msg("What would you like to name that object?")
|
||||
else:
|
||||
target_obj = functions_db.standard_plr_objsearch(session, searchstring)
|
||||
target_obj = Object.objects.standard_plr_objsearch(session, searchstring)
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not target_obj:
|
||||
return
|
||||
|
|
@ -489,7 +493,7 @@ def cmd_description(cdat):
|
|||
elif len(eq_args) < 2:
|
||||
session.msg("How would you like to describe that object?")
|
||||
else:
|
||||
target_obj = functions_db.standard_plr_objsearch(session, searchstring)
|
||||
target_obj = Object.objects.standard_plr_objsearch(session, searchstring)
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not target_obj:
|
||||
return
|
||||
|
|
@ -519,7 +523,7 @@ def cmd_destroy(cdat):
|
|||
session.msg("Destroy what?")
|
||||
return
|
||||
else:
|
||||
target_obj = functions_db.standard_plr_objsearch(session, ' '.join(args))
|
||||
target_obj = Object.objects.standard_plr_objsearch(session, ' '.join(args))
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not target_obj:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from apps.objects.models import Object
|
||||
import defines_global
|
||||
import functions_general
|
||||
import functions_db
|
||||
import ansi
|
||||
|
||||
"""
|
||||
|
|
@ -52,7 +52,7 @@ def cmd_boot(cdat):
|
|||
break
|
||||
else:
|
||||
# Grab the objects that match
|
||||
objs = functions_db.global_object_name_search(searchstring)
|
||||
objs = Objects.object.global_object_name_search(searchstring)
|
||||
|
||||
if len(objs) < 1:
|
||||
session.msg("Who would you like to boot?")
|
||||
|
|
@ -98,7 +98,7 @@ def cmd_newpassword(cdat):
|
|||
session.msg("You must supply a new password.")
|
||||
return
|
||||
|
||||
target_obj = functions_db.standard_plr_objsearch(session, searchstring)
|
||||
target_obj = Objects.object.standard_plr_objsearch(session, searchstring)
|
||||
# Use standard_plr_objsearch to handle duplicate/nonexistant results.
|
||||
if not target_obj:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
from django.contrib.auth.models import User
|
||||
from apps.objects.models import Attribute, Object
|
||||
import functions_db
|
||||
import functions_general
|
||||
import defines_global
|
||||
|
||||
"""
|
||||
Commands that are available from the connect screen.
|
||||
"""
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from apps.objects.models import Attribute, Object
|
||||
import functions_general
|
||||
import defines_global
|
||||
|
||||
def cmd_connect(cdat):
|
||||
"""
|
||||
|
|
@ -24,7 +23,7 @@ def cmd_connect(cdat):
|
|||
password = cdat['uinput']['splitted'][2]
|
||||
|
||||
# Match an email address to an account.
|
||||
email_matches = functions_db.get_user_from_email(uemail)
|
||||
email_matches = Object.objects.get_user_from_email(uemail)
|
||||
|
||||
autherror = "Specified email does not match any accounts!"
|
||||
# No username match
|
||||
|
|
@ -71,7 +70,7 @@ def cmd_create(cdat):
|
|||
# Search for a user object with the specified username.
|
||||
account = User.objects.filter(username=uname)
|
||||
# Match an email address to an account.
|
||||
email_matches = functions_db.get_user_from_email(email)
|
||||
email_matches = Object.objects.get_user_from_email(email)
|
||||
# Look for any objects with an 'Alias' attribute that matches
|
||||
# the requested username
|
||||
alias_matches = Object.objects.filter(attribute__attr_name__exact="ALIAS",
|
||||
|
|
@ -85,7 +84,7 @@ def cmd_create(cdat):
|
|||
elif len(password) < 3:
|
||||
session.msg("Your password must be 3 characters or longer.")
|
||||
else:
|
||||
functions_db.create_user(cdat, uname, email, password)
|
||||
Object.objects.create_user(cdat, uname, email, password)
|
||||
|
||||
def cmd_quit(cdat):
|
||||
"""
|
||||
|
|
|
|||
378
functions_db.py
378
functions_db.py
|
|
@ -1,378 +0,0 @@
|
|||
import sets
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from django.db import connection
|
||||
from django.contrib.auth.models import User
|
||||
from django.db.models import Q
|
||||
|
||||
from apps.objects.models import Object, Attribute
|
||||
from apps.config.models import ConfigValue
|
||||
import defines_global
|
||||
|
||||
"""
|
||||
Common database functions.
|
||||
"""
|
||||
def num_total_players():
|
||||
"""
|
||||
Returns the total number of registered players.
|
||||
"""
|
||||
return User.objects.count()
|
||||
|
||||
def get_connected_players():
|
||||
"""
|
||||
Returns the a QuerySet containing the currently connected players.
|
||||
"""
|
||||
return Object.objects.filter(nosave_flags__contains="CONNECTED")
|
||||
|
||||
def get_recently_created_players(days=7):
|
||||
"""
|
||||
Returns a QuerySet containing the player User accounts that have been
|
||||
connected within the last <days> days.
|
||||
"""
|
||||
end_date = datetime.now()
|
||||
tdelta = timedelta(days)
|
||||
start_date = end_date - tdelta
|
||||
return User.objects.filter(date_joined__range=(start_date, end_date))
|
||||
|
||||
def get_recently_connected_players(days=7):
|
||||
"""
|
||||
Returns a QuerySet containing the player User accounts that have been
|
||||
connected within the last <days> days.
|
||||
"""
|
||||
end_date = datetime.now()
|
||||
tdelta = timedelta(days)
|
||||
start_date = end_date - tdelta
|
||||
return User.objects.filter(last_login__range=(start_date, end_date)).order_by('-last_login')
|
||||
|
||||
def is_unsavable_flag(flagname):
|
||||
"""
|
||||
Returns TRUE if the flag is an unsavable flag.
|
||||
"""
|
||||
return flagname.upper() in defines_global.NOSAVE_FLAGS
|
||||
|
||||
def is_modifiable_flag(flagname):
|
||||
"""
|
||||
Check to see if a particular flag is modifiable.
|
||||
"""
|
||||
if flagname.upper() not in defines_global.NOSET_FLAGS:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def is_modifiable_attrib(attribname):
|
||||
"""
|
||||
Check to see if a particular attribute is modifiable.
|
||||
|
||||
attribname: (string) An attribute name to check.
|
||||
"""
|
||||
if attribname.upper() not in defines_global.NOSET_ATTRIBS:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_nextfree_dbnum():
|
||||
"""
|
||||
Figure out what our next free database reference number is.
|
||||
|
||||
If we need to recycle a GARBAGE object, return the object to recycle
|
||||
Otherwise, return the first free dbref.
|
||||
"""
|
||||
# First we'll see if there's an object of type 6 (GARBAGE) that we
|
||||
# can recycle.
|
||||
nextfree = Object.objects.filter(type__exact=defines_global.OTYPE_GARBAGE)
|
||||
if nextfree:
|
||||
# We've got at least one garbage object to recycle.
|
||||
return nextfree.id
|
||||
else:
|
||||
# No garbage to recycle, find the highest dbnum and increment it
|
||||
# for our next free.
|
||||
return int(Object.objects.order_by('-id')[0].id + 1)
|
||||
|
||||
def global_object_name_search(ostring, exact_match=False):
|
||||
"""
|
||||
Searches through all objects for a name match.
|
||||
"""
|
||||
if exact_match:
|
||||
return Object.objects.filter(name__iexact=ostring).exclude(type=defines_global.OTYPE_GARBAGE)
|
||||
else:
|
||||
return Object.objects.filter(name__icontains=ostring).exclude(type=defines_global.OTYPE_GARBAGE)
|
||||
|
||||
def list_search_object_namestr(searchlist, ostring, dbref_only=False, limit_types=False, match_type="fuzzy"):
|
||||
"""
|
||||
Iterates through a list of objects and returns a list of
|
||||
name matches.
|
||||
searchlist: (List of Objects) The objects to perform name comparisons on.
|
||||
ostring: (string) The string to match against.
|
||||
dbref_only: (bool) Only compare dbrefs.
|
||||
limit_types: (list of int) A list of Object type numbers to filter by.
|
||||
"""
|
||||
if dbref_only:
|
||||
if limit_types:
|
||||
return [prospect for prospect in searchlist if prospect.dbref_match(ostring) and prospect.type in limit_types]
|
||||
else:
|
||||
return [prospect for prospect in searchlist if prospect.dbref_match(ostring)]
|
||||
else:
|
||||
if limit_types:
|
||||
return [prospect for prospect in searchlist if prospect.name_match(ostring, match_type=match_type) and prospect.type in limit_types]
|
||||
else:
|
||||
return [prospect for prospect in searchlist if prospect.name_match(ostring, match_type=match_type)]
|
||||
|
||||
|
||||
def standard_plr_objsearch(session, ostring, search_contents=True, search_location=True, dbref_only=False, limit_types=False):
|
||||
"""
|
||||
Perform a standard object search via a player session, handling multiple
|
||||
results and lack thereof gracefully.
|
||||
|
||||
session: (SessionProtocol) Reference to the player's session.
|
||||
ostring: (str) The string to match object names against.
|
||||
"""
|
||||
pobject = session.get_pobject()
|
||||
results = local_and_global_search(pobject, ostring, search_contents=search_contents, search_location=search_location, dbref_only=dbref_only, limit_types=limit_types)
|
||||
|
||||
if len(results) > 1:
|
||||
session.msg("More than one match found (please narrow target):")
|
||||
for result in results:
|
||||
session.msg(" %s" % (result.get_name(),))
|
||||
return False
|
||||
elif len(results) == 0:
|
||||
session.msg("I don't see that here.")
|
||||
return False
|
||||
else:
|
||||
return results[0]
|
||||
|
||||
def object_totals():
|
||||
"""
|
||||
Returns a dictionary with database object totals.
|
||||
"""
|
||||
dbtotals = {}
|
||||
dbtotals["objects"] = Object.objects.count()
|
||||
dbtotals["things"] = Object.objects.filter(type=defines_global.OTYPE_THING).count()
|
||||
dbtotals["exits"] = Object.objects.filter(type=defines_global.OTYPE_EXIT).count()
|
||||
dbtotals["rooms"] = Object.objects.filter(type=defines_global.OTYPE_ROOM).count()
|
||||
dbtotals["garbage"] = Object.objects.filter(type=defines_global.OTYPE_GARBAGE).count()
|
||||
dbtotals["players"] = Object.objects.filter(type=defines_global.OTYPE_PLAYER).count()
|
||||
return dbtotals
|
||||
|
||||
def alias_search(searcher, ostring):
|
||||
"""
|
||||
Search players by alias. Returns a list of objects whose "ALIAS" attribute
|
||||
exactly (not case-sensitive) matches ostring.
|
||||
|
||||
searcher: (Object) The object doing the searching.
|
||||
ostring: (string) The alias string to search for.
|
||||
"""
|
||||
search_query = ''.join(ostring)
|
||||
results = Attribute.objects.select_related().filter(attr_name__exact="ALIAS").filter(attr_value__iexact=ostring)
|
||||
return [prospect.get_object() for prospect in results if prospect.get_object().is_player()]
|
||||
|
||||
def player_name_search(search_string):
|
||||
"""
|
||||
Combines an alias and global search for a player's name. If there are
|
||||
no alias matches, do a global search limiting by type PLAYER.
|
||||
|
||||
search_string: (string) The name string to search for.
|
||||
"""
|
||||
# Handle the case where someone might have started the search_string
|
||||
# with a *
|
||||
if search_string.startswith('*') is True:
|
||||
search_string = search_string[1:]
|
||||
# Use Q objects to build complex OR query to look at either
|
||||
# the player name or ALIAS attribute
|
||||
player_filter = Q(name__iexact=search_string)
|
||||
alias_filter = Q(attribute__attr_name__exact="ALIAS") & \
|
||||
Q(attribute__attr_value__iexact=search_string)
|
||||
player_matches = Object.objects.filter(
|
||||
player_filter | alias_filter).filter(
|
||||
type=defines_global.OTYPE_PLAYER).distinct()
|
||||
try:
|
||||
return player_matches[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def dbref_search(dbref_string, limit_types=False):
|
||||
"""
|
||||
Searches for a given dbref.
|
||||
|
||||
dbref_number: (string) The dbref to search for
|
||||
limit_types: (list of int) A list of Object type numbers to filter by.
|
||||
"""
|
||||
if not is_dbref(dbref_string):
|
||||
return None
|
||||
dbref_string = dbref_string[1:]
|
||||
dbref_matches = Object.objects.filter(id=dbref_string).exclude(
|
||||
type=defines_global.OTYPE_GARBAGE)
|
||||
# Check for limiters
|
||||
if limit_types is not False:
|
||||
for limiter in limit_types:
|
||||
dbref_matches.filter(type=limiter)
|
||||
try:
|
||||
return dbref_matches[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def local_and_global_search(searcher, ostring, search_contents=True, search_location=True, dbref_only=False, limit_types=False):
|
||||
"""
|
||||
Searches an object's location then globally for a dbref or name match.
|
||||
|
||||
searcher: (Object) The object performing the search.
|
||||
ostring: (string) The string to compare names against.
|
||||
search_contents: (bool) While true, check the contents of the searcher.
|
||||
search_location: (bool) While true, check the searcher's surroundings.
|
||||
dbref_only: (bool) Only compare dbrefs.
|
||||
limit_types: (list of int) A list of Object type numbers to filter by.
|
||||
"""
|
||||
search_query = ''.join(ostring)
|
||||
|
||||
# This is a global dbref search. Not applicable if we're only searching
|
||||
# searcher's contents/locations, dbref comparisons for location/contents
|
||||
# searches are handled by list_search_object_namestr() below.
|
||||
if is_dbref(ostring):
|
||||
search_num = search_query[1:]
|
||||
dbref_match = dbref_search(search_num, limit_types)
|
||||
if dbref_match is not None:
|
||||
return [dbref_match]
|
||||
|
||||
# If the search string is one of the following, return immediately with
|
||||
# the appropriate result.
|
||||
if searcher.get_location().dbref_match(ostring) or ostring == 'here':
|
||||
return [searcher.get_location()]
|
||||
elif ostring == 'me' and searcher:
|
||||
return [searcher]
|
||||
|
||||
if search_query[0] == "*":
|
||||
# Player search- gotta search by name or alias
|
||||
search_target = search_query[1:]
|
||||
player_match = player_name_search(search_target)
|
||||
if player_match is not None:
|
||||
return [player_match]
|
||||
|
||||
local_matches = []
|
||||
# Handle our location/contents searches. list_search_object_namestr() does
|
||||
# name and dbref comparisons against search_query.
|
||||
if search_contents:
|
||||
local_matches += list_search_object_namestr(searcher.get_contents(), search_query, limit_types)
|
||||
if search_location:
|
||||
local_matches += list_search_object_namestr(searcher.get_location().get_contents(), search_query, limit_types=limit_types)
|
||||
return local_matches
|
||||
|
||||
def is_dbref(dbstring):
|
||||
"""
|
||||
Is the input a well-formed dbref number?
|
||||
"""
|
||||
try:
|
||||
number = int(dbstring[1:])
|
||||
except ValueError:
|
||||
return False
|
||||
if not dbstring.startswith("#"):
|
||||
return False
|
||||
elif number < 1:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def get_user_from_email(uemail):
|
||||
"""
|
||||
Returns a player's User object when given an email address.
|
||||
"""
|
||||
return User.objects.filter(email__iexact=uemail)
|
||||
|
||||
def get_object_from_dbref(dbref):
|
||||
"""
|
||||
Returns an object when given a dbref.
|
||||
"""
|
||||
return Object.objects.get(id=dbref)
|
||||
|
||||
def create_object(odat):
|
||||
"""
|
||||
Create a new object. odat is a dictionary that contains the following keys.
|
||||
REQUIRED KEYS:
|
||||
* type: Integer representing the object's type.
|
||||
* name: The name of the new object.
|
||||
* location: Reference to another object for the new object to reside in.
|
||||
* owner: The creator of the object.
|
||||
OPTIONAL KEYS:
|
||||
* home: Reference to another object to home to. If not specified, use
|
||||
location key for home.
|
||||
"""
|
||||
next_dbref = get_nextfree_dbnum()
|
||||
new_object = Object()
|
||||
|
||||
new_object.id = next_dbref
|
||||
new_object.type = odat["type"]
|
||||
new_object.set_name(odat["name"])
|
||||
|
||||
# If this is a player, we don't want him owned by anyone.
|
||||
# The get_owner() function will return that the player owns
|
||||
# himself.
|
||||
if odat["type"] == 1:
|
||||
new_object.owner = None
|
||||
new_object.zone = None
|
||||
else:
|
||||
new_object.owner = odat["owner"]
|
||||
|
||||
if new_object.get_owner().get_zone():
|
||||
new_object.zone = new_object.get_owner().get_zone()
|
||||
|
||||
# If we have a 'home' key, use that for our home value. Otherwise use
|
||||
# the location key.
|
||||
if odat.has_key("home"):
|
||||
new_object.home = odat["home"]
|
||||
else:
|
||||
if new_object.is_exit():
|
||||
new_object.home = None
|
||||
else:
|
||||
new_object.home = odat["location"]
|
||||
|
||||
new_object.save()
|
||||
|
||||
# Rooms have a NULL location.
|
||||
if not new_object.is_room():
|
||||
new_object.move_to(odat['location'])
|
||||
|
||||
return new_object
|
||||
|
||||
def create_user(cdat, uname, email, password):
|
||||
"""
|
||||
Handles the creation of new users.
|
||||
"""
|
||||
session = cdat['session']
|
||||
server = cdat['server']
|
||||
start_room = int(ConfigValue.objects.get_configvalue('player_dbnum_start'))
|
||||
start_room_obj = get_object_from_dbref(start_room)
|
||||
|
||||
# The user's entry in the User table must match up to an object
|
||||
# on the object table. The id's are the same, we need to figure out
|
||||
# the next free unique ID to use and make sure the two entries are
|
||||
# the same number.
|
||||
uid = get_nextfree_dbnum()
|
||||
print 'UID', uid
|
||||
|
||||
# If this is an object, we know to recycle it since it's garbage. We'll
|
||||
# pluck the user ID from it.
|
||||
if not str(uid).isdigit():
|
||||
uid = uid.id
|
||||
print 'UID2', uid
|
||||
|
||||
user = User.objects.create_user(uname, email, password)
|
||||
# It stinks to have to do this but it's the only trivial way now.
|
||||
user.save()
|
||||
|
||||
# We can't use the user model to change the id because of the way keys
|
||||
# are handled, so we actually need to fall back to raw SQL. Boo hiss.
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("UPDATE auth_user SET id=%d WHERE id=%d" % (uid, user.id))
|
||||
|
||||
# Grab the user object again since we've changed it and the old reference
|
||||
# is no longer valid.
|
||||
user = User.objects.get(id=uid)
|
||||
|
||||
# Create a player object of the same ID in the Objects table.
|
||||
odat = {"id": uid, "name": uname, "type": 1, "location": start_room_obj, "owner": None}
|
||||
user_object = create_object(odat)
|
||||
|
||||
# Activate the player's session and set them loose.
|
||||
session.login(user)
|
||||
print 'Registration: %s' % (session,)
|
||||
session.msg("Welcome to %s, %s.\n\r" % (
|
||||
ConfigValue.objects.get_configvalue('site_name'),
|
||||
session.get_pobject().get_name(show_dbref=False)))
|
||||
10
session.py
10
session.py
|
|
@ -1,15 +1,19 @@
|
|||
import time, sys
|
||||
"""
|
||||
This module contains classes related to Sessions. session_mgr has the things
|
||||
needed to manage them.
|
||||
"""
|
||||
import time
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from django.utils import simplejson
|
||||
|
||||
from twisted.conch.telnet import StatefulTelnetProtocol
|
||||
|
||||
from django.utils import simplejson
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from apps.objects.models import Object
|
||||
from apps.config.models import ConnectScreen, ConfigValue
|
||||
import cmdhandler
|
||||
import functions_db
|
||||
import functions_general
|
||||
import functions_log
|
||||
import session_mgr
|
||||
|
|
|
|||
0
src/__init__.py
Normal file
0
src/__init__.py
Normal file
11
src/exceptions_generic.py
Normal file
11
src/exceptions_generic.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
"""
|
||||
This module contains exceptions used throughout the server
|
||||
"""
|
||||
class GenericException(Exception):
|
||||
"""
|
||||
The custom exception class from which all other exceptions are derived.
|
||||
"""
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
def __str__(self):
|
||||
return repr(self.value)
|
||||
19
src/flags.py
Normal file
19
src/flags.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
"""
|
||||
Everything related to flags and flag management.
|
||||
"""
|
||||
import defines_global
|
||||
|
||||
def is_unsavable_flag(flagname):
|
||||
"""
|
||||
Returns TRUE if the flag is an unsavable flag.
|
||||
"""
|
||||
return flagname.upper() in defines_global.NOSAVE_FLAGS
|
||||
|
||||
def is_modifiable_flag(flagname):
|
||||
"""
|
||||
Check to see if a particular flag is modifiable.
|
||||
"""
|
||||
if flagname.upper() not in defines_global.NOSET_FLAGS:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
Loading…
Add table
Add a link
Reference in a new issue