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:
parent
2b2d27ed39
commit
55f6f5b713
6 changed files with 81 additions and 15 deletions
|
|
@ -149,15 +149,19 @@ class MenuTree(object):
|
||||||
'START' and 'END' respectively.
|
'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
|
We specify startnode/endnode so that the system knows where to
|
||||||
enter and where to exit the menu tree. If nodes is given, it
|
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.
|
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.tree = {}
|
||||||
self.startnode = startnode
|
self.startnode = startnode
|
||||||
self.endnode = endnode
|
self.endnode = endnode
|
||||||
|
self.exec_end = exec_end
|
||||||
self.caller = caller
|
self.caller = caller
|
||||||
if nodes and utils.is_iter(nodes):
|
if nodes and utils.is_iter(nodes):
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
|
|
@ -186,7 +190,8 @@ class MenuTree(object):
|
||||||
# if we was given the END node key, we clean up immediately.
|
# if we was given the END node key, we clean up immediately.
|
||||||
self.caller.cmdset.delete("menucmdset")
|
self.caller.cmdset.delete("menucmdset")
|
||||||
del self.caller.db._menu_data
|
del self.caller.db._menu_data
|
||||||
self.caller.execute_cmd("look")
|
if self.exec_end != None:
|
||||||
|
self.caller.execute_cmd(self.exec_end)
|
||||||
return
|
return
|
||||||
# not exiting, look for a valid code.
|
# not exiting, look for a valid code.
|
||||||
node = self.tree.get(key, None)
|
node = self.tree.get(key, None)
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ class Character(BaseCharacter):
|
||||||
# save location again to be sure
|
# save location again to be sure
|
||||||
self.db.prelogout_location = self.location
|
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)
|
self.location.at_object_receive(self, self.location)
|
||||||
|
|
||||||
class Room(BaseRoom):
|
class Room(BaseRoom):
|
||||||
|
|
|
||||||
|
|
@ -50,11 +50,17 @@ COMMAND_PARSER = utils.mod_import(*settings.COMMAND_PARSER.rsplit('.', 1))
|
||||||
# allow for custom behaviour when the command handler hits
|
# allow for custom behaviour when the command handler hits
|
||||||
# special situations -- it then calls a normal Command
|
# special situations -- it then calls a normal Command
|
||||||
# that you can customize!
|
# that you can customize!
|
||||||
|
# Import these variables and use them rather than trying
|
||||||
|
# to remember the actual string constants.
|
||||||
|
|
||||||
CMD_NOINPUT = "__noinput_command"
|
CMD_NOINPUT = "__noinput_command"
|
||||||
CMD_NOMATCH = "__nomatch_command"
|
CMD_NOMATCH = "__nomatch_command"
|
||||||
CMD_MULTIMATCH = "__multimatch_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):
|
class NoCmdSets(Exception):
|
||||||
"No cmdsets found. Critical error."
|
"No cmdsets found. Critical error."
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ from src.comms.models import Channel
|
||||||
|
|
||||||
from src.utils import create, logger, utils, ansi
|
from src.utils import create, logger, utils, ansi
|
||||||
from src.commands.default.muxcommand import MuxCommand
|
from src.commands.default.muxcommand import MuxCommand
|
||||||
|
from src.commands.cmdhandler import CMD_LOGINSTART
|
||||||
|
|
||||||
CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
|
CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
|
||||||
|
|
||||||
|
|
@ -221,10 +222,12 @@ class CmdQuit(MuxCommand):
|
||||||
class CmdUnconnectedLook(MuxCommand):
|
class CmdUnconnectedLook(MuxCommand):
|
||||||
"""
|
"""
|
||||||
This is an unconnected version of the look command for simplicity.
|
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"
|
key = CMD_LOGINSTART
|
||||||
aliases = "l"
|
aliases = ["look", "l"]
|
||||||
locks = "cmd:all()"
|
locks = "cmd:all()"
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
|
|
|
||||||
|
|
@ -59,10 +59,6 @@ class ServerSession(Session):
|
||||||
# start (persistent) scripts on this object
|
# start (persistent) scripts on this object
|
||||||
ScriptDB.objects.validate(obj=character)
|
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):
|
def session_login(self, player):
|
||||||
"""
|
"""
|
||||||
Startup mechanisms that need to run at login. This is called
|
Startup mechanisms that need to run at login. This is called
|
||||||
|
|
@ -96,11 +92,10 @@ class ServerSession(Session):
|
||||||
player.at_pre_login()
|
player.at_pre_login()
|
||||||
|
|
||||||
character = player.character
|
character = player.character
|
||||||
#print "at_init() - character"
|
|
||||||
character.at_init()
|
|
||||||
if character:
|
if character:
|
||||||
# this player has a character. Check if it's the
|
# this player has a character. Check if it's the
|
||||||
# first time *this character* logs in
|
# first time *this character* logs in
|
||||||
|
character.at_init()
|
||||||
if character.db.FIRST_LOGIN:
|
if character.db.FIRST_LOGIN:
|
||||||
character.at_first_login()
|
character.at_first_login()
|
||||||
del character.db.FIRST_LOGIN
|
del character.db.FIRST_LOGIN
|
||||||
|
|
@ -190,7 +185,7 @@ class ServerSession(Session):
|
||||||
if str(command_string).strip() == IDLE_COMMAND:
|
if str(command_string).strip() == IDLE_COMMAND:
|
||||||
self.update_session_counters(idle=True)
|
self.update_session_counters(idle=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
# all other inputs, including empty inputs
|
# all other inputs, including empty inputs
|
||||||
character = self.get_character()
|
character = self.get_character()
|
||||||
|
|
||||||
|
|
@ -216,6 +211,7 @@ class ServerSession(Session):
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return self.address == other.address
|
return self.address == other.address
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""
|
"""
|
||||||
String representation of the user session class. We use
|
String representation of the user session class. We use
|
||||||
|
|
@ -249,3 +245,57 @@ class ServerSession(Session):
|
||||||
def msg(self, string='', data=None):
|
def msg(self, string='', data=None):
|
||||||
"alias for at_data_out"
|
"alias for at_data_out"
|
||||||
self.data_out(string, data=data)
|
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
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ from django.contrib.auth.models import User
|
||||||
from src.server.models import ServerConfig
|
from src.server.models import ServerConfig
|
||||||
from src.utils import utils
|
from src.utils import utils
|
||||||
|
|
||||||
|
from src.commands.cmdhandler import CMD_LOGINSTART
|
||||||
|
|
||||||
# i18n
|
# i18n
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
|
|
@ -94,7 +96,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
Creates a new, unlogged-in game session.
|
Creates a new, unlogged-in game session.
|
||||||
"""
|
"""
|
||||||
self.sessions[sessid] = session
|
self.sessions[sessid] = session
|
||||||
session.execute_cmd('look')
|
session.execute_cmd(CMD_LOGINSTART)
|
||||||
|
|
||||||
def portal_disconnect(self, sessid):
|
def portal_disconnect(self, sessid):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue