mirror of
https://github.com/evennia/evennia.git
synced 2026-03-30 20:47:17 +02:00
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:
parent
b50266623e
commit
231af4a351
5 changed files with 120 additions and 50 deletions
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue