Ejemplo n.º 1
0
 def __init__(self, *args, **kwargs):
     "Parent must be initialized first."
     TypedObject.__init__(self, *args, **kwargs)
     # handlers
     _SA(self, "cmdset", CmdSetHandler(self))
     _GA(self, "cmdset").update(init_mode=True)
     _SA(self, "scripts", ScriptHandler(self))
     _SA(self, "attributes", AttributeHandler(self))
     _SA(self, "nicks", NickHandler(self))
     _SA(self, "tags", TagHandler(self))
     _SA(self, "aliases", AliasHandler(self))
Ejemplo n.º 2
0
    def at_login(self, player):
        """
        Hook called by sessionhandler when the session becomes authenticated.

        player - the player associated with the session
        """
        self.player = player
        self.uid = self.player.id
        self.uname = self.player.username
        self.logged_in = True
        self.conn_time = time.time()
        self.puid = None
        self.puppet = None
        self.cmdset_storage = settings.CMDSET_SESSION

        # Update account's last login time.
        self.player.last_login = datetime.now()
        self.player.save()

        # add the session-level cmdset
        self.cmdset = CmdSetHandler(self, True)
Ejemplo n.º 3
0
    def at_login(self, player):
        """
        Hook called by sessionhandler when the session becomes authenticated.

        player - the player associated with the session
        """
        self.player = player
        self.uid = self.player.id
        self.uname = self.player.username
        self.logged_in = True
        self.conn_time = time.time()
        self.puid = None
        self.puppet = None
        self.cmdset_storage = settings.CMDSET_SESSION

        # Update account's last login time.
        self.player.last_login = datetime.now()
        self.player.save()

        # add the session-level cmdset
        self.cmdset = CmdSetHandler(self, True)
Ejemplo n.º 4
0
 def cmdset(self):
     return CmdSetHandler(self, True)
Ejemplo n.º 5
0
 def __init__(self):
     "Initiate to avoid AttributeErrors down the line"
     self.puppet = None
     self.player = None
     self.cmdset_storage_string = ""
     self.cmdset = CmdSetHandler(self, True)
Ejemplo n.º 6
0
class ServerSession(Session):
    """
    This class represents a player's session and is a template for
    individual protocols to communicate with Evennia.

    Each player gets a session assigned to them whenever they connect
    to the game server. All communication between game and player goes
    through their session.

    """

    def __init__(self):
        "Initiate to avoid AttributeErrors down the line"
        self.puppet = None
        self.player = None
        self.cmdset_storage_string = ""
        self.cmdset = CmdSetHandler(self, True)

    def __cmdset_storage_get(self):
        return [path.strip() for path in self.cmdset_storage_string.split(",")]

    def __cmdset_storage_set(self, value):
        self.cmdset_storage_string = ",".join(str(val).strip() for val in make_iter(value))

    cmdset_storage = property(__cmdset_storage_get, __cmdset_storage_set)

    def at_sync(self):
        """
        This is called whenever a session has been resynced with the portal.
        At this point all relevant attributes have already been set and
        self.player been assigned (if applicable).

        Since this is often called after a server restart we need to set up
        the session as it was.
        """
        global _ObjectDB
        if not _ObjectDB:
            from src.objects.models import ObjectDB as _ObjectDB

        if not self.logged_in:
            # assign the unloggedin-command set.
            self.cmdset_storage = settings.CMDSET_UNLOGGEDIN

        self.cmdset.update(init_mode=True)

        if self.puid:
            # reconnect puppet (puid is only set if we are coming
            # back from a server reload)
            obj = _ObjectDB.objects.get(id=self.puid)
            self.player.puppet_object(self.sessid, obj, normal_mode=False)

    def at_login(self, player):
        """
        Hook called by sessionhandler when the session becomes authenticated.

        player - the player associated with the session
        """
        self.player = player
        self.uid = self.player.id
        self.uname = self.player.username
        self.logged_in = True
        self.conn_time = time.time()
        self.puid = None
        self.puppet = None
        self.cmdset_storage = settings.CMDSET_SESSION

        # Update account's last login time.
        self.player.last_login = datetime.now()
        self.player.save()

        # add the session-level cmdset
        self.cmdset = CmdSetHandler(self, True)

    def at_disconnect(self):
        """
        Hook called by sessionhandler when disconnecting this session.
        """
        if self.logged_in:
            sessid = self.sessid
            player = self.player
            _GA(player.dbobj, "unpuppet_object")(sessid)
            uaccount = player.dbobj
            uaccount.last_login = datetime.now()
            uaccount.save()
            # calling player hook
            _GA(player.typeclass, "at_disconnect")()
            self.logged_in = False
            if not self.sessionhandler.sessions_from_player(player):
                # no more sessions connected to this player
                player.is_connected = False
            # this may be used to e.g. delete player after disconnection etc
            _GA(player.typeclass, "at_post_disconnect")()

    def get_player(self):
        """
        Get the player associated with this session
        """
        return self.logged_in and self.player

    def get_puppet(self):
        """
        Returns the in-game character associated with this session.
        This returns the typeclass of the object.
        """
        return self.logged_in and self.puppet

    get_character = get_puppet

    def get_puppet_or_player(self):
        """
        Returns session if not logged in; puppet if one exists,
        otherwise return the player.
        """
        if self.logged_in:
            return self.puppet if self.puppet else self.player
        return None

    def log(self, message, channel=True):
        """
        Emits session info to the appropriate outputs and info channels.
        """
        if channel:
            try:
                cchan = settings.CHANNEL_CONNECTINFO
                cchan = ChannelDB.objects.get_channel(cchan[0])
                cchan.msg("[%s]: %s" % (cchan.key, message))
            except Exception:
                pass
        logger.log_infomsg(message)

    def update_session_counters(self, idle=False):
        """
        Hit this when the user enters a command in order to update idle timers
        and command counters.
        """
        # Store the timestamp of the user's last command.
        self.cmd_last = time.time()
        if not idle:
            # Increment the user's command counter.
            self.cmd_total += 1
            # Player-visible idle time, not used in idle timeout calcs.
            self.cmd_last_visible = time.time()

    def data_in(self, text=None, **kwargs):
        """
        Send User->Evennia. This will in effect
        execute a command string on the server.

        Especially handled keywords:

        oob - this should hold a dictionary of oob command calls from
              the oob-supporting protocol.
        """
        if text:
            # this is treated as a command input
            text = to_unicode(text)
            # handle the 'idle' command
            if text.strip() == IDLE_COMMAND:
                self.update_session_counters(idle=True)
                return
            if self.player:
                # nick replacement
                puppet = self.player.get_puppet(self.sessid)
                if puppet:
                    text = puppet.nicks.nickreplace(text, categories=("inputline", "channel"), include_player=True)
                else:
                    text = self.player.nicks.nickreplace(
                        text, categories=("inputline", "channels"), include_player=False
                    )
            cmdhandler(self, text, callertype="session", sessid=self.sessid)
            self.update_session_counters()
        if "oob" in kwargs:
            # handle oob instructions
            global _OOB_HANDLER
            if not _OOB_HANDLER:
                from src.server.oobhandler import OOB_HANDLER as _OOB_HANDLER
            oobstruct = self.sessionhandler.oobstruct_parser(kwargs.pop("oob", None))
            # print "session.data_in: oobstruct:",oobstruct
            for (funcname, args, kwargs) in oobstruct:
                if funcname:
                    _OOB_HANDLER.execute_cmd(self, funcname, *args, **kwargs)

    execute_cmd = data_in  # alias

    def data_out(self, text=None, **kwargs):
        """
        Send Evennia -> User
        """
        self.sessionhandler.data_out(self, text=text, **kwargs)

    def __eq__(self, other):
        return self.address == other.address

    def __str__(self):
        """
        String representation of the user session class. We use
        this a lot in the server logs.
        """
        symbol = ""
        if self.logged_in and hasattr(self, "player") and self.player:
            symbol = "(#%s)" % self.player.id
        try:
            if hasattr(self.address, "__iter__"):
                address = ":".join([str(part) for part in self.address])
            else:
                address = self.address
        except Exception:
            address = self.address
        return "%s%s@%s" % (self.uname, symbol, address)

    def __unicode__(self):
        """
        Unicode representation
        """
        return u"%s" % str(self)

    # easy-access functions

    # def login(self, player):
    #    "alias for at_login"
    #    self.session_login(player)
    # def disconnect(self):
    #    "alias for session_disconnect"
    #    self.session_disconnect()
    def msg(self, text="", **kwargs):
        "alias for at_data_out"
        self.data_out(text=text, **kwargs)

    # Dummy API hooks for use during 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
Ejemplo n.º 7
0
 def __init__(self):
     "Initiate to avoid AttributeErrors down the line"
     self.puppet = None
     self.player = None
     self.cmdset_storage_string = ""
     self.cmdset = CmdSetHandler(self, True)
Ejemplo n.º 8
0
class ServerSession(Session):
    """
    This class represents a player's session and is a template for
    individual protocols to communicate with Evennia.

    Each player gets a session assigned to them whenever they connect
    to the game server. All communication between game and player goes
    through their session.

    """
    def __init__(self):
        "Initiate to avoid AttributeErrors down the line"
        self.puppet = None
        self.player = None
        self.cmdset_storage_string = ""
        self.cmdset = CmdSetHandler(self, True)

    def __cmdset_storage_get(self):
        return [path.strip() for path in self.cmdset_storage_string.split(',')]

    def __cmdset_storage_set(self, value):
        self.cmdset_storage_string = ",".join(
            str(val).strip() for val in make_iter(value))

    cmdset_storage = property(__cmdset_storage_get, __cmdset_storage_set)

    def at_sync(self):
        """
        This is called whenever a session has been resynced with the portal.
        At this point all relevant attributes have already been set and
        self.player been assigned (if applicable).

        Since this is often called after a server restart we need to set up
        the session as it was.
        """
        global _ObjectDB
        if not _ObjectDB:
            from src.objects.models import ObjectDB as _ObjectDB

        if not self.logged_in:
            # assign the unloggedin-command set.
            self.cmdset_storage = settings.CMDSET_UNLOGGEDIN

        self.cmdset.update(init_mode=True)

        if self.puid:
            # reconnect puppet (puid is only set if we are coming
            # back from a server reload)
            obj = _ObjectDB.objects.get(id=self.puid)
            self.player.puppet_object(self.sessid, obj, normal_mode=False)

    def at_login(self, player):
        """
        Hook called by sessionhandler when the session becomes authenticated.

        player - the player associated with the session
        """
        self.player = player
        self.uid = self.player.id
        self.uname = self.player.username
        self.logged_in = True
        self.conn_time = time.time()
        self.puid = None
        self.puppet = None
        self.cmdset_storage = settings.CMDSET_SESSION

        # Update account's last login time.
        self.player.last_login = datetime.now()
        self.player.save()

        # add the session-level cmdset
        self.cmdset = CmdSetHandler(self, True)

    def at_disconnect(self):
        """
        Hook called by sessionhandler when disconnecting this session.
        """
        if self.logged_in:
            sessid = self.sessid
            player = self.player
            _GA(player.dbobj, "unpuppet_object")(sessid)
            uaccount = player.dbobj
            uaccount.last_login = datetime.now()
            uaccount.save()
            # calling player hook
            _GA(player.typeclass, "at_disconnect")()
            self.logged_in = False
            if not self.sessionhandler.sessions_from_player(player):
                # no more sessions connected to this player
                player.is_connected = False
            # this may be used to e.g. delete player after disconnection etc
            _GA(player.typeclass, "at_post_disconnect")()

    def get_player(self):
        """
        Get the player associated with this session
        """
        return self.logged_in and self.player

    def get_puppet(self):
        """
        Returns the in-game character associated with this session.
        This returns the typeclass of the object.
        """
        return self.logged_in and self.puppet

    get_character = get_puppet

    def get_puppet_or_player(self):
        """
        Returns session if not logged in; puppet if one exists,
        otherwise return the player.
        """
        if self.logged_in:
            return self.puppet if self.puppet else self.player
        return None

    def log(self, message, channel=True):
        """
        Emits session info to the appropriate outputs and info channels.
        """
        if channel:
            try:
                cchan = settings.CHANNEL_CONNECTINFO
                cchan = ChannelDB.objects.get_channel(cchan[0])
                cchan.msg("[%s]: %s" % (cchan.key, message))
            except Exception:
                pass
        logger.log_infomsg(message)

    def get_client_size(self):
        """
        Return eventual eventual width and height reported by the
        client. Note that this currently only deals with a single
        client window (windowID==0) as in traditional telnet session
        """
        flags = self.protocol_flags
        width = flags.get('SCREENWIDTH', {}).get(0,
                                                 settings.CLIENT_DEFAULT_WIDTH)
        height = flags.get('SCREENHEIGHT',
                           {}).get(0, settings.CLIENT_DEFAULT_HEIGHT)
        return width, height

    def update_session_counters(self, idle=False):
        """
        Hit this when the user enters a command in order to update idle timers
        and command counters.
        """
        # Store the timestamp of the user's last command.
        self.cmd_last = time.time()
        if not idle:
            # Increment the user's command counter.
            self.cmd_total += 1
            # Player-visible idle time, not used in idle timeout calcs.
            self.cmd_last_visible = time.time()

    def data_in(self, text=None, **kwargs):
        """
        Send User->Evennia. This will in effect
        execute a command string on the server.

        Especially handled keywords:

        oob - this should hold a dictionary of oob command calls from
              the oob-supporting protocol.
        """
        if text:
            # this is treated as a command input
            #text = to_unicode(escape_control_sequences(text), encoding=self.encoding)
            # handle the 'idle' command
            if text.strip() == IDLE_COMMAND:
                self.update_session_counters(idle=True)
                return
            if self.player:
                # nick replacement
                puppet = self.player.get_puppet(self.sessid)
                if puppet:
                    text = puppet.nicks.nickreplace(text,
                                                    categories=("inputline",
                                                                "channel"),
                                                    include_player=True)
                else:
                    text = self.player.nicks.nickreplace(
                        text,
                        categories=("inputline", "channels"),
                        include_player=False)
            cmdhandler(self, text, callertype="session", sessid=self.sessid)
            self.update_session_counters()
        if "oob" in kwargs:
            # handle oob instructions
            global _OOB_HANDLER
            if not _OOB_HANDLER:
                from src.server.oobhandler import OOB_HANDLER as _OOB_HANDLER
            oobstruct = self.sessionhandler.oobstruct_parser(
                kwargs.pop("oob", None))
            #print "session.data_in: oobstruct:",oobstruct
            for (funcname, args, kwargs) in oobstruct:
                if funcname:
                    _OOB_HANDLER.execute_cmd(self, funcname, *args, **kwargs)

    execute_cmd = data_in  # alias

    def data_out(self, text=None, **kwargs):
        """
        Send Evennia -> User
        """
        text = text if text else ""
        #if text is None:
        #    text = ""
        #else:
        #    text = to_unicode(text)
        #    text = to_str(text, self.encoding)

        self.sessionhandler.data_out(self, text=text, **kwargs)

    def __eq__(self, other):
        return self.address == other.address

    def __str__(self):
        """
        String representation of the user session class. We use
        this a lot in the server logs.
        """
        symbol = ""
        if self.logged_in and hasattr(self, "player") and self.player:
            symbol = "(#%s)" % self.player.id
        try:
            if hasattr(self.address, '__iter__'):
                address = ":".join([str(part) for part in self.address])
            else:
                address = self.address
        except Exception:
            address = self.address
        return "%s%s@%s" % (self.uname, symbol, address)

    def __unicode__(self):
        """
        Unicode representation
        """
        return u"%s" % str(self)

    # easy-access functions

    #def login(self, player):
    #    "alias for at_login"
    #    self.session_login(player)
    #def disconnect(self):
    #    "alias for session_disconnect"
    #    self.session_disconnect()
    def msg(self, text='', **kwargs):
        "alias for at_data_out"
        self.data_out(text=text, **kwargs)

    # Dummy API hooks for use during non-loggedin operation

    def at_cmdset_get(self, **kwargs):
        "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