Restructure the node logic in evmenu_login

This commit is contained in:
Vincent Le Goff 2016-04-18 16:33:29 -07:00 committed by Griatch
parent 41ad2aed5d
commit bf50f5b94a

View file

@ -73,7 +73,7 @@ def start(caller):
{ {
"key": "new", "key": "new",
"desc": "Create a new character.", "desc": "Create a new character.",
"goto": "create_username", "goto": "create_account",
}, },
{ {
"key": "_default", "key": "_default",
@ -86,65 +86,110 @@ def start(caller):
def username(caller, input): def username(caller, input):
"""Check that the username leads to an existing player. """Check that the username leads to an existing player.
This is a temporary node. If the username doesn't exist, Check that the specified username exists. If the username doesn't
go to the first node. If it does exist, move to the next exist, display an error message and ask the user to either
node (enter password). enter 'b' to go back, or to try again.
If it does exist, move to the next node (enter password).
""" """
input = input.strip() input = input.strip()
player = managers.players.get_player_from_name(input) player = managers.players.get_player_from_name(input)
if not player: if player is None:
string = dedent(""" text = dedent("""
|rThe username {} doesn't exist yet. Have you created it?|n |rThe username {} doesn't exist yet. Have you created it?|n
Type |yb|n to go back to the previous menu.
Or try another name.
""".strip("\n")).format(input) """.strip("\n")).format(input)
caller.msg(string) options = (
{
# Return to the first node "key": "b",
return start(caller) "desc": "Back to the previous menu.",
"goto": "start",
},
{
"key": "_default",
"desc": "Try again.",
"goto": "username",
},
)
else: else:
# Saves the player in the menutree
caller.ndb._menutree.player = player caller.ndb._menutree.player = player
text = "Enter the password for the {} account.".format(player.name)
# Disables echo for the password # Disables echo for the password
caller.msg(echo=False) caller.msg(echo=False)
# Redirects to the password's node caller.msg(echo=False)
return password(caller, None) options = (
{
"key": "_default",
"desc": "Enter your account's password.",
"goto": "password",
},
)
return text, options
def password(caller, input): def password(caller, input):
"""Ask the password to enter the password to this player. """Ask the user to enter the password to this player.
This is assuming the user exists (see 'create_username' and This is assuming the user exists (see 'create_username' and
'create_password'). This node "loops" if needed: if the 'create_password'). This node "loops" if needed: if the
user specifies a wrong password, the user doesn't leave this user specifies a wrong password, offers the user to try
menu and is prompted again for the password (you might like again or to go back by entering 'b'.
to do more checks here, perhaps send warnings or add delays). If the password is correct, then login.
""" """
menutree = caller.ndb._menutree menutree = caller.ndb._menutree
if input is None:
text = "Enter this account's password :"
else:
caller.msg(echo=True) caller.msg(echo=True)
input = input.strip() input = input.strip()
options = (
{
"key": "_default",
"desc": "Enter your password.",
"goto": "password",
},
)
# Check the password and login if correct # Check the password and login if correct
if not hasattr(menutree, "player"): if not hasattr(menutree, "player"):
caller.msg(dedent(""" text = dedent("""
|rSomething went wrong! The player was not remembered |rSomething went wrong! The player was not remembered
from last step!|n from last step!|n
""".strip("\n"))) Press RETURN to continue.
""".strip("\n"))
# Redirects to the first node # Redirects to the first node
return start(caller) options = (
{
"key": "_default",
"desc": "Press RETURN to continue.",
"goto": "start",
},
)
else:
player = menutree.player player = menutree.player
bans = ServerConfig.objects.conf("server_bans")
banned = bans and (any(tup[0] == player.name.lower() for tup in bans) \
or any(tup[2].match(caller.address) for tup in bans if tup[2]))
if not player.check_password(input): if not player.check_password(input):
caller.msg(echo=False) caller.msg(echo=False)
caller.msg("|rIncorrect password.|n") text = dedent("""
|rIncorrect password.|n
Type |yb|n to go back to the login screen.
Or enter your password again.
""".strip("\n"))
# Loops on the same node # Loops on the same node
return password(caller, None) options = (
{
# Before going on, check eventual bans "key": "b",
bans = ServerConfig.objects.conf("server_bans") "desc": "Go back to the login screen.",
if bans and (any(tup[0] == player.name.lower() for tup in bans) or \ "goto": "start",
any(tup[2].match(caller.address) for tup in bans if tup[2])): },
{
"key": "_default",
"desc": "Enter your password again.",
"goto": "password",
},
)
elif banned:
# This is a banned IP or name! # This is a banned IP or name!
string = dedent(""" string = dedent("""
|rYou have been banned and cannot continue from here. |rYou have been banned and cannot continue from here.
@ -155,17 +200,34 @@ def password(caller, input):
caller, "Good bye! Disconnecting...") caller, "Good bye! Disconnecting...")
# This is not necessary, since the player is disconnected, # This is not necessary, since the player is disconnected,
# but it seems to raise an error if simply returning None, None # but it seems to raise an error if simply returning None, None
return password(caller, None) text = ""
options = (
{
"key": "_default",
"desc": "Go back to the login screen.",
"goto": "start",
},
)
else:
# We are OK, log us in. # We are OK, log us in.
text = "" text = ""
caller.sessionhandler.login(caller, player) caller.sessionhandler.login(caller, player)
return text, options
def create_account(caller):
"""Create a new account.
This node simply prompts the user to entere a username.
The input is redirected to 'create_username'.
"""
text = "Enter your new account's name."
options = ( options = (
{ {
"key": "_default", "key": "_default",
"desc": "Enter your password.", "desc": "Enter your new username.",
"goto": "password", "goto": "create_username",
}, },
) )
return text, options return text, options
@ -173,55 +235,79 @@ def password(caller, input):
def create_username(caller, input): def create_username(caller, input):
"""Prompt to enter a valid username (one that doesnt exist). """Prompt to enter a valid username (one that doesnt exist).
This node is called when the user enters 'NEW' after connecting. 'input' contains the new username. If it exists, prompt
This node also "loops": as long as the user doesn't enter a the username to retry or go back to the login screen.
valid username, the menu repeats itself.
""" """
menutree = caller.ndb._menutree menutree = caller.ndb._menutree
if input and input.lower().strip() == "new":
# If the user just entered 'NEW', assumes it's the
# begginning of the node
input = None
if input is None:
text = "Enter the name of the character you would like to create."
else:
input = input.strip() input = input.strip()
player = managers.players.get_player_from_name(input) player = managers.players.get_player_from_name(input)
options = (
{
"key": "_default",
"desc": "Enter your new account's password.",
"goto": "create_password",
},
)
# If a player with that name exists, a new one will not be created # If a player with that name exists, a new one will not be created
if player: if player:
caller.msg(dedent(""" text = dedent("""
|rThe account {} already exists, try another one.|n |rThe account {} already exists.|n
""".strip("\n")).format(input)) Type |yb|n to go back to the login screen.
Or enter another username to create.
""".strip("\n")).format(input)
# Loops on the same node # Loops on the same node
return create_username(caller, None) options = (
{
"key": "b",
"desc": "Go back to the login screen.",
"goto": "start",
},
{
"key": "_default",
"desc": "Enter another username.",
"goto": "create_username",
},
)
elif not RE_VALID_USERNAME.search(input): elif not RE_VALID_USERNAME.search(input):
caller.msg(dedent(""" text = dedent("""
|rThis username isn't valid.|n Only letters are accepted, |rThis username isn't valid.|n
without special characters. The username must be Only letters are accepted, without special characters.
at least 3 characters long. The username must be at least 3 characters long.
""".strip("\n"))) Type |yb|n to go back to the login screen.
return create_username(caller, None) Or enter another username to be created.
""".strip("\n"))
options = (
{
"key": "b",
"desc": "Go back to the login screen.",
"goto": "start",
},
{
"key": "_default",
"desc": "Enter another username.",
"goto": "create_username",
},
)
else: else:
menutree.playername = input menutree.playername = input
# Disables echo for entering password # Disables echo for entering password
caller.msg(echo=False) caller.msg(echo=False)
# Redirects to the creation of a password # Redirects to the creation of a password
return create_password(caller, None) text = "Enter this account's new password."
options = ( options = (
{ {
"key": "_default", "key": "_default",
"desc": "Enter your new account's name.", "desc": "Enter this account's new password.",
"goto": "create_username", "goto": "create_password",
}, },
) )
return text, options return text, options
def create_password(caller, input): def create_password(caller, input):
"""Asks the user to create a password. """Ask the user to create a password.
This node is at the end of the menu for account creation. If This node is at the end of the menu for account creation. If
a proper MULTI_SESSION is configured, a character is also a proper MULTI_SESSION is configured, a character is also
@ -230,31 +316,47 @@ def create_password(caller, input):
""" """
menutree = caller.ndb._menutree menutree = caller.ndb._menutree
text = "" text = ""
if input is None: options = (
text = "Enter this account's new password." {
else: "key": "b",
"desc": "Go back to the login screen.",
"goto": "start",
},
{
"key": "_default",
"desc": "Enter your password.",
"goto": "create_password",
},
)
caller.msg(echo=True) caller.msg(echo=True)
password = input.strip() password = input.strip()
if not hasattr(menutree, 'playername'): if not hasattr(menutree, 'playername'):
caller.msg(dedent(""" text = dedent("""
|rSomething went wrong! Playername not remembered |rSomething went wrong! Playername not remembered
from previous step!{n from previous step!|n
""".strip("\n"))) Press RETURN to go back to the login screen.
""".strip("\n"))
# Redirects to the starting node # Redirects to the starting node
return start(caller) options = (
{
"key": "_default",
"desc": "Go back to the login screen.",
"goto": "start",
},
)
else:
playername = menutree.playername playername = menutree.playername
if len(password) < LEN_PASSWD: if len(password) < LEN_PASSWD:
caller.msg(echo=False) caller.msg(echo=False)
# The password is too short password # The password is too short
string = dedent(""" text = dedent("""
|rYour password must be at least {} characters long.|n |rYour password must be at least {} characters long.|n
""".strip("\n").format(LEN_PASSWD)) Type |yb|n to return to the login screen.
caller.msg(string) Or enter another password.
# Loops on the same node """.strip("\n")).format(LEN_PASSWD)
return create_password(caller, None) else:
# Everything's OK. Create the new player account and # Everything's OK. Create the new player account and
# possibly the character, depending on the multisession mode # possibly the character, depending on the multisession mode
from evennia.commands.default import unloggedin from evennia.commands.default import unloggedin
@ -268,8 +370,8 @@ def create_password(caller, input):
if settings.MULTISESSION_MODE < 2: if settings.MULTISESSION_MODE < 2:
default_home = ObjectDB.objects.get_id( default_home = ObjectDB.objects.get_id(
settings.DEFAULT_HOME) settings.DEFAULT_HOME)
unloggedin._create_character(caller, new_player, typeclass, unloggedin._create_character(caller, new_player,
default_home, permissions) typeclass, default_home, permissions)
except Exception: except Exception:
# We are in the middle between logged in and -not, so we have # We are in the middle between logged in and -not, so we have
# to handle tracebacks ourselves at this point. If we don't, we # to handle tracebacks ourselves at this point. If we don't, we
@ -277,6 +379,8 @@ def create_password(caller, input):
caller.msg(dedent(""" caller.msg(dedent("""
|rAn error occurred.|n Please e-mail an admin if |rAn error occurred.|n Please e-mail an admin if
the problem persists. the problem persists.
Type |yb|n to go back to the login screen.
Or enter another password.
""".strip("\n"))) """.strip("\n")))
logger.log_trace() logger.log_trace()
else: else:
@ -284,13 +388,6 @@ def create_password(caller, input):
caller.msg("Welcome, you're new account has been created!") caller.msg("Welcome, you're new account has been created!")
caller.sessionhandler.login(caller, new_player) caller.sessionhandler.login(caller, new_player)
options = (
{
"key": "_default",
"desc": "Enter your new password.",
"goto": "create_password",
},
)
return text, options return text, options
## Other functions ## Other functions