Big big update. Lots of reorganization and shuffling.

This commit is contained in:
Greg Taylor 2006-12-03 00:25:10 +00:00
parent 43f2167e74
commit 703fddcb7f
9 changed files with 345 additions and 178 deletions

View file

@ -1,6 +1,7 @@
from django.db import models from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
class ObjectClass(models.Model): class ObjectClass(models.Model):
""" """
Each object class can have different behaviors to apply to it. Each object class can have different behaviors to apply to it.
@ -66,21 +67,63 @@ class Object(models.Model):
# attribute's names. # attribute's names.
attrib_list = {} attrib_list = {}
def __str__(self): class Meta:
return "%s(%d)" % (self.name, self.id,) permissions = (
("can_examine", "Can examine objects"),
def is_type(self, typename): )
"""
Do a string comparison of user's input and the object's type class object's
name.
"""
return self.type.name == typename
def set_type(self, typename):
"""
Sets a object's type.
"""
pass
class Admin: class Admin:
list_display = ('name',) list_display = ('name',)
"""
BEGIN COMMON METHODS
"""
def move_to(self, target):
"""
Moves the object to a new location.
"""
self.location.contents_list.remove(self)
self.location = target
target.contents_list.append(self)
self.save()
def dbref_match(self, oname):
import functions_db
"""
Check if the input (oname) can be used to identify this particular object
by means of a dbref match.
"""
if not functions_db.is_dbref(oname):
return False
try:
is_match = int(oname[1:]) == self.id
except ValueError:
return false
return is_match
def name_match(self, oname):
import functions_db
"""
See if the input (oname) can be used to identify this particular object.
Check the # sign for dbref (exact) reference, and anything else is a
name comparison.
NOTE: A 'name' can be a dbref or the actual name of the object. See
dbref_match for an exclusively name-based match.
"""
if oname[0] == '#':
return self.dbref_match(oname)
else:
return oname.lower() in self.name.lower()
def filter_contents_from_str(self, oname):
"""
Search an object's contents for name and dbref matches. Don't put any
logic in here, we'll do that from the end of the command or function.
"""
return [prospect for prospect in self.contents_list if prospect.name_match(oname)]
def __str__(self):
return "%s(%d)" % (self.name, self.id,)

View file

@ -1,168 +1,11 @@
from django.contrib.auth.models import User from commands_staff import StaffCommands
from apps.objects.models import Object from commands_general import GenCommands
import settings from commands_unloggedin import UnLoggedInCommands
import string
from ansi import *
""" """
This is the command processing module. It is instanced once in the main This is the command processing module. It is instanced once in the main
server module and the handle() function is hit every time a player sends server module and the handle() function is hit every time a player sends
something. something.
""" """
class GenCommands:
"""
Generic command class. Pretty much every command should go here for
now.
"""
def do_look(self, cdat):
"""
Handle looking at objects.
"""
session = cdat['session']
server = cdat['server']
player_loc = session.player_loc
player_loc_obj = server.object_list[player_loc]
retval = "%s%s%s%s\n\r%s" % (
ansi["normal"],
ansi["hilite"],
player_loc_obj.name,
ansi["normal"],
player_loc_obj.description,
)
session.msg(retval)
def do_quit(self, cdat):
"""
Gracefully disconnect the user as per his own request.
"""
session = cdat['session']
session.msg("Quitting!")
session.handle_close()
def do_who(self, cdat):
"""
Generic WHO command.
"""
session_list = cdat['server'].session_list
session = cdat['session']
retval = "Player Name\n\r"
for player in session_list:
retval += '%s\n\r' % (player,)
retval += '%d Players logged in.' % (len(session_list),)
session.msg(retval)
def do_say(self, cdat):
"""
Room-based speech command.
"""
session_list = cdat['server'].session_list
session = cdat['session']
speech = cdat['uinput']['splitted'][1:]
players_present = [player for player in session_list if player.player_loc == session.player_loc and player != session]
retval = "You say, '%s'" % (''.join(speech),)
for player in players_present:
player.msg("%s says, '%s'" % (session.name, speech,))
session.msg(retval)
def do_version(self, cdat):
"""
Version info command.
"""
session = cdat['session']
retval = "-"*50 +"\n\r"
retval += "Evennia %s\n\r" % (settings.EVENNIA_VERSION,)
retval += "-"*50
session.msg(retval)
class StaffCommands:
"""
Restricted staff commands.
"""
def do_dig(self, cdat):
"""
Digs a new room out.
"""
session = cdat['session']
uinput= cdat['uinput']
roomname = ''.join(uinput[1:])
if roomname == '':
session.msg("You must supply a room name!")
else:
newroom = Object()
newroom.name = roomname
newroom.type = "Room"
def do_nextfree(self, cdat):
"""
Returns the next free object number.
"""
session = cdat['session']
server = cdat['server']
nextfree = server.get_nextfree_dbnum()
retval = "Next free object number: %s" % (nextfree,)
session.msg(retval)
class UnLoggedInCommands:
"""
Commands that are available from the connect screen.
"""
def do_connect(self, cdat):
"""
This is the connect command at the connection screen. Fairly simple,
uses the Django database API and User model to make it extremely simple.
"""
session = cdat['session']
uname = cdat['uinput']['splitted'][1]
password = cdat['uinput']['splitted'][2]
account = User.objects.filter(username=uname)
user = account[0]
autherror = "Invalid username or password!"
if account.count() == 0:
session.msg(autherror)
if not user.check_password(password):
session.msg(autherror)
else:
uname = user.username
session.login(user)
def do_create(self, cdat):
"""
Handle the creation of new accounts.
"""
session = cdat['session']
server = cdat['server']
uname = cdat['uinput']['splitted'][1]
email = cdat['uinput']['splitted'][2]
password = cdat['uinput']['splitted'][3]
account = User.objects.filter(username=uname)
if not account.count() == 0:
session.msg("There is already a player with that name!")
elif len(password) < 3:
session.msg("Your password must be 3 characters or longer.")
else:
server.create_user(session, uname, email, password)
def do_quit(self, cdat):
"""
We're going to maintain a different version of the quit command
here for unconnected users for the sake of simplicity. The logged in
version will be a bit more complicated.
"""
session = cdat['session']
session.msg("Disconnecting...")
session.handle_close()
# We'll use this for our getattr() in the Handler class. # We'll use this for our getattr() in the Handler class.
gencommands = GenCommands() gencommands = GenCommands()
staffcommands = StaffCommands() staffcommands = StaffCommands()

View file

@ -0,0 +1,72 @@
import settings
from ansi import *
class GenCommands:
"""
Generic command class. Pretty much every command should go here for
now.
"""
def do_look(self, cdat):
"""
Handle looking at objects.
"""
session = cdat['session']
server = cdat['server']
player_loc = session.player_loc
player_loc_obj = server.object_list[player_loc]
retval = "%s%s%s%s\n\r%s" % (
ansi["normal"],
ansi["hilite"],
player_loc_obj.name,
ansi["normal"],
player_loc_obj.description,
)
session.msg(retval)
def do_quit(self, cdat):
"""
Gracefully disconnect the user as per his own request.
"""
session = cdat['session']
session.msg("Quitting!")
session.handle_close()
def do_who(self, cdat):
"""
Generic WHO command.
"""
session_list = cdat['server'].session_list
session = cdat['session']
retval = "Player Name\n\r"
for player in session_list:
retval += '%s\n\r' % (player,)
retval += '%d Players logged in.' % (len(session_list),)
session.msg(retval)
def do_say(self, cdat):
"""
Room-based speech command.
"""
session_list = cdat['server'].session_list
session = cdat['session']
speech = cdat['uinput']['splitted'][1:]
players_present = [player for player in session_list if player.player_loc == session.player_loc and player != session]
retval = "You say, '%s'" % (''.join(speech),)
for player in players_present:
player.msg("%s says, '%s'" % (session.name, speech,))
session.msg(retval)
def do_version(self, cdat):
"""
Version info command.
"""
session = cdat['session']
retval = "-"*50 +"\n\r"
retval += "Evennia %s\n\r" % (settings.EVENNIA_VERSION,)
retval += "-"*50
session.msg(retval)

View file

@ -0,0 +1,95 @@
from apps.objects.models import Object
import functions_db
class StaffCommands:
"""
Restricted staff commands.
"""
def do_dig(self, cdat):
"""
Digs a new room out.
"""
session = cdat['session']
uinput= cdat['uinput']
roomname = ''.join(uinput[1:])
if roomname == '':
session.msg("You must supply a room name!")
else:
newroom = Object()
newroom.name = roomname
newroom.type = "Room"
def do_nextfree(self, cdat):
"""
Returns the next free object number.
"""
session = cdat['session']
server = cdat['server']
nextfree = server.get_nextfree_dbnum()
retval = "Next free object number: %s" % (nextfree,)
session.msg(retval)
def do_teleport(self, cdat):
"""
Teleports an object somewhere.
"""
session = cdat['session']
pobject = session.pobject
server = cdat['server']
args = cdat['uinput']['splitted'][1:]
if len(args) == 0:
session.msg("Teleport where/what?")
return
eq_args = args[0].split('=')
# If we have more than one entry in our '=' delimited argument list,
# then we're doing a @tel <victim>=<location>. If not, we're doing
# a direct teleport, @tel <destination>.
if len(eq_args) > 1:
session.msg("Equal sign present.")
else:
session.msg("No equal sign, direct tport.")
results = functions_db.local_and_global_search(pobject, ''.join(args))
if len(results) > 1:
session.msg("More than one match found (please narrow target):")
for result in results:
session.msg(" %s(#%s)" % (result.name, result.id,))
elif len(results) == 0:
session.msg("I don't see that here.")
else:
session.msg("Teleported.")
pobject.move_to(results[0])
#GenCommands.do_look(cdat)
#session.msg("Args: %s\n\rEqargs: %s" % (args, eq_args,))
def do_find(self, cdat):
"""
Searches for an object of a particular name.
"""
session = cdat['session']
server = cdat['server']
searchstring = ''.join(cdat['uinput']['splitted'][1:])
if searchstring == '':
session.msg("No search pattern given.")
return
memory_based = True
if memory_based:
results = functions_db.list_search_object_namestr(server.object_list.values(), searchstring)
if len(results) > 0:
session.msg("Name matches for: %s" % (searchstring,))
for result in results:
session.msg(" %s(#%s)" % (result.name, result.id,))
session.msg("%d matches returned." % (len(results),))
else:
session.msg("No name matches found for: %s" % (searchstring,))

View file

@ -0,0 +1,54 @@
from django.contrib.auth.models import User
class UnLoggedInCommands:
"""
Commands that are available from the connect screen.
"""
def do_connect(self, cdat):
"""
This is the connect command at the connection screen. Fairly simple,
uses the Django database API and User model to make it extremely simple.
"""
session = cdat['session']
uname = cdat['uinput']['splitted'][1]
password = cdat['uinput']['splitted'][2]
account = User.objects.filter(username=uname)
user = account[0]
autherror = "Invalid username or password!"
if account.count() == 0:
session.msg(autherror)
if not user.check_password(password):
session.msg(autherror)
else:
uname = user.username
session.login(user)
def do_create(self, cdat):
"""
Handle the creation of new accounts.
"""
session = cdat['session']
server = cdat['server']
uname = cdat['uinput']['splitted'][1]
email = cdat['uinput']['splitted'][2]
password = cdat['uinput']['splitted'][3]
account = User.objects.filter(username=uname)
if not account.count() == 0:
session.msg("There is already a player with that name!")
elif len(password) < 3:
session.msg("Your password must be 3 characters or longer.")
else:
server.create_user(session, uname, email, password)
def do_quit(self, cdat):
"""
We're going to maintain a different version of the quit command
here for unconnected users for the sake of simplicity. The logged in
version will be a bit more complicated.
"""
session = cdat['session']
session.msg("Disconnecting...")
session.handle_close()

View file

@ -1,4 +1,4 @@
from apps.objects.models import Object, Attribute from apps.objects.models import Object, Attribute
def object_find_neighbor(searcher, target_string): def list_search_object_str(searchlist, ostring):
pass [prospect for prospect in searchlist if prospect.name_match(ostring)]

View file

@ -0,0 +1,47 @@
from apps.objects.models import Object
def list_search_object_namestr(searchlist, ostring, dbref_only=False):
"""
Iterates through a list of objects and returns a list of
name matches.
"""
if dbref_only:
return [prospect for prospect in searchlist if prospect.dbref_match(ostring)]
else:
return [prospect for prospect in searchlist if prospect.name_match(ostring)]
def local_and_global_search(object, ostring):
"""
Searches an object's location then globally for a dbref or name match.
"""
search_query = ''.join(ostring)
local_matches = list_search_object_namestr(object.location.contents_list, search_query)
# If the object the invoker is in matches, add it as well.
if object.location.dbref_match(ostring) or ostring == 'here':
local_matches.append(object.location)
global_matches = []
if is_dbref(ostring):
global_matches = list(Object.objects.filter(id=search_query))
return local_matches + global_matches
def is_dbref(dbstring):
"""
Is the input a well-formed dbref number?
"""
try:
number = int(dbstring[1:])
except ValueError:
return False
if dbstring[0] != '#':
return False
elif number < 1:
return False
else:
return True

View file

@ -51,6 +51,7 @@ class Server(dispatcher):
# Load stuff up into memory for easy/quick access. # Load stuff up into memory for easy/quick access.
self.load_configvalues() self.load_configvalues()
self.load_objects() self.load_objects()
self.load_objects_contents()
self.load_attributes() self.load_attributes()
self.load_cmd_aliases() self.load_cmd_aliases()
@ -87,7 +88,19 @@ class Server(dispatcher):
dbnum = object.id dbnum = object.id
self.object_list[dbnum] = object self.object_list[dbnum] = object
print ' Objects Loaded: %d' % (len(self.object_list),) print ' Objects Loaded: %d' % (len(self.object_list),)
def load_objects_contents(self):
"""
Populate the 'contents_list' list for each object.
TODO: Make this a lot more efficient or merge into
load_objects.
"""
for key, object in self.object_list.iteritems():
if object.location:
object.location.contents_list.append(object)
print ' * Object Inventories Populated'
def load_attributes(self): def load_attributes(self):
""" """
Load all of our attributes into memory. Load all of our attributes into memory.

View file

@ -81,7 +81,7 @@ class PlayerSession(async_chat):
""" """
After the user has authenticated, handle logging him in. After the user has authenticated, handle logging him in.
""" """
self.pobject = user self.pobject = Object.objects.filter(id=user.id)[0]
self.name = user.username self.name = user.username
self.logged_in = True self.logged_in = True
self.conn_time = time.time() self.conn_time = time.time()