Contrib: Added a new, alternative login system, using menus. Also edited the ways unlogged commands are started by the engine, by using a standardized system command name (it does not need to be "look" anymore).

This commit is contained in:
Griatch 2011-11-06 18:53:10 +01:00
parent 2b2d27ed39
commit 55f6f5b713
6 changed files with 81 additions and 15 deletions

View file

@ -149,15 +149,19 @@ class MenuTree(object):
'START' and 'END' respectively.
"""
def __init__(self, caller, nodes=None, startnode="START", endnode="END"):
def __init__(self, caller, nodes=None, startnode="START", endnode="END", exec_end="look"):
"""
We specify startnode/endnode so that the system knows where to
enter and where to exit the menu tree. If nodes is given, it
shuld be a list of valid node objects to add to the tree.
exec_end - if not None, will execute the given command string
directly after the menu system has been exited.
"""
self.tree = {}
self.startnode = startnode
self.endnode = endnode
self.exec_end = exec_end
self.caller = caller
if nodes and utils.is_iter(nodes):
for node in nodes:
@ -186,7 +190,8 @@ class MenuTree(object):
# if we was given the END node key, we clean up immediately.
self.caller.cmdset.delete("menucmdset")
del self.caller.db._menu_data
self.caller.execute_cmd("look")
if self.exec_end != None:
self.caller.execute_cmd(self.exec_end)
return
# not exiting, look for a valid code.
node = self.tree.get(key, None)

View file

@ -128,7 +128,7 @@ class Character(BaseCharacter):
# save location again to be sure
self.db.prelogout_location = self.location
self.location.msg_contents("%s has entered the game." % self.name)
self.location.msg_contents("%s has entered the game." % self.name, exclude=[self])
self.location.at_object_receive(self, self.location)
class Room(BaseRoom):

View file

@ -50,11 +50,17 @@ COMMAND_PARSER = utils.mod_import(*settings.COMMAND_PARSER.rsplit('.', 1))
# allow for custom behaviour when the command handler hits
# special situations -- it then calls a normal Command
# that you can customize!
# Import these variables and use them rather than trying
# to remember the actual string constants.
CMD_NOINPUT = "__noinput_command"
CMD_NOMATCH = "__nomatch_command"
CMD_MULTIMATCH = "__multimatch_command"
CMD_CHANNEL = "__send_to_channel"
CMD_CHANNEL = "__send_to_channel_command"
# this is the name of the command the engine calls when the player
# connects. It is expected to show the login screen.
CMD_LOGINSTART = "__unloggedin_look_command"
class NoCmdSets(Exception):
"No cmdsets found. Critical error."

View file

@ -13,6 +13,7 @@ from src.comms.models import Channel
from src.utils import create, logger, utils, ansi
from src.commands.default.muxcommand import MuxCommand
from src.commands.cmdhandler import CMD_LOGINSTART
CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
@ -221,10 +222,12 @@ class CmdQuit(MuxCommand):
class CmdUnconnectedLook(MuxCommand):
"""
This is an unconnected version of the look command for simplicity.
All it does is re-show the connect screen.
This is called by the server and kicks everything in gear.
All it does is display the connect screen.
"""
key = "look"
aliases = "l"
key = CMD_LOGINSTART
aliases = ["look", "l"]
locks = "cmd:all()"
def func(self):

View file

@ -59,10 +59,6 @@ class ServerSession(Session):
# start (persistent) scripts on this object
ScriptDB.objects.validate(obj=character)
def at_cmdset_get(self):
"dummy hook all objects with cmdsets need to have"
pass
def session_login(self, player):
"""
Startup mechanisms that need to run at login. This is called
@ -96,11 +92,10 @@ class ServerSession(Session):
player.at_pre_login()
character = player.character
#print "at_init() - character"
character.at_init()
if character:
# this player has a character. Check if it's the
# first time *this character* logs in
character.at_init()
if character.db.FIRST_LOGIN:
character.at_first_login()
del character.db.FIRST_LOGIN
@ -190,7 +185,7 @@ class ServerSession(Session):
if str(command_string).strip() == IDLE_COMMAND:
self.update_session_counters(idle=True)
return
# all other inputs, including empty inputs
character = self.get_character()
@ -216,6 +211,7 @@ class ServerSession(Session):
def __eq__(self, other):
return self.address == other.address
def __str__(self):
"""
String representation of the user session class. We use
@ -249,3 +245,57 @@ class ServerSession(Session):
def msg(self, string='', data=None):
"alias for at_data_out"
self.data_out(string, data=data)
# Dummy API hooks for use a non-loggedin operation
def at_cmdset_get(self):
"dummy hook all objects with cmdsets need to have"
pass
# Mock db/ndb properties for allowing easy storage on the session
# (note that no databse is involved at all here. session.db.attr =
# value just saves a normal property in memory, just like ndb).
#@property
def ndb_get(self):
"""
A non-persistent store (ndb: NonDataBase). Everything stored
to this is guaranteed to be cleared when a server is shutdown.
Syntax is same as for the _get_db_holder() method and
property, e.g. obj.ndb.attr = value etc.
"""
try:
return self._ndb_holder
except AttributeError:
class NdbHolder(object):
"Holder for storing non-persistent attributes."
def all(self):
return [val for val in self.__dict__.keys()
if not val.startswith['_']]
def __getattribute__(self, key):
# return None if no matching attribute was found.
try:
return object.__getattribute__(self, key)
except AttributeError:
return None
self._ndb_holder = NdbHolder()
return self._ndb_holder
#@ndb.setter
def ndb_set(self, value):
"Stop accidentally replacing the db object"
string = "Cannot assign directly to ndb object! "
string = "Use ndb.attr=value instead."
raise Exception(string)
#@ndb.deleter
def ndb_del(self):
"Stop accidental deletion."
raise Exception("Cannot delete the ndb object!")
ndb = property(ndb_get, ndb_set, ndb_del)
db = property(ndb_get, ndb_set, ndb_del)
# Mock access method for the session (there is no lock info
# at this stage, so we just present a uniform API)
def access(self, *args, **kwargs):
"Dummy method."
return True

View file

@ -19,6 +19,8 @@ from django.contrib.auth.models import User
from src.server.models import ServerConfig
from src.utils import utils
from src.commands.cmdhandler import CMD_LOGINSTART
# i18n
from django.utils.translation import ugettext as _
@ -94,7 +96,7 @@ class ServerSessionHandler(SessionHandler):
Creates a new, unlogged-in game session.
"""
self.sessions[sessid] = session
session.execute_cmd('look')
session.execute_cmd(CMD_LOGINSTART)
def portal_disconnect(self, sessid):
"""