mirror of
https://github.com/evennia/evennia.git
synced 2026-04-04 23:17:17 +02:00
Lots of cleanup and bug fixes. Still some issues with reconnecting to the right location in multisession_mode 0.
This commit is contained in:
parent
e86c127903
commit
9eb1903f02
8 changed files with 73 additions and 83 deletions
|
|
@ -903,9 +903,14 @@ class CmdCharCreate(MuxCommandOOC):
|
|||
|
||||
new_character = create.create_object(typeclass, key=key, location=default_home,
|
||||
home=default_home, permissions=permissions)
|
||||
# only allow creator (and immortals) to puppet this char
|
||||
new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Immortals) or pperm(Immortals)" %
|
||||
(new_character.id, player.id))
|
||||
player.db._playable_characters.append(new_character)
|
||||
if desc:
|
||||
new_character.db.desc = desc
|
||||
else:
|
||||
new_character.db.desc = "This is a Player."
|
||||
self.msg("Created new character %s." % new_character.key)
|
||||
|
||||
|
||||
|
|
@ -942,7 +947,7 @@ class CmdIC(MuxCommandOOC):
|
|||
|
||||
new_character = None
|
||||
if not self.args:
|
||||
new_character = caller.db.last_puppet
|
||||
new_character = caller.db._last_puppet
|
||||
if not new_character:
|
||||
self.msg("Usage: @ic <character>")
|
||||
return
|
||||
|
|
@ -960,7 +965,10 @@ class CmdIC(MuxCommandOOC):
|
|||
return
|
||||
if new_character.player:
|
||||
if new_character.sessid == sessid:
|
||||
self.msg("{RYou already act as {c%s{n from another session." % new_character.name)
|
||||
self.msg("{RYou already act as {c%s{n." % new_character.name)
|
||||
return
|
||||
elif new_character.player == caller:
|
||||
self.msg("{RYou already act as {c%s{n in another session." % new_character.name)
|
||||
return
|
||||
elif not caller.get_character(character=new_character):
|
||||
self.msg("{c%s{r is already acted by another player.{n" % new_character.name)
|
||||
|
|
@ -972,7 +980,7 @@ class CmdIC(MuxCommandOOC):
|
|||
self.msg("\n{gYou become {c%s{n.\n" % new_character.name)
|
||||
caller.db.last_puppet = old_character
|
||||
if not new_character.location:
|
||||
# this might be due to being hidden away at logout; check
|
||||
# this might be due to being hidden away at logout; check
|
||||
loc = new_character.db.prelogout_location
|
||||
if not loc: # still no location; use home
|
||||
loc = new_character.home
|
||||
|
|
@ -1012,7 +1020,7 @@ class CmdOOC(MuxCommandOOC):
|
|||
self.msg(string)
|
||||
return
|
||||
|
||||
caller.db.last_puppet = old_char
|
||||
caller.db._last_puppet = old_char
|
||||
# save location as if we were disconnecting from the game entirely.
|
||||
if old_char.location:
|
||||
old_char.location.msg_contents("%s has left the game." % old_char.key, exclude=[old_char])
|
||||
|
|
|
|||
|
|
@ -92,12 +92,11 @@ class CmdUnconnectedConnect(MuxCommand):
|
|||
return
|
||||
|
||||
# actually do the login. This will call all other hooks:
|
||||
# session.at_init()
|
||||
# if character:
|
||||
# at_first_login() # only once
|
||||
# at_pre_login()
|
||||
# player.at_post_login() - calls look if no character is set
|
||||
# character.at_post_login() - this calls look command by default
|
||||
# session.at_login()
|
||||
# player.at_init() # always called when object is loaded from disk
|
||||
# player.at_pre_login()
|
||||
# player.at_first_login() # only once
|
||||
# player.at_post_login()
|
||||
session.sessionhandler.login(session, player)
|
||||
|
||||
class CmdUnconnectedCreate(MuxCommand):
|
||||
|
|
@ -199,7 +198,8 @@ class CmdUnconnectedCreate(MuxCommand):
|
|||
# If no description is set, set a default description
|
||||
if not new_character.db.desc:
|
||||
new_character.db.desc = "This is a Player."
|
||||
|
||||
# set flag for triggering first-time login hook
|
||||
new_character.db._first_login = True
|
||||
|
||||
# tell the caller everything went well.
|
||||
string = "A new account '%s' was created. Welcome!"
|
||||
|
|
|
|||
|
|
@ -794,6 +794,7 @@ class Character(Object):
|
|||
"""
|
||||
This recovers the character again after having been "stoved away" at disconnect.
|
||||
"""
|
||||
print "char:at_post_login", self
|
||||
if self.db.prelogout_location:
|
||||
# try to recover
|
||||
self.location = self.db.prelogout_location
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ from src.typeclasses.typeclass import TypeClass
|
|||
from src.commands.cmdsethandler import CmdSetHandler
|
||||
from src.commands import cmdhandler
|
||||
from src.utils import logger, utils
|
||||
from src.utils.utils import inherits_from
|
||||
from src.utils.utils import inherits_from, make_iter
|
||||
|
||||
__all__ = ("PlayerAttribute", "PlayerNick", "PlayerDB")
|
||||
|
||||
|
|
@ -182,50 +182,17 @@ class PlayerDB(TypedObject):
|
|||
#@property
|
||||
def objs_get(self):
|
||||
"Getter. Allows for value = self.obj"
|
||||
return self.db_objs.all()
|
||||
#return get_field_cache(self, "objs").all()
|
||||
#@obj.setter
|
||||
return list(self.db_objs.all())
|
||||
#@objs.setter
|
||||
def objs_set(self, value):
|
||||
"Setter. Allows for self.obj = value"
|
||||
global _TYPECLASS
|
||||
if not _TYPECLASS:
|
||||
from src.typeclasses.typeclass import TypeClass as _TYPECLASS
|
||||
|
||||
if isinstance(value, _TYPECLASS):
|
||||
value = value.dbobj
|
||||
try:
|
||||
self.db_objs.add(value)
|
||||
self.save()
|
||||
#set_field_cache(self, "obj", value)
|
||||
except Exception:
|
||||
logger.log_trace()
|
||||
raise Exception("Cannot assign %s as a player object!" % value)
|
||||
"Setter. Allows for self.objs = value"
|
||||
raise Exception("Use access methods to add new characters instead.")
|
||||
#@obj.deleter
|
||||
def objs_del(self):
|
||||
"Deleter. Allows for del self.obj"
|
||||
self.db_objs.clear()
|
||||
self.save()
|
||||
#del_field_cache(self, "obj")
|
||||
raise Exception("Use access methods to delete new characters instead.")
|
||||
objs = property(objs_get, objs_set, objs_del)
|
||||
|
||||
# whereas the name 'obj' is consistent with the rest of the code,
|
||||
# 'character' is a more intuitive property name, so we
|
||||
# define this too, as an alias to player.obj.
|
||||
#@property
|
||||
def character_get(self):
|
||||
"Getter. Allows for value = self.character"
|
||||
return get_field_cache(self, "obj")
|
||||
#@character.setter
|
||||
def character_set(self, character):
|
||||
"Setter. Allows for self.character = value"
|
||||
if inherits_from(character, TypeClass):
|
||||
character = character.dbobj
|
||||
set_field_cache(self, "obj", character)
|
||||
#@character.deleter
|
||||
def character_del(self):
|
||||
"Deleter. Allows for del self.character"
|
||||
del_field_cache(self, "obj")
|
||||
character = property(character_get, character_set, character_del)
|
||||
characters = property(objs_get, objs_set, objs_del)
|
||||
|
||||
# cmdset_storage property
|
||||
# This seems very sensitive to caching, so leaving it be for now /Griatch
|
||||
|
|
@ -407,6 +374,22 @@ class PlayerDB(TypedObject):
|
|||
# a non-character session; this goes to player directly
|
||||
_GA(self, "execute_cmd")(ingoing_string, sessid=sessid)
|
||||
|
||||
def get_session(self, sessid):
|
||||
"""
|
||||
Return session with given sessid connected to this player.
|
||||
"""
|
||||
global _SESSIONS
|
||||
if not _SESSIONS:
|
||||
from src.server.sessionhandler import SESSIONS as _SESSIONS
|
||||
return _SESSIONS.sessions_from_player(self, sessid=sessid)
|
||||
|
||||
def get_all_sessions(self):
|
||||
"Return all sessions connected to this player"
|
||||
global _SESSIONS
|
||||
if not _SESSIONS:
|
||||
from src.server.sessionhandler import SESSIONS as _SESSIONS
|
||||
return _SESSIONS.sessions_from_player(self)
|
||||
|
||||
def get_session_from_sessid(self, sessid):
|
||||
"""
|
||||
Get the session object from sessid. If session with sessid is not
|
||||
|
|
@ -421,8 +404,8 @@ class PlayerDB(TypedObject):
|
|||
"""
|
||||
Access method for disconnecting a given session from the player.
|
||||
"""
|
||||
session = self.get_session_from_sessid(sessid)
|
||||
if session:
|
||||
sessions = self.get_session_from_sessid(sessid)
|
||||
for session in make_iter(sessions):
|
||||
session.sessionhandler.disconnect(session)
|
||||
|
||||
def connect_session_to_character(self, sessid, character, force=False):
|
||||
|
|
@ -454,10 +437,11 @@ class PlayerDB(TypedObject):
|
|||
# start (persistent) scripts on this object
|
||||
#ScriptDB.objects.validate(obj=character)
|
||||
pass
|
||||
if character.db.FIRST_LOGIN:
|
||||
if character.db._first_login:
|
||||
character.at_first_login()
|
||||
del character.db.FIRST_LOGIN
|
||||
del character.db._first_login
|
||||
character.at_pre_login()
|
||||
print "player: calling at_post_login on char"
|
||||
character.at_post_login()
|
||||
return True
|
||||
|
||||
|
|
@ -494,23 +478,8 @@ class PlayerDB(TypedObject):
|
|||
char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
|
||||
if not char:
|
||||
return
|
||||
self.connect_session_to_character(sessid, char, force=True)
|
||||
_GA(self, "connect_session_to_character")(sessid, char, force=True)
|
||||
|
||||
def get_session(self, sessid):
|
||||
"""
|
||||
Return session with given sessid connected to this player.
|
||||
"""
|
||||
global _SESSIONS
|
||||
if not _SESSIONS:
|
||||
from src.server.sessionhandler import SESSIONS as _SESSIONS
|
||||
return _SESSIONS.sessions_from_player(self, sessid=sessid)
|
||||
|
||||
def get_all_sessions(self):
|
||||
"Return all sessions connected to this player"
|
||||
global _SESSIONS
|
||||
if not _SESSIONS:
|
||||
from src.server.sessionhandler import SESSIONS as _SESSIONS
|
||||
return _SESSIONS.sessions_from_player(self)
|
||||
|
||||
def get_character(self, sessid=None, character=None, return_dbobj=False):
|
||||
"""
|
||||
|
|
@ -550,14 +519,23 @@ class PlayerDB(TypedObject):
|
|||
"""
|
||||
return _GA(self, "get_character")(sessid=None, character=None)
|
||||
|
||||
def get_all_connected_characters(self):
|
||||
"""
|
||||
Return all characters with an active session connected
|
||||
to them through this player
|
||||
"""
|
||||
chars = make_iter(_GA(self, "get_character")(sessid=None, character=None))
|
||||
sessids = [sess.sessid for sess in _GA(self, "get_all_sessions")()]
|
||||
return [char for char in chars if char.sessid in sessids]
|
||||
|
||||
def connect_character(self, character, sessid=None):
|
||||
"""
|
||||
Use the Player to connect a Character to a session. Note that
|
||||
we don't do any access checks at this point. Note that if the
|
||||
Use the Player to connect a Character to the Player. Note that
|
||||
we don't do any access checks at this point. If the
|
||||
game was fully restarted (including the Portal), this must be
|
||||
used, since sessids will have changed as players reconnect.
|
||||
|
||||
if sessid is given, also connect the sessid to the character.
|
||||
if sessid is given, also connect the sessid to the character directly.
|
||||
"""
|
||||
# first disconnect any other character from this session
|
||||
char = character.dbobj
|
||||
|
|
@ -590,7 +568,6 @@ class PlayerDB(TypedObject):
|
|||
set_prop_cache(self, "_characters", cache)
|
||||
return char
|
||||
|
||||
|
||||
def disconnect_all_characters(self):
|
||||
for char in self.db_objs.all():
|
||||
_GA(self, "disconnect_character")(char)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ from src.comms.models import Channel
|
|||
from src.utils import logger
|
||||
__all__ = ("Player",)
|
||||
|
||||
_MULTISESSION_MODE = settings.MULTISESSION_MODE
|
||||
_CMDSET_OOC = settings.CMDSET_OOC
|
||||
_CONNECT_CHANNEL = None
|
||||
|
||||
|
|
@ -322,9 +323,11 @@ class Player(TypeClass):
|
|||
at_post_login hook.
|
||||
"""
|
||||
self._send_to_connect_channel("{G%s connected{n" % self.key)
|
||||
# Character.at_post_login also looks around. Only use
|
||||
# this as a backup when logging in without a character
|
||||
self.execute_cmd("look")
|
||||
|
||||
if _MULTISESSION_MODE == 2 or not self.get_all_characters():
|
||||
# Character.at_post_login also looks around. Only use
|
||||
# this as a backup when logging in without a character
|
||||
self.execute_cmd("look")
|
||||
|
||||
def at_disconnect(self, reason=None):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ def create_objects():
|
|||
|
||||
god_character.save()
|
||||
god_character.set_attribute("_superuser_character", True)
|
||||
gor_character.set_attribute("_first_login", True)
|
||||
|
||||
# Limbo is the default "nowhere" starting room
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ class ServerSession(Session):
|
|||
return
|
||||
if self.logged_in:
|
||||
# the inmsg handler will relay to the right place
|
||||
self.player.inmsg(command_string, self.sessid)
|
||||
self.player.inmsg(command_string, sessid=self.sessid)
|
||||
else:
|
||||
# we are not logged in. Use the session directly
|
||||
# (it uses the settings.UNLOGGEDIN cmdset)
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ class ServerSessionHandler(SessionHandler):
|
|||
|
||||
player.at_pre_login()
|
||||
|
||||
session.log(_('Logged in: %(self)s') % {'self': self})
|
||||
session.log(_('Logged in: %(self)s') % {'self': player})
|
||||
|
||||
# start (persistent) scripts on this object
|
||||
#ScriptDB.objects.validate(obj=self.player.character)
|
||||
|
|
@ -275,12 +275,12 @@ class ServerSessionHandler(SessionHandler):
|
|||
|
||||
def disconnect_duplicate_sessions(self, curr_session, reason = _("Logged in from elsewhere. Disconnecting.") ):
|
||||
"""
|
||||
Disconnects any existing sessions with the same game object.
|
||||
Disconnects any existing sessions with the same user.
|
||||
"""
|
||||
curr_char = curr_session.get_character()
|
||||
uid = curr_session.uid
|
||||
doublet_sessions = [sess for sess in self.sessions.values()
|
||||
if sess.logged_in
|
||||
and sess.get_character() == curr_char
|
||||
and sess.uid == uid
|
||||
and sess != curr_session]
|
||||
for session in doublet_sessions:
|
||||
self.disconnect(session, reason)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue