Continued work on multi-char-per-account. Added a new default login point. Still need to add sessid to commands.

This commit is contained in:
Griatch 2013-02-02 15:55:42 +01:00
parent b50266623e
commit 231af4a351
5 changed files with 120 additions and 50 deletions

View file

@ -649,7 +649,12 @@ class CmdAccess(MuxCommand):
string += "\nPlayer {c%s{n: %s" % (caller.player.key, pperms)
caller.msg(string)
#------------------------------------------------------------
# OOC commands
#------------------------------------------------------------
class CmdOOCLook(MuxCommandOOC, CmdLook):
"""
@ -658,28 +663,67 @@ class CmdOOCLook(MuxCommandOOC, CmdLook):
Usage:
look
This is an OOC version of the look command. Since a
Player doesn't have an in-game existence, there is no
concept of location or "self". If we are controlling
a character, pass control over to normal look.
Look in the ooc state.
"""
#This is an OOC version of the look command. Since a
#Player doesn't have an in-game existence, there is no
#concept of location or "self". If we are controlling
#a character, pass control over to normal look.
key = "look"
aliases = ["l", "ls"]
locks = "cmd:all()"
help_category = "General"
def look_target(self):
"Hook method for when an argument is given."
# caller is assumed to be a player object here.
caller = self.caller
looktarget = caller.get_character(key=self.args)
if looktarget:
caller.msg(looktarget.return_appearance())
else:
caller.msg("No such character.")
return
def no_look_target(self):
"Hook method for default look without a specified target"
# caller is always a player at this point.
player = self.caller
sessid = self.sessid
# get all our characters
characters = player.get_all_characters() # get all characters
string = "You are logged in as {g%s{n." % player.key
string += " Use {w@ic <character>{n to enter the game."
string += "\n\nAvailable character%s:" % (characters.count() > 1 and "s" or "")
for char in characters:
csessid = char.sessid
if csessid:
# character is already puppeted
if csessid == sessid:
# this should not happen.
string += "\n - {r%s{n (sessid not properly cleared! Contact an admin!)" % char.key
elif player.get_session(csessid):
string += "\n - {G%s{n (played by you in another session)"
else:
string += "\n - {R%s{n (played by someone else)" % char.key
else:
# character is "free to puppet"
string += "\n - %s" % char.key
player.msg(string)
def func(self):
"implement the ooc look command"
if not self.character:
string = "You are out-of-character (OOC). "
string += "Use {w@ic{n to get back to the game, {whelp{n for more info."
self.caller.msg(string)
else:
self.caller = self.character # we have to put this back for normal look to work.
if utils.inherits_from(self.caller, "src.objects.objects.Object"):
# An object of some type is calling. Use default look instead.
super(CmdOOCLook, self).func()
elif self.args:
self.look_target()
else:
self.no_look_target()
class CmdIC(MuxCommandOOC):
"""

View file

@ -274,14 +274,13 @@ class ObjectDB(TypedObject):
if not get_field_cache(self, "player"):
del_field_cache(self, "sessid")
return get_field_cache(self, "sessid")
#@player.setter
#@sessid.setter
def __sessid_set(self, player):
"Setter. Allows for self.player = value"
if inherits_from(player, TypeClass):
player = player.dbobj
set_field_cache(self, "player", player)
#@player.deleter
#@sessid.deleter
def __player_del(self):
"Deleter. Allows for del self.player"
del_field_cache(self, "player")

View file

@ -225,7 +225,7 @@ class PlayerDB(TypedObject):
#@property
def character_get(self):
"Getter. Allows for value = self.character"
return get_field_cache(self, "obj)
return get_field_cache(self, "obj")
#@character.setter
def character_set(self, character):
"Setter. Allows for self.character = value"
@ -378,7 +378,7 @@ class PlayerDB(TypedObject):
session = _GA(self, "get_session")(sessid)
if session:
char = _GA(self, "get_character")(sessid)
if char and not char.at_msg_receive(outgoing_string, from_obj=from_obj, data=data)):
if char and not char.at_msg_receive(outgoing_string, from_obj=from_obj, data=data):
# if hook returns false, cancel send
return
session.msg(outgoing_string, data)
@ -411,7 +411,7 @@ class PlayerDB(TypedObject):
its session id.
"""
def get_sessions(self, sessid=None):
def get_session(self, sessid=None):
"""
Return session with given sessid connected to this player. If sessid is
not given, return all connected sessions.
@ -420,24 +420,36 @@ class PlayerDB(TypedObject):
"""
return SESSIONS.get_session_from_player(self, sessid=sessid)
def get_character(self, sessid):
def get_character(self, sessid=None, key=None):
"""
Get the character connected through this sessid, if any
Get the character connected through this sessid, if any. May also
try to return a character based on key. If neither sessid nor key
is given, return all characters connected to this player
"""
if not sessid: # sessid is always > 0
return None
try:
char = get_prop_cache(self, "_characters").get(sessid)
except AttributeError:
set_prop_cache(self, "_characters", {})
char = None
if not char:
char = self.db_objs.filter(player=self, sessid=sessid)
if char.count():
chars_cache = get_prop_cache(self, "_characters")
chars_cache[sessid] = char[0]
set_prop_cache(self, "_characters")
return char
cache = get_prop_cache(self, "_characters") or {}
if sessid:
# try to return a character with a given sessid
char = cache.get(sessid)
if not char:
char = self.db_objs.filter(player=self, sessid=sessid) or None
if char:
cache[sessid] = char[0]
set_prop_cache(self, "_characters", cache)
if key:
return char.key.lower() == key.lower() and char or None
return char
elif key:
char = self.db_objs.filter(player=self, db_key__iexact=key)
return char and char[0] or None
else:
# no sessid given - return all available characters
return list(self.db_objs.filter(player=self, sessid=sessid))
def get_all_characters(self):
"""
Readability-wrapper for getting all characters
"""
return self.get_character(sessid=None)
def connect_character(self, character, sessid):
"""
@ -446,25 +458,39 @@ class PlayerDB(TypedObject):
game was fully restarted (including the Portal), this must be
used, since sessids will have changed as players reconnect.
"""
# first disconnect any other character from this session
self.disconnect_character(sessid=sessid)
character = character.dbobj
character.player = self
character.sessid = sessid
self.db_objs.add(character)
self.save()
# update cache
cache = get_prop_cache(self, "_characters") or {}
cache[sessid] = character
set_prop_cache(self, "_characters", cache)
def disconnect_character(self, character):
def disconnect_character(self, sessid=None, char=None):
"""
Disconnect a character from this player.
Disconnect a character from this player, either based
on sessid or by giving the character object directly
"""
character = character.dbobj
if self.db_objs.filter(id=_GA(character,"id")):
self.db_objs.remove(character)
character.player = None
character.sessid = None
key = char and char.key or None
char = self.get_character(sessid=sessid, key=key)
if char:
self.db_objs.remove(char)
del char.player
del char.sessid
self.save()
# clear cache
cache = get_prop_cache(self, "_characters") or {}
if cache and sessid in cache:
del cache[sessid]
set_prop_cache(self, "_characters", cache)
def disconnect_all_characters(self):
for char in self.db_objs.all():
self.disconnect_character(char)
def swap_character(self, new_character, delete_old_character=False):
"""

View file

@ -32,7 +32,8 @@ SSYNC = chr(8) # server session sync
from django.utils.translation import ugettext as _
SERVERNAME = settings.SERVERNAME
ALLOW_MULTISESSION = settings.ALLOW_MULTISESSION
#ALLOW_MULTISESSION = settings.ALLOW_MULTISESSION
MULTISESSION_MODE = settings.MULTISESSION_MODE
IDLE_TIMEOUT = settings.IDLE_TIMEOUT
#-----------------------------------------------------------
@ -163,8 +164,8 @@ class ServerSessionHandler(SessionHandler):
"""
# prep the session with player/user info
if not ALLOW_MULTISESSION:
# disconnect previous sessions.
if MULTISESSION_MODE == 0:
# disconnect all previous sessions.
self.disconnect_duplicate_sessions(session)
session.logged_in = True
# sync the portal to this session
@ -235,7 +236,7 @@ class ServerSessionHandler(SessionHandler):
uid = player.uid
if sessid:
return [session for session in self.sessions.values() if session.logged_in and session.sessid == sessid and session.uid == uid]
else
else:
return [session for session in self.sessions.values() if session.logged_in and session.uid == uid]
def sessions_from_character(self, character):

View file

@ -59,12 +59,12 @@ SSL_ENABLED = False
SSL_PORTS = [4001]
# Interface addresses to listen to. If 0.0.0.0, listen to all.
SSL_INTERFACES = ['0.0.0.0']
# If multisessions are allowed, a user can log into the game
# from several different computers/clients at the same time.
# All feedback from the game will be echoed to all sessions.
# If false, only one session is allowed, all other are logged off
# when a new connects.
ALLOW_MULTISESSION = False
# Multisession modes allow a player (=account) to connect to the game simultaneously
# with multiple clients in various ways according to the set mode:
# 0 - no multisession - when a new session is connected, the old one is disconnected
# 1 - multiple sessions, one player, one character, each session getting the same data
# 2 - multiple sessions, one player, each session controlling different characters
MULTISESSION_MODE = 0
# The path that contains this settings.py file (no trailing slash).
BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Path to the src directory containing the bulk of the codebase's code.