Note

You are reading an old version of the Evennia documentation. The latest version is here

.

# Source code for evennia

    """
    Evennia MUD/MUX/MU* creation system

    This is the main top-level API for Evennia. You can explore the evennia library
    by accessing evennia.<subpackage> directly. From inside the game you can read
    docs of all object by viewing its `__doc__` string, such as through

        py evennia.ObjectDB.__doc__

    For full functionality you should explore this module via a django-
    aware shell. Go to your game directory and use the command

       evennia shell

    to launch such a shell (using python or ipython depending on your install).
    See www.evennia.com for full documentation.

    """
    import evennia

    # docstring header

    DOCSTRING = """
    Evennia MU* creation system.

    Online manual and API docs are found at http://www.evennia.com.

    Flat-API shortcut names:
    {}
    """

    # Delayed loading of properties

    # Typeclasses

    DefaultAccount = None
    DefaultGuest = None
    DefaultObject = None
    DefaultCharacter = None
    DefaultRoom = None
    DefaultExit = None
    DefaultChannel = None
    DefaultScript = None

    # Database models
    ObjectDB = None
    AccountDB = None
    ScriptDB = None
    ChannelDB = None
    Msg = None
    ServerConfig = None

    # Properties
    AttributeProperty = None
    TagProperty = None
    TagCategoryProperty = None

    # commands
    Command = None
    CmdSet = None
    default_cmds = None
    syscmdkeys = None
    InterruptCommand = None

    # search functions
    search_object = None
    search_script = None
    search_account = None
    search_channel = None
    search_message = None
    search_help = None
    search_tag = None

    # create functions
    create_object = None
    create_script = None
    create_account = None
    create_channel = None
    create_message = None
    create_help_entry = None

    # utilities
    settings = None
    lockfuncs = None
    inputhandler = None
    logger = None
    gametime = None
    ansi = None
    spawn = None
    managers = None
    contrib = None
    EvMenu = None
    EvTable = None
    EvForm = None
    EvEditor = None
    EvMore = None
    ANSIString = None
    signals = None
    FuncParser = None

    # Handlers
    SESSION_HANDLER = None
    PORTAL_SESSION_HANDLER = None
    SERVER_SESSION_HANDLER = None
    TASK_HANDLER = None
    TICKER_HANDLER = None
    MONITOR_HANDLER = None

    # Containers
    GLOBAL_SCRIPTS = None
    OPTION_CLASSES = None

    PROCESS_ID = None

    TWISTED_APPLICATION = None
    EVENNIA_PORTAL_SERVICE = None
    EVENNIA_SERVER_SERVICE = None

    def _create_version():
        """
        Helper function for building the version string
        """
        import os
        from subprocess import STDOUT, CalledProcessError, check_output

        version = "Unknown"
        root = os.path.dirname(os.path.abspath(__file__))
        try:
            with open(os.path.join(root, "VERSION.txt"), "r") as f:
                version = f.read().strip()
        except IOError as err:
            print(err)
        try:
            rev = (
                check_output("git rev-parse --short HEAD", shell=True, cwd=root, stderr=STDOUT)
                .strip()
                .decode()
            )
            version = "%s (rev %s)" % (version, rev)
        except (IOError, CalledProcessError, OSError):
            # ignore if we cannot get to git
            pass
        return version

    __version__ = _create_version()
    del _create_version

    _LOADED = False

    PORTAL_MODE = False

    def _init(portal_mode=False):
        """
        This function is called automatically by the launcher only after
        Evennia has fully initialized all its models. It sets up the API
        in a safe environment where all models are available already.
        """
        global _LOADED
        if _LOADED:
            return
        _LOADED = True
        global DefaultAccount, DefaultObject, DefaultGuest, DefaultCharacter
        global DefaultRoom, DefaultExit, DefaultChannel, DefaultScript
        global ObjectDB, AccountDB, ScriptDB, ChannelDB, Msg
        global Command, CmdSet, default_cmds, syscmdkeys, InterruptCommand
        global search_object, search_script, search_account, search_channel
        global search_help, search_tag, search_message
        global create_object, create_script, create_account, create_channel
        global create_message, create_help_entry
        global signals
        global settings, lockfuncs, logger, utils, gametime, ansi, spawn, managers
        global contrib, TICKER_HANDLER, MONITOR_HANDLER, SESSION_HANDLER, PROCESS_ID
        global TASK_HANDLER, PORTAL_SESSION_HANDLER, SERVER_SESSION_HANDLER
        global GLOBAL_SCRIPTS, OPTION_CLASSES, EVENNIA_PORTAL_SERVICE, EVENNIA_SERVER_SERVICE, TWISTED_APPLICATION
        global EvMenu, EvTable, EvForm, EvMore, EvEditor
        global ANSIString, FuncParser
        global AttributeProperty, TagProperty, TagCategoryProperty, ServerConfig
        global PORTAL_MODE
        PORTAL_MODE = portal_mode

        # Parent typeclasses
        # utilities
        import os

        from django.conf import settings

        from . import contrib
        from .accounts.accounts import DefaultAccount, DefaultGuest
        from .accounts.models import AccountDB
        from .commands.cmdset import CmdSet
        from .commands.command import Command, InterruptCommand
        from .comms.comms import DefaultChannel
        from .comms.models import ChannelDB, Msg
        from .locks import lockfuncs
        from .objects.models import ObjectDB
        from .objects.objects import (
            DefaultCharacter,
            DefaultExit,
            DefaultObject,
            DefaultRoom,
        )
        from .prototypes.spawner import spawn
        from .scripts.models import ScriptDB
        from .scripts.monitorhandler import MONITOR_HANDLER
        from .scripts.scripts import DefaultScript
        from .scripts.taskhandler import TASK_HANDLER
        from .scripts.tickerhandler import TICKER_HANDLER
        from .server import signals
        from .server.models import ServerConfig
        from .typeclasses.attributes import AttributeProperty
        from .typeclasses.tags import TagCategoryProperty, TagProperty
        from .utils import ansi, class_from_module, gametime, logger
        from .utils.ansi import ANSIString

        if not PORTAL_MODE:
            # containers
            from .utils.containers import GLOBAL_SCRIPTS, OPTION_CLASSES

        # create functions
        from .utils.create import (
            create_account,
            create_channel,
            create_help_entry,
            create_message,
            create_object,
            create_script,
        )
        from .utils.eveditor import EvEditor
        from .utils.evform import EvForm
        from .utils.evmenu import EvMenu
        from .utils.evmore import EvMore
        from .utils.evtable import EvTable
        from .utils.funcparser import FuncParser

        # search functions
        from .utils.search import (
            search_account,
            search_channel,
            search_help,
            search_message,
            search_object,
            search_script,
            search_tag,
        )
        from .utils.utils import class_from_module

        PROCESS_ID = os.getpid()

        from twisted.application.service import Application

        TWISTED_APPLICATION = Application("Evennia")

        _evennia_service_class = None

        if portal_mode:
            # Set up the PortalSessionHandler
            from evennia.server.portal import portalsessionhandler

            portal_sess_handler_class = class_from_module(settings.PORTAL_SESSION_HANDLER_CLASS)
            portalsessionhandler.PORTAL_SESSIONS = portal_sess_handler_class()
            SESSION_HANDLER = portalsessionhandler.PORTAL_SESSIONS
            evennia.PORTAL_SESSION_HANDLER = evennia.SESSION_HANDLER
            _evennia_service_class = class_from_module(settings.EVENNIA_PORTAL_SERVICE_CLASS)
            EVENNIA_PORTAL_SERVICE = _evennia_service_class()
            EVENNIA_PORTAL_SERVICE.setServiceParent(TWISTED_APPLICATION)

            from django.db import connection

            # we don't need a connection to the database so close it right away
            try:
                connection.close()
            except Exception:
                pass

        else:
            # Create the ServerSesssionHandler
            from evennia.server import sessionhandler

            sess_handler_class = class_from_module(settings.SERVER_SESSION_HANDLER_CLASS)
            sessionhandler.SESSIONS = sess_handler_class()
            sessionhandler.SESSION_HANDLER = sessionhandler.SESSIONS
            SESSION_HANDLER = sessionhandler.SESSIONS
            SERVER_SESSION_HANDLER = SESSION_HANDLER
            _evennia_service_class = class_from_module(settings.EVENNIA_SERVER_SERVICE_CLASS)
            EVENNIA_SERVER_SERVICE = _evennia_service_class()
            EVENNIA_SERVER_SERVICE.setServiceParent(TWISTED_APPLICATION)

        # API containers

        class _EvContainer(object):
            """
            Parent for other containers

            """

            def _help(self):
                "Returns list of contents"
                names = [name for name in self.__class__.__dict__ if not name.startswith("_")]
                names += [name for name in self.__dict__ if not name.startswith("_")]
                print(self.__doc__ + "-" * 60 + "\n" + ", ".join(names))

            help = property(_help)

        class DBmanagers(_EvContainer):
            """
            Links to instantiated Django database managers. These are used
            to perform more advanced custom database queries than the standard
            search functions allow.

            helpentries - HelpEntry.objects
            accounts - AccountDB.objects
            scripts - ScriptDB.objects
            msgs    - Msg.objects
            channels - Channel.objects
            objects - ObjectDB.objects
            serverconfigs - ServerConfig.objects
            tags - Tags.objects
            attributes - Attributes.objects

            """

            from .accounts.models import AccountDB
            from .comms.models import ChannelDB, Msg
            from .help.models import HelpEntry
            from .objects.models import ObjectDB
            from .scripts.models import ScriptDB
            from .server.models import ServerConfig
            from .typeclasses.attributes import Attribute
            from .typeclasses.tags import Tag

            # create container's properties
            helpentries = HelpEntry.objects
            accounts = AccountDB.objects
            scripts = ScriptDB.objects
            msgs = Msg.objects
            channels = ChannelDB.objects
            objects = ObjectDB.objects
            serverconfigs = ServerConfig.objects
            attributes = Attribute.objects
            tags = Tag.objects
            # remove these so they are not visible as properties
            del HelpEntry, AccountDB, ScriptDB, Msg, ChannelDB
            # del ExternalChannelConnection
            del ObjectDB, ServerConfig, Tag, Attribute

        managers = DBmanagers()
        del DBmanagers

        class DefaultCmds(_EvContainer):
            """
            This container holds direct shortcuts to all default commands in Evennia.

            To access in code, do 'from evennia import default_cmds' then
            access the properties on the imported default_cmds object.

            """

            from .commands.default.cmdset_account import AccountCmdSet
            from .commands.default.cmdset_character import CharacterCmdSet
            from .commands.default.cmdset_session import SessionCmdSet
            from .commands.default.cmdset_unloggedin import UnloggedinCmdSet
            from .commands.default.muxcommand import MuxAccountCommand, MuxCommand

            def __init__(self):
                "populate the object with commands"

                def add_cmds(module):
                    "helper method for populating this object with cmds"
                    from evennia.utils import utils

                    cmdlist = utils.variable_from_module(module, module.__all__)
                    self.__dict__.update(dict([(c.__name__, c) for c in cmdlist]))

                from .commands.default import (
                    account,
                    admin,
                    batchprocess,
                    building,
                    comms,
                    general,
                    help,
                    system,
                    unloggedin,
                )

                add_cmds(admin)
                add_cmds(building)
                add_cmds(batchprocess)
                add_cmds(building)
                add_cmds(comms)
                add_cmds(general)
                add_cmds(account)
                add_cmds(help)
                add_cmds(system)
                add_cmds(unloggedin)

        default_cmds = DefaultCmds()
        del DefaultCmds

        class SystemCmds(_EvContainer):
            """
            Creating commands with keys set to these constants will make
            them system commands called as a replacement by the parser when
            special situations occur. If not defined, the hard-coded
            responses in the server are used.

            CMD_NOINPUT - no input was given on command line
            CMD_NOMATCH - no valid command key was found
            CMD_MULTIMATCH - multiple command matches were found
            CMD_LOGINSTART - this command will be called as the very
                             first command when an account connects to
                             the server.

            To access in code, do 'from evennia import syscmdkeys' then
            access the properties on the imported syscmdkeys object.

            """

            from .commands import cmdhandler

            CMD_NOINPUT = cmdhandler.CMD_NOINPUT
            CMD_NOMATCH = cmdhandler.CMD_NOMATCH
            CMD_MULTIMATCH = cmdhandler.CMD_MULTIMATCH
            CMD_LOGINSTART = cmdhandler.CMD_LOGINSTART
            del cmdhandler

        syscmdkeys = SystemCmds()
        del SystemCmds
        del _EvContainer

    def set_trace(term_size=(140, 80), debugger="auto"):
        """
        Helper function for running a debugger inside the Evennia event loop.

        Args:
            term_size (tuple, optional): Only used for Pudb and defines the size of the terminal
                (width, height) in number of characters.
            debugger (str, optional): One of 'auto', 'pdb' or 'pudb'. Pdb is the standard debugger. Pudb
                is an external package with a different, more 'graphical', ncurses-based UI. With
                'auto', will use pudb if possible, otherwise fall back to pdb. Pudb is available through
                `pip install pudb`.

        Notes:
            To use:

            1) add this to a line to act as a breakpoint for entering the debugger:

                from evennia import set_trace; set_trace()

            2) restart evennia in interactive mode

                evennia istart

            3) debugger will appear in the interactive terminal when breakpoint is reached. Exit
               with 'q', remove the break line and restart server when finished.

        """
        import sys

        dbg = None

        if debugger in ("auto", "pudb"):
            try:
                from pudb import debugger

                dbg = debugger.Debugger(stdout=sys.__stdout__, term_size=term_size)
            except ImportError:
                if debugger == "pudb":
                    raise
                pass

        if not dbg:
            import pdb

            dbg = pdb.Pdb(stdout=sys.__stdout__)

        try:
            # Start debugger, forcing it up one stack frame (otherwise `set_trace`
            # will start debugger this point, not the actual code location)
            dbg.set_trace(sys._getframe().f_back)
        except Exception:
            # Stopped at breakpoint. Press 'n' to continue into the code.
            dbg.set_trace()

    # initialize the doc string
    global __doc__
    __doc__ = DOCSTRING.format(
        "\n- "
        + "\n- ".join(
            f"evennia.{key}"
            for key in sorted(globals())
            if not key.startswith("_") and key not in ("DOCSTRING",)
        )
    )

Note

You are reading an old version of the Evennia documentation. The latest version is here

.