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.
|
||||
|
||||
"""
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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."
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue