Ejemplo n.º 1
0
 def func(self):
     game = self.caller.search("game")
     players = list(search_tag("pc"))
     for x in players:
         player = self.caller.search(x)
         if not player:
             continue
         player.end_turn()
Ejemplo n.º 2
0
    def func(self):
        game = search_tag("Game")

        stats = game[0].get_stats()
        string = ""
        for x in stats:
            string += "%s: %s\n" % (x, stats[x])
        self.caller.msg(string)
Ejemplo n.º 3
0
    def find_phone(self, phone_number):
        """Return the object with this associated phone number, or None.

        Args:
            phone_number (str): the phone number.

        """
        phones = search_tag(phone_number, category="phone number")
        return phones[0] if phones else None
Ejemplo n.º 4
0
def results(caller, **kwargs):
    game = caller.search("Game")
    players = list(search_tag("pc"))
    if not kwargs:
        string = ""
    else:
        string = kwargs["text"]
    for x in players:
        player = caller.search(x)
        if not player:
            continue
        player.db.inventory["Budget"] += 15000
    stats = game.get_stats()
    for x in stats:
        string += "%s: %s\n" % (x, stats[x])

    return string, None
Ejemplo n.º 5
0
    def func(self):
        """ """
        char = self.character
        here = char.location
        account = self.account
        cmd = self.cmdstring
        switches = self.switches
        args = self.args.strip()
        zones = ['zone', 'area', 'region', 'realm']
        switches_list = [u'search']

        if not switches:
            zones_here = [here.tags.get(category='realm')]
            if here and zones_here[0]:
                zones_here.append(here.tags.get(category='region'))
                zones_here.append(here.tags.get(category='area'))
                zones_here.append(here.tags.get(category='zone'))
                account.msg('Zone here: |c%s' % "|n, |c".join(
                    a for a in [x for x in zones_here if x is not None]))
            else:
                account.msg(
                    "No realm zone found here. You are not in any realm.")
                return
        elif not all(x in switches_list for x in switches):
            account.msg("Not a valid switch for %s. Use only these: |g/%s" %
                        (cmd, "|n, |g/".join(switches_list)))
            return
        if 'search' in switches:
            if not args or args not in zones or self.lhs not in zones:
                account.msg(
                    "Searching requires providing a search string.  Try one of: zone, area, region, or realm."
                )
                return
            else:
                category = self.rhs or args
                zone = self.lhs if not self.rhs else args
                rooms = search.search_tag(zone, category=category)
                room_count = len(rooms)
                if room_count > 0:
                    match_string = ", ".join(
                        r.get_display_name(account) for r in rooms)
                    string = "Found |w%i|n room%s with zone category '|g%s|n':\n %s" % \
                             (room_count, "s" if room_count > 1 else '', args, match_string)
                    account.msg(string)
                else:
                    account.msg("No %s zones found." % args)
Ejemplo n.º 6
0
    def prep_puppet(self, nick):
        """
        This method will find an existing puppet or create a puppet of
        a given name. It will then teleport the puppet to the location
        and keep a reference to more easily facilitate passing commands to.

        Used when first connecting to a IRC channel or a new user joins.

        Args:
            nick (str): The name of the user the puppet will represent.
        """
        # Ignore bot and automatic users.
        if nick in self.db.userignorelist:
            return

        puppetdict = self.db.puppetdict

        # List of puppet objects with matching name.
        puppetlist = [
            puppet for puppet in search.search_tag(self.key + "-puppet")
            if puppet.key == self.db.puppetprefix + nick + self.db.puppetsuffix
        ]

        # Use an existing puppet.
        if puppetlist:
            puppetdict[nick] = puppetlist[0]
            if not puppetdict[nick].location == self.db.ev_location:
                puppetdict[nick].move_to(self.db.ev_location, quiet=True)
                self.db.ev_location.msg_contents(puppetdict[nick].key +
                                                 self.db.puppetentrymsg)

        # Create a new puppet.
        else:
            puppetdict[nick] = create.create_object(
                DefaultPuppet,
                key=self.db.puppetprefix + nick + self.db.puppetsuffix,
                location=self.db.ev_location)
            puppetdict[nick].db.nick = nick
            puppetdict[nick].db.desc = self.db.puppetdefaultdesc
            puppetdict[nick].tags.add(self.key + "-puppet")
            puppetdict[nick].db.bot = self
            self.db.ev_location.msg_contents(puppetdict[nick].key +
                                             self.db.puppetentrymsg)
        return
Ejemplo n.º 7
0
    def func(self):
        """ """
        char = self.character
        here = char.location
        account = self.account
        cmd = self.cmdstring
        switches = self.switches
        args = self.args.strip()
        zones = ['zone', 'area', 'region', 'realm']
        switches_list = [u'search']

        if not switches:
            zones_here = [here.tags.get(category='realm')]
            if here and zones_here[0]:
                zones_here.append(here.tags.get(category='region'))
                zones_here.append(here.tags.get(category='area'))
                zones_here.append(here.tags.get(category='zone'))
                account.msg('Zone here: |c%s' % "|n, |c".join(a for a in [x for x in zones_here if x is not None]))
            else:
                account.msg("No realm zone found here. You are not in any realm.")
                return
        elif not all(x in switches_list for x in switches):
            account.msg("Not a valid switch for %s. Use only these: |g/%s" % (cmd, "|n, |g/".join(switches_list)))
            return
        if 'search' in switches:
            if not args or args not in zones or self.lhs not in zones:
                account.msg("Searching requires providing a search string.  Try one of: zone, area, region, or realm.")
                return
            else:
                category = self.rhs or args
                zone = self.lhs if not self.rhs else args
                rooms = search.search_tag(zone, category=category)
                room_count = len(rooms)
                if room_count > 0:
                    match_string = ", ".join(r.get_display_name(account) for r in rooms)
                    string = "Found |w%i|n room%s with zone category '|g%s|n':\n %s" % \
                             (room_count, "s" if room_count > 1 else '', args, match_string)
                    account.msg(string)
                else:
                    account.msg("No %s zones found." % args)
Ejemplo n.º 8
0
    def delete(self, *args, **kwargs):
        """
        Deletes the bot permanently.

        Notes:
            `*args` and `**kwargs` are passed on to the base delete
             mechanism (these are usually not used).

        """
        # Delete listener
        if self.db.listener:
            self.db.listener.delete()

        # Delete puppets
        puppetlist = [
            puppet for puppet in search.search_tag(self.key + "-puppet")
        ]
        for puppet in puppetlist:
            puppet.delete()

        # Delete bot
        self.db.ev_location.msg_contents("Bot commencing shut-down process.")
        super().delete(*args, **kwargs)
Ejemplo n.º 9
0
    def func(self):
        caller = self.caller

        armed_puzzles = search.search_tag(_PUZZLES_TAG_MEMBER,
                                          category=_PUZZLES_TAG_CATEGORY)

        armed_puzzles = dict((k, list(g)) for k, g in itertools.groupby(
            armed_puzzles, lambda ap: ap.db.puzzle_name))

        div = "-" * 60
        msgf_pznm = "Puzzle name: |y%s|n"
        msgf_item = "|m%25s|w(%s)|n at |c%25s|w(%s)|n"
        text = [div]
        for pzname, items in armed_puzzles.items():
            text.append(msgf_pznm % (pzname))
            for item in items:
                text.append(msgf_item %
                            (item.name, item.dbref, item.location.name,
                             item.location.dbref))
        else:
            text.append(div)
            text.append("Found |r%d|n armed puzzle(s)." % (len(armed_puzzles)))
            text.append(div)
        caller.msg("\n".join(text))
Ejemplo n.º 10
0
 def objs(self):
     """Return the list of objects with the PObj's key."""
     return search_tag(self.key, category="pobj")
Ejemplo n.º 11
0
    def execute_cmd(self, session=None, txt=None, **kwargs):
        """
        Take incoming data and make the appropriate action. This acts as a
        CommandHandler of sorts for the various "type" of actions the PortalBot 
        returns to the Evennia. This is triggered by the bot_data_in Inputfunc.

        Args:
            session (Session, optional): Session responsible for this
                                         command. Note that this is the bot.
            txt (str, optional):  Command string.
        Kwargs:
            user (str): The name of the user who sent the message.
            channel (str): The name of channel the message was sent to.
            nicklist (list, optional): Set if `type='nicklist'`. This is a
                                       list of nicks returned by calling
                                       the `self.get_nicklist`. It must look
                                       for a list `self._nicklist_callers`
                                       which will contain all callers waiting
                                       for the nicklist.
            timings (float, optional): Set if `type='ping'`. This is the return
                                       (in seconds) of a ping request triggered
                                       with `self.ping`. The return must look
                                       for a list `self._ping_callers` which
                                       will contain all callers waiting for
                                       the ping return.
            type (str): The type of response returned by the IRC bot.
                        Including:
                        "nicklist": Returned when first joining a channel.
                        "joined": Returned when a new user joins a channel.
                        "left": Returned when a user leaves a channel.
                        "action": Returned when a user uses /me in IRC
                        Everything else is assumed to be text to speak.
        """
        if kwargs["type"] == "nicklist":
            """
            Returned when first joining a channel.
            """
            # Send Nicklist to requesting players
            if hasattr(self, "_nicklist_callers") and self._nicklist_callers:
                chstr = "%s (%s:%s)" % (self.db.irc_channel,
                                        self.db.irc_network, self.db.irc_port)
                nicklist = ", ".join(
                    sorted(kwargs["nicklist"], key=lambda n: n.lower()))
                for obj in self._nicklist_callers:
                    obj.msg("Nicks at %s:\n %s" % (chstr, nicklist))
                self._nicklist_callers = []
                return

            # Called by AccountBot to initiate puppets.
            else:
                self.prep_listener()

                # Prepare puppets
                self.db.puppetdict = {}
                for nick in kwargs["nicklist"]:
                    self.prep_puppet(ansi.strip_ansi(nick))

                # Hide stale puppets.
                for puppet in search.search_tag(self.key + "-puppet"):
                    if puppet.location is not None \
                            and puppet not in self.db.puppetdict.values():
                        puppet.move_to(None, to_none=True)
                return

        elif kwargs["type"] == "ping":
            """
            Returned by the ping command.
            """
            if hasattr(self, "_ping_callers") and self._ping_callers:
                chstr = "%s (%s:%s)" % (self.db.irc_channel,
                                        self.db.irc_network, self.db.irc_port)
                for obj in self._ping_callers:
                    obj.msg("IRC ping return from %s took %ss." %
                            (chstr, kwargs["timing"]))
                self._ping_callers = []
            return

        elif kwargs["type"] == "joined":
            """
            Returned when a new user joins a channel - Prepare Puppet
            """
            for nick in kwargs["nicklist"]:
                self.prep_puppet(ansi.strip_ansi(nick))
            return

        elif kwargs["type"] == "renamed":
            """
            Returned when IRC user changes nick.
            """
            puppetdict = self.db.puppetdict
            newname = kwargs["newname"]
            oldname = kwargs["oldname"]

            # List of puppet objects matching newname.
            puppetlist = [
                puppet for puppet in search.search_tag(self.key + "-puppet")
                if puppet.key == newname
            ]

            # Use an existing puppet.
            if puppetlist:
                # Set up new puppet
                puppetdict[newname] = puppetlist[0]
                if not puppetdict[newname].location == self.db.ev_location:
                    puppetdict[newname].move_to(self.db.ev_location,
                                                quiet=True)
                    self.db.ev_location.msg_contents(oldname + " has become " +
                                                     newname)
                # Pack up old puppet
                self.db.puppetdict[oldname].move_to(None, to_none=True)
                del self.db.puppetdict[oldname]

            # Else recycle old puppet.
            elif oldname in puppetdict:
                puppetdict[oldname].key = newname
                puppetdict[newname] = puppetdict.pop(oldname)
                self.db.ev_location.msg_contents(oldname + " has become " +
                                                 newname)
                return

        elif kwargs["type"] == "left":
            """
            Returned when a user leaves a channel - Pack up puppet.
            """
            for nick in kwargs["nicklist"]:
                nick = ansi.strip_ansi(nick)
                if nick in self.db.puppetdict:
                    self.db.puppetdict[nick].move_to(None, to_none=True)
                    self.db.ev_location.msg_contents(nick +
                                                     self.db.puppetexitmsg)
                    del self.db.puppetdict[nick]
            return

        elif kwargs["type"] == "action":
            """
            Returned when a user uses /me in IRC
            Causes in-game puppet to act out pose.
            """
            nick = ansi.strip_ansi(kwargs["user"])
            if nick in self.db.puppetdict:
                self.db.puppetdict[nick].execute_cmd("pose " + txt)
            return

        else:
            """
            Everything else is assumed to be text to speak.
            Cause the puppet to say the message.
            """
            nick = ansi.strip_ansi(kwargs["user"])
            if nick in self.db.puppetdict:
                self.db.puppetdict[nick].execute_cmd("say " + txt)
            return
Ejemplo n.º 12
0
 def characters(self):
     """Return the list of characters with the PChar's key."""
     return search_tag(self.key, category="pchar")
Ejemplo n.º 13
0
 def at_rename(self, old_name, new_name):
     """The key (name) of the prototype is changed."""
     for character in search_tag(old_name, category="pchar"):
         character.tags.remove(old_name, category="pchar")
         character.tags.add(new_name, category="pchar")
Ejemplo n.º 14
0
 def rooms(self):
     """Return the list of rooms of this prototype."""
     return search_tag(self.key, category="proom")
Ejemplo n.º 15
0
 def at_rename(self, old_name, new_name):
     """The key (name) of the prototype has changed."""
     for room in search_tag(old_name, category="proom"):
         room.tags.remove(old_name, category="proom")
         room.tags.add(new_name, category="proom")
Ejemplo n.º 16
0
    def func(self):
        """ """
        char = self.character
        here = char.location
        account = self.account
        cmd = self.cmdstring
        args = self.args.strip()
        lhs, rhs = [self.lhs, self.rhs]
        opt = self.switches
        opt_list = [u'list', u'info', u'long', u'search']

        if not all(x in opt_list for x in opt):
            account.msg("Not a valid switch for |y%s|n. Use only these: |g/%s" % (cmd, "|n, |g/".join(opt_list)))
            return
        if not opt or 'long' in opt:
            obj = here
            if not lhs:
                if not here:
                    account.msg("No flag can be put on this location. Trying flags on %s%s|n/" % (char.STYLE, char.key))
                    obj = char
            else:
                obj = char.search(lhs, location=[char, char.location]) if args else here
                if not obj:
                    return
            flags_obj = obj.tags.all(category='flags')
            flags_obj_count = len(flags_obj)
            if flags_obj:  # returns a list of flags
                if 'long' in opt:
                    account.msg('Flag list on %s: (%s): ' % (obj.get_display_name(account), flags_obj_count))
                    for flag in flags_obj:
                        account.msg('|c%s: |w%s|n|/' % (flag, self.FLAGS[flag]))
                else:
                    account.msg('Flag list on %s: (%s) = |c%s' %
                               (obj.get_display_name(account), flags_obj_count, "|n, |c".join(a for a in flags_obj)))
            else:
                account.msg('Flag list is not found on %s.' % obj.get_display_name(account))
            if rhs:  # If something is on the right hand side!
                good_flag = [x for x in self.FLAGS if x in rhs]
                overlap = [x for x in good_flag if x in flags_obj]
                to_set = [x for x in good_flag if x not in overlap]
                if overlap:
                    is_one = abs(len(overlap)) == 1
                    plural = '' if is_one else 's'
                    account.msg('Flag%s already set: |y%s' % (plural, "|n, |y".join(a for a in overlap)))
                is_one = abs(len(to_set)) == 1
                plural = '' if is_one else 's'
                account.msg('Set flag%s: |g%s' % (plural, "|n, |g".join(a for a in to_set)))
        if 'list' in opt:
            account.msg('Displaying list of ' + ('|ymatching' if args else '|gall') + '|n flags:')
            if args:  # Show list of matching flags
                match_list = [x for x in self.FLAGS if x in args]  # This match is not "starts with" or partial.
                account.msg('|c%s' % "|n, |c".join(match_list))
            else:
                account.msg('|c%s' % "|n, |c".join(a for a in self.FLAGS))
        if 'info' in opt:
            good_flag = [x for x in self.FLAGS if x in args] if args else self.FLAGS
            account.msg('Displaying info for ' + ('|ymatching' if args else '|gall') + '|n flags:')
            account.msg("|/".join('|c%s|n - |w%s' % (a, self.FLAGS[a]) for a in good_flag))
        if 'search' in opt:
            obj = search.search_tag(args, category='flags')
            object_count = len(obj)
            if object_count > 0:
                match_string = ", ".join(o.get_display_name(account) for o in obj)
                if args:
                    string = "Found |w%i|n object%s with the flag '|g%s|n' set:\n %s" %\
                             (object_count, "s" if object_count > 1 else '', args, match_string)
                else:
                    string = "Found |w%i|n object%s with any flag set:\n %s" % \
                             (object_count, "s" if object_count > 1 else '', match_string)
                account.msg(string)
            else:
                account.msg('Found no objects flagged: "|g%s"' % args)
Ejemplo n.º 17
0
 def at_rename(self, old_name, new_name):
     """The key (name) of the prototype has changed."""
     for obj in search_tag(old_name, category="pobj"):
         obj.tags.remove(old_name, category="pobj")
         obj.tags.add(new_name, category="pobj")
Ejemplo n.º 18
0
    def func(self):
        """Setup the irc-channel mapping"""

        if not settings.IRC_ENABLED:
            string = "IRC is not enabled. Activate it in game/settings.py."
            self.msg(string)
            return

        # If no args: list bots.
        if not self.args:
            # show all connections
            ircbots = [
                bot for bot in AccountDB.objects.filter(
                    db_is_bot=True, username__startswith="ircbot-")
            ]
            if ircbots:
                from evennia.utils.evtable import EvTable
                table = EvTable("|w#dbref|n",
                                "|wbotname|n",
                                "|wev-channel/location|n",
                                "|wirc-channel|n",
                                "|wSSL|n",
                                maxwidth=_DEFAULT_WIDTH)
                for ircbot in ircbots:
                    ircinfo = "%s (%s:%s)" % (ircbot.db.irc_channel,
                                              ircbot.db.irc_network,
                                              ircbot.db.irc_port)
                    table.add_row(
                        "#%i" % ircbot.id, ircbot.db.irc_botname,
                        ircbot.attributes.get("ev_channel",
                                              ircbot.db.ev_location.key),
                        ircinfo, ircbot.db.irc_ssl)
                self.msg(table)
                self.msg("Use 'help @puppetbot' for more infomation.")
            else:
                self.msg("No irc bots found.")
            return

        # Switch options available only if valid bot is given.
        if self.switches:
            botname = "ircbot-%s" % self.lhs
            matches = AccountDB.objects.filter(db_is_bot=True,
                                               username=botname)
            dbref = utils.dbref(self.lhs)
            if not matches and dbref:
                # try dbref match
                matches = AccountDB.objects.filter(db_is_bot=True, id=dbref)
            if not matches:
                self.msg("No valid bot given. Consult 'help @puppetbot'")
                return

            # Puppetbot/delete <bot> - Delete bot.
            if any(i in ['disconnect', 'remove', 'delete']
                   for i in self.switches):
                matches[0].delete()
                self.msg("IRC link/bot destroyed.")
                return

            # Puppetbot/ping <bot> - ping bot.
            if "ping" in self.switches:
                matches[0].ping(self.caller)
                self.msg("Pinging " + self.lhs)
                return

            # Puppetbot/who <bot> - Get IRC user list..
            if "who" in self.switches:
                # retrieve user list. The bot must handles the echo since it's
                # an asynchronous call.
                self.caller.msg(
                    "Requesting nicklist from %s (%s:%s)." %
                    (matches[0].db.irc_channel, matches[0].db.irc_network,
                     matches[0].db.irc_port))
                matches[0].get_nicklist(self.caller)
                return

            # Puppetbot/reconnect <bot> - reconnect bot.
            if "reconnect" in self.switches:
                matches[0].reconnect()
                self.msg("Reconnecting " + self.lhs)
                return

            # Puppetbot/reload <bot> - Delete all bots, recreates bots from new user list.
            if "reload" in self.switches:
                matches[0].db.ev_location.msg_contents(
                    "Puppet reload in progress.")
                puppetlist = [
                    puppet
                    for puppet in search.search_tag(matches[0].key + "-puppet")
                ]
                for puppet in puppetlist:
                    puppet.delete()
                matches[0].get_nicklist()
                return

        # Create Bot.
        location = self.caller.location
        self.args = self.args.replace('#', ' ')  # Avoid Python comment issues
        try:
            irc_network, irc_port, irc_channel, irc_botname = \
                       [part.strip() for part in self.args.split(None, 4)]
            irc_channel = "#%s" % irc_channel
        except Exception:
            string = "IRC bot definition '%s' is not valid." % self.args
            self.msg(string)
            return

        botname = "ircbot-%s" % irc_botname
        # create a new bot
        bot = AccountDB.objects.filter(username__iexact=botname)
        if bot:
            self.msg("Account '%s' already exists." % botname)
            return
        else:
            password = "******"
            try:
                bot = create.create_account(botname,
                                            None,
                                            password,
                                            typeclass=AccountBot)
            except Exception as err:
                self.msg("|rError, could not create the bot:|n '%s'." % err)
                return
        bot.start(ev_location=location,
                  irc_botname=irc_botname,
                  irc_channel=irc_channel,
                  irc_network=irc_network,
                  irc_port=irc_port)
        self.msg("Connection created. Starting IRC bot.")
Ejemplo n.º 19
0
    def func(self):
        """Setup the irc-channel mapping"""

        if not settings.IRC_ENABLED:
            string = "IRC is not enabled. Activate it in game/settings.py."
            self.msg(string)
            return

        # If no args: list bots.
        if not self.args:
            # show all connections
            ircbots = [
                bot for bot in AccountDB.objects.filter(
                    db_is_bot=True, username__startswith="ircbot-")
            ]
            if ircbots:
                from evennia.utils.evtable import EvTable
                table = EvTable("|w#dbref|n",
                                "|wbotname|n",
                                "|wev-channel/location|n",
                                "|wirc-channel|n",
                                "|wSSL|n",
                                maxwidth=_DEFAULT_WIDTH)
                for ircbot in ircbots:
                    ircinfo = "%s (%s:%s)" % (ircbot.db.irc_channel,
                                              ircbot.db.irc_network,
                                              ircbot.db.irc_port)
                    table.add_row(
                        "#%i" % ircbot.id, ircbot.db.irc_botname,
                        ircbot.attributes.get("ev_channel",
                                              ircbot.db.ev_location.key),
                        ircinfo, ircbot.db.irc_ssl)
                self.msg(table)
                self.msg("Use 'help @puppetbot' for more infomation.")
            else:
                self.msg("No irc bots found.")
            return

        # Switch options available only if valid bot is given.
        if self.switches:
            botname = "ircbot-%s" % self.lhs
            matches = AccountDB.objects.filter(db_is_bot=True,
                                               username=botname)
            dbref = utils.dbref(self.lhs)
            if not matches and dbref:
                # try dbref match
                matches = AccountDB.objects.filter(db_is_bot=True, id=dbref)
            if not matches:
                self.msg("No valid bot given. Consult 'help @puppetbot'")
                return

            # Puppetbot/delete <bot> - Delete bot.
            if any(i in ['disconnect', 'remove', 'delete']
                   for i in self.switches):
                matches[0].delete()
                self.msg("IRC link/bot destroyed.")
                return

            # Puppetbot/ping <bot> - ping bot.
            if "ping" in self.switches:
                matches[0].ping(self.caller)
                self.msg("Pinging " + self.lhs)
                return

            # Puppetbot/about <bot> = msg - Set bot about message.
            if "about" in self.switches:
                if self.rhs:
                    matches[0].db.botdesc = self.rhs
                    self.msg("Bot about message changed to: " + self.rhs)
                else:
                    self.msg("No message given. 'About' desc change aborted.")
                return

            # Puppetbot/who <bot> - Get IRC user list..
            if "who" in self.switches:
                # retrieve user list. The bot must handles the echo since it's
                # an asynchronous call.
                self.caller.msg(
                    "Requesting nicklist from %s (%s:%s)." %
                    (matches[0].db.irc_channel, matches[0].db.irc_network,
                     matches[0].db.irc_port))
                matches[0].get_nicklist(self.caller)
                return

            # Puppetbot/reconnect <bot> - reconnect bot.
            if "reconnect" in self.switches:
                matches[0].reconnect()
                self.msg("Reconnecting " + self.lhs)
                return

            # Puppetbot/reload <bot> - Delete all bots, recreates bots from new user list.
            if "reload" in self.switches:
                matches[0].db.ev_location.msg_contents(
                    "Puppet reload in progress.")
                puppetlist = [
                    puppet
                    for puppet in search.search_tag(matches[0].key + "-puppet")
                ]
                for puppet in puppetlist:
                    puppet.delete()
                matches[0].get_nicklist()
                return

            # Puppetbot/ignore <bot> = puppet - Toggle ignore IRC user.
            if "ignore" in self.switches:
                if self.rhs:
                    user = self.rhs.strip()
                    # If already ignored, toggle off.
                    if user in matches[0].db.userignorelist:
                        matches[0].db.userignorelist.remove(user)
                        matches[0].get_nicklist()
                        return

                    # Else ignore user.
                    else:
                        matches[0].db.userignorelist.append(user)
                        if user in matches[0].db.puppetdict:
                            matches[0].db.puppetdict[user].delete()
                            del matches[0].db.puppetdict[user]
                        return
                else:
                    self.msg("Usage: Puppetbot/ignore <bot> = <puppet>")
                    return

            # Puppetbot/entrymsg <bot> = msg - Set default puppet creation message.
            if "entrymsg" in self.switches:
                if self.rhs:
                    matches[0].db.puppetentrymsg = " " + self.rhs
                    self.msg("Bot entry message changed to: " + " " + self.rhs)
                else:
                    self.msg("No message given. Message change aborted.")
                return

            # Puppetbot/exitmsg <bot> = msg - Set default puppet deletion message.
            if "exitmsg" in self.switches:
                if self.rhs:
                    matches[0].db.puppetexitmsg = " " + self.rhs
                    self.msg("Bot exit message changed to: " + " " + self.rhs)
                else:
                    self.msg("No message given. Message change aborted.")
                return

            # Puppetbot/prefix <bot> = msg - Set string put before username in puppet.key
            if "prefix" in self.switches:
                if self.rhs:
                    matches[0].db.puppetprefix = self.rhs
                    self.msg("Puppet prefix changed to: " + self.rhs)
                    self.msg(
                        "Use: '@puppetbot/reload <bot>' to implement changes.")
                else:
                    self.msg("No message given. Prefix change aborted.")
                return

            # Puppetbot/suffix <bot> = msg - Set string put after username in puppet.key
            if "suffix" in self.switches:
                if self.rhs:
                    matches[0].db.puppetsuffix = self.rhs
                    self.msg("Puppet suffix changed to: " + self.rhs)
                    self.msg(
                        "Use: '@puppetbot/reload <bot>' to implement changes.")
                else:
                    self.msg("No message given. Suffix change aborted.")
                return

            # Puppetbot/defaultdesc <bot> = msg - Set default puppet desc message.
            if "defaultdesc" in self.switches:
                if self.rhs:
                    matches[0].db.puppetlastdesc = matches[
                        0].db.puppetdefaultdesc
                    matches[0].db.puppetdefaultdesc = self.rhs
                    self.msg("Default puppet description changed to: " +
                             self.rhs)
                else:
                    self.msg("No message given. Message change aborted.")
                return

            # Puppetbot/softdesc <bot> = msg - Only changes non custom puppet descriptions to new default.
            if "softdesc" in self.switches:
                puppetlist = [
                    puppet
                    for puppet in search.search_tag(matches[0].key + "-puppet")
                ]
                for puppet in puppetlist:
                    if puppet.db.desc == matches[0].db.puppetlastdesc:
                        puppet.db.desc = matches[0].db.puppetdefaultdesc
                self.msg("Puppets description changed to: " +
                         matches[0].db.puppetdefaultdesc)
                return

            # Puppetbot/forcedesc <bot> = msg - Changes all puppet descriptions to new default.
            if "forcedesc" in self.switches:
                puppetlist = [
                    puppet
                    for puppet in search.search_tag(matches[0].key + "-puppet")
                ]
                for puppet in puppetlist:
                    puppet.db.desc = matches[0].db.puppetdefaultdesc
                self.msg("Puppets description changed to: " +
                         matches[0].db.puppetdefaultdesc)
                return

        # Create Bot.
        location = self.caller.location
        self.args = self.args.replace('#', ' ')  # Avoid Python comment issues
        try:
            irc_network, irc_port, irc_channel, irc_botname = \
                       [part.strip() for part in self.args.split(None, 4)]
            irc_channel = "#%s" % irc_channel
        except Exception:
            string = "IRC bot definition '%s' is not valid." % self.args
            self.msg(string)
            return

        botname = "ircbot-%s" % irc_botname
        # create a new bot
        bot = AccountDB.objects.filter(username__iexact=botname)
        if bot:
            # re-use an existing bot
            bot = bot[0]
            if not bot.is_bot:
                self.msg("'%s' already exists and is not a bot." % botname)
                return
        else:
            try:
                bot = create.create_account(botname,
                                            None,
                                            None,
                                            typeclass=ServerBot)
            except Exception as err:
                self.msg("|rError, could not create the bot:|n '%s'." % err)
                return
        bot.start(ev_location=location,
                  irc_botname=irc_botname,
                  irc_channel=irc_channel,
                  irc_network=irc_network,
                  irc_port=irc_port)
        self.msg("Connection created. Starting IRC bot.")
Ejemplo n.º 20
0
    def execute_cmd(self, session=None, txt=None, **kwargs):
        """
        Take incoming data and make the appropriate action. This acts as a
        CommandHandler of sorts for the various "type" of actions the Portal
        bot returns to the Server. This is triggered by the bot_data_in
        Inputfunc.

        Args:
            session (Session, optional): Session responsible for this
                command. Note that this is the bot.
            txt (str, optional):  Command string.
        Kwargs:
            user (str): The name of the user who sent the message.
            channel (str): The name of channel the message was sent to.
            nicklist (list, optional): Set if `type='nicklist'`. This is a
                                       list of nicks returned by calling
                                       the `self.get_nicklist`. It must look
                                       for a list `self._nicklist_callers`
                                       which will contain all callers waiting
                                       for the nicklist.
            timings (float, optional): Set if `type='ping'`. This is the return
                                       (in seconds) of a ping request triggered
                                       with `self.ping`. The return must look
                                       for a list `self._ping_callers` which
                                       will contain all callers waiting for
                                       the ping return.
            type (str): The type of response returned by the IRC bot.
                        Including:
                        "nicklist": Returned when first joining a channel.
                        "joined": Returned when a new user joins a channel.
                        "left": Returned when a user leaves a channel.
                        "privmsg": Returned when the bot is directly messaged.
                        "action": Returned when a user uses /me in IRC
                        Everything else is assumed to be text to speak.
        """
        if kwargs["type"] == "nicklist":
            """
            Returned when first joining a channel.
            """
            if hasattr(self, "_nicklist_callers") and self._nicklist_callers:
                chstr = "%s (%s:%s)" % (self.db.irc_channel,
                                        self.db.irc_network, self.db.irc_port)
                nicklist = ", ".join(
                    sorted(kwargs["nicklist"], key=lambda n: n.lower()))
                for obj in self._nicklist_callers:
                    obj.msg("Nicks at %s:\n %s" % (chstr, nicklist))
                self._nicklist_callers = []
                return

            else:
                # Prepare blank reference dictionary.
                self.db.puppetdict = {}

                # Prepare listener.
                self.prep_listener()

                # Prepare puppets.
                for nick in kwargs["nicklist"]:
                    self.prep_puppet(ansi.strip_ansi(nick))

                # Hide stale puppets.
                for puppet in search.search_tag(self.key + "-puppet"):
                    if puppet.location is not None \
                            and puppet not in self.db.puppetdict.values():
                        puppet.move_to(None, to_none=True)
                return

        elif kwargs["type"] == "ping":
            """
            Returned by the ping command.
            """
            if hasattr(self, "_ping_callers") and self._ping_callers:
                chstr = "%s (%s:%s)" % (self.db.irc_channel,
                                        self.db.irc_network, self.db.irc_port)
                for obj in self._ping_callers:
                    obj.msg("IRC ping return from %s took %ss." %
                            (chstr, kwargs["timing"]))
                self._ping_callers = []
            return

        elif kwargs["type"] == "joined":
            """
            Returned when a new user joins a channel.
            """
            # Prepare puppet.
            for nick in kwargs["nicklist"]:
                self.prep_puppet(ansi.strip_ansi(nick))
            return

        elif kwargs["type"] == "renamed":
            """
            Returned when IRC user changes nick.
            """
            puppetdict = self.db.puppetdict
            newname = kwargs["newname"]
            oldname = kwargs["oldname"]
            newkey = self.db.puppetprefix + newname + self.db.puppetsuffix
            oldkey = self.db.puppetprefix + oldname + self.db.puppetsuffix

            # List of puppet objects matching newname.
            puppetlist = [
                puppet for puppet in search.search_tag(self.key + "-puppet")
                if puppet.key == newkey
            ]

            # Use an existing puppet.
            if puppetlist:
                # Set up new puppet
                puppetdict[newname] = puppetlist[0]
                if not puppetdict[newname].location == self.db.ev_location:
                    puppetdict[newname].move_to(self.db.ev_location,
                                                quiet=True)
                    self.db.ev_location.msg_contents(oldkey + " has become " +
                                                     newkey)
                # Pack up old puppet
                self.db.puppetdict[oldname].move_to(None, to_none=True)
                del self.db.puppetdict[oldname]

            # Else recycle old puppet.
            elif oldname in puppetdict:
                print('Reusing puppetbot from puppetdict: ', oldname,
                      puppetdict[oldname])
                puppetdict[oldname].key = newkey
                puppetdict[newname] = puppetdict.pop(oldname)
                self.db.ev_location.msg_contents(oldkey + " has become " +
                                                 newkey)
                return

        elif kwargs["type"] == "left":
            """
            Returned when a user leaves a channel.
            """
            # Pack up puppet.
            for nick in kwargs["nicklist"]:
                nick = ansi.strip_ansi(nick)
                if nick in self.db.puppetdict:
                    self.db.puppetdict[nick].move_to(None, to_none=True)
                    self.db.ev_location.msg_contents(
                        self.db.puppetdict[nick].key + self.db.puppetexitmsg)
                    del self.db.puppetdict[nick]
            return

        elif kwargs["type"] == "privmsg":
            """
            Returned when the bot is directly messaged.
            Users can issue commands to the Server bot through IRC PM.
            "Who" - Return a list of current users in the MUD
            "About" - Describes the bot and the connected MUD
            "Look" - Look at the Evennia location and those within it.
            "whisper" - Whisper in-game account "whisper user = msg"
            "Desc" - If empty, shows in-game bots description. Else, sets bots
                     in-game bot description to given value.
            All other messages return a help message.
            """

            user = kwargs["user"]

            # Who command - Returns online users in game.
            if txt.lower().startswith("who"):
                # return server WHO list (abbreviated for IRC)
                global _SESSIONS
                if not _SESSIONS:
                    from evennia.server.sessionhandler import \
                        SESSIONS as _SESSIONS
                whos = []
                t0 = time.time()
                for sess in _SESSIONS.get_sessions():
                    delta_cmd = t0 - sess.cmd_last_visible
                    delta_conn = t0 - session.conn_time
                    account = sess.get_account()
                    whos.append("%s (%s/%s)" %
                                (utils.crop("|w%s|n" % account.name, width=25),
                                 utils.time_format(delta_conn, 0),
                                 utils.time_format(delta_cmd, 1)))
                text = "Who list (online/idle): %s" % ", ".join(
                    sorted(whos, key=lambda w: w.lower()))

                # Return Message.
                super(ServerBot, self).msg(privmsg=((text, ), {"user": user}))

            # About command - Return a blurb explaining origin of bot.
            elif txt.lower().startswith("about"):
                # some bot info
                text = self.db.botdesc

                # Return Message.
                super(ServerBot, self).msg(privmsg=((text, ), {"user": user}))

            # Look command - Look at the Evennia location and those within it.
            elif txt.lower().startswith("look"):
                # Mirror in-game look command.
                txt = txt.partition(" ")[2]
                if not txt:
                    target = self.db.ev_location
                else:
                    result = search.object_search(
                        txt, candidates=self.db.ev_location.contents)
                    target = result[0] if len(result) > 0 else None

                if not target:
                    text = "'%s' could not be located." % txt
                else:
                    text = target.return_appearance(
                        self.db.puppetdict[user]).replace('\n', ' ')

                # Return Message.
                super(ServerBot, self).msg(privmsg=((text, ), {"user": user}))

            # Desc command - If empty, shows in-game bots description. Else,
            # sets bots in-game bot description to given value.
            elif txt.lower().startswith("desc"):
                # Split text - set desc as text or return current desc if none.
                txt = txt.partition(" ")[2]
                if not txt:
                    text = self.db.puppetdict[user].db.desc
                else:
                    self.db.puppetdict[user].db.desc = txt
                    text = "Desc changed to: " + txt

                # Return Message.
                super(ServerBot, self).msg(privmsg=((text, ), {"user": user}))

            # Whisper command - Whisper a user in game through a puppet.
            elif txt.lower().startswith("whisper"):

                # Parse input. Must be in form 'whisper nick = msg'
                txt = txt.split(" ", 1)[1]
                try:
                    nick, msg = txt.split("=")
                except Exception:
                    text = "Whisper Usage: 'Whisper Character = Msg'"
                    super(ServerBot, self).msg(privmsg=((text, ), {
                        "user": user
                    }))
                    return

                if not nick or not msg:
                    text = "Whisper Usage: 'Whisper Character = Msg'"
                    super(ServerBot, self).msg(privmsg=((text, ), {
                        "user": user
                    }))
                    return

                puppet = self.db.puppetdict[ansi.strip_ansi(user)]
                target = puppet.search(nick)

                if not target:
                    text = "Whisper Aborted: Character could not be found."
                    # Return Message.
                    super(ServerBot, self).msg(privmsg=((text, ), {
                        "user": user
                    }))
                    return

                puppet.execute_cmd("whisper " + nick + "=" + msg)
                text = 'You whisper to ' + nick + ', "' + msg + '"'
                super(ServerBot, self).msg(privmsg=((text, ), {"user": user}))
                return

            # Default message - Acts as help information.
            else:
                text = (
                    "Command list: \n"
                    '   "Who": Return a list of online users on %s.\n'
                    '   "About": Returns information about %s.\n'
                    '   "Look": Look at the Evennia location and those within it.\n'
                    '   "Desc": If empty, shows in-game bots description. Else, sets\n'
                    '   "whisper" - Whisper in-game account "whisper user = msg"\n'
                    '           bots in-game bot description to given value.\n'
                    '   All other messages return this help message.') % (
                        settings.SERVERNAME, settings.SERVERNAME)

                # Return Message.
                super(ServerBot, self).msg(privmsg=((text, ), {"user": user}))

        elif kwargs["type"] == "action":
            """
            Returned when a user uses /me in IRC
            """
            # Cause puppet to act out pose.
            if ansi.strip_ansi(kwargs["user"]) in self.db.puppetdict:
                user = ansi.strip_ansi(kwargs["user"])
                self.db.puppetdict[user].execute_cmd("pose " + txt)
            return

        else:
            """
            Everything else is assumed to be text to speak.
            """
            # Cause the puppet to say the message.
            if ansi.strip_ansi(kwargs["user"]) in self.db.puppetdict:
                user = ansi.strip_ansi(kwargs["user"])
                self.db.puppetdict[user].execute_cmd("say " + txt)
            return
Ejemplo n.º 21
0
Archivo: flag.py Proyecto: dimaguy/NOW
    def func(self):
        """ """
        char = self.character
        here = char.location
        account = self.account
        cmd = self.cmdstring
        args = self.args.strip()
        lhs, rhs = [self.lhs, self.rhs]
        opt = self.switches
        opt_list = [u'list', u'info', u'long', u'search']

        if not all(x in opt_list for x in opt):
            account.msg(
                "Not a valid switch for |y%s|n. Use only these: |g/%s" %
                (cmd, "|n, |g/".join(opt_list)))
            return
        if not opt or 'long' in opt:
            obj = here
            if not lhs:
                if not here:
                    account.msg(
                        "No flag can be put on this location. Trying flags on %s%s|n/"
                        % (char.STYLE, char.key))
                    obj = char
            else:
                obj = char.search(lhs, location=[char, char.location
                                                 ]) if args else here
                if not obj:
                    return
            flags_obj = obj.tags.all(category='flags')
            flags_obj_count = len(flags_obj)
            if flags_obj:  # returns a list of flags
                if 'long' in opt:
                    account.msg(
                        'Flag list on %s: (%s): ' %
                        (obj.get_display_name(account), flags_obj_count))
                    for flag in flags_obj:
                        account.msg('|c%s: |w%s|n|/' %
                                    (flag, self.FLAGS[flag]))
                else:
                    account.msg(
                        'Flag list on %s: (%s) = |c%s' %
                        (obj.get_display_name(account), flags_obj_count,
                         "|n, |c".join(a for a in flags_obj)))
            else:
                account.msg('Flag list is not found on %s.' %
                            obj.get_display_name(account))
            if rhs:  # If something is on the right hand side!
                good_flag = [x for x in self.FLAGS if x in rhs]
                overlap = [x for x in good_flag if x in flags_obj]
                to_set = [x for x in good_flag if x not in overlap]
                if overlap:
                    is_one = abs(len(overlap)) == 1
                    plural = '' if is_one else 's'
                    account.msg('Flag%s already set: |y%s' %
                                (plural, "|n, |y".join(a for a in overlap)))
                is_one = abs(len(to_set)) == 1
                plural = '' if is_one else 's'
                account.msg('Set flag%s: |g%s' %
                            (plural, "|n, |g".join(a for a in to_set)))
        if 'list' in opt:
            account.msg('Displaying list of ' +
                        ('|ymatching' if args else '|gall') + '|n flags:')
            if args:  # Show list of matching flags
                match_list = [x for x in self.FLAGS if x in args
                              ]  # This match is not "starts with" or partial.
                account.msg('|c%s' % "|n, |c".join(match_list))
            else:
                account.msg('|c%s' % "|n, |c".join(a for a in self.FLAGS))
        if 'info' in opt:
            good_flag = [x for x in self.FLAGS
                         if x in args] if args else self.FLAGS
            account.msg('Displaying info for ' +
                        ('|ymatching' if args else '|gall') + '|n flags:')
            account.msg("|/".join('|c%s|n - |w%s' % (a, self.FLAGS[a])
                                  for a in good_flag))
        if 'search' in opt:
            obj = search.search_tag(args, category='flags')
            object_count = len(obj)
            if object_count > 0:
                match_string = ", ".join(
                    o.get_display_name(account) for o in obj)
                if args:
                    string = "Found |w%i|n object%s with the flag '|g%s|n' set:\n %s" %\
                             (object_count, "s" if object_count > 1 else '', args, match_string)
                else:
                    string = "Found |w%i|n object%s with any flag set:\n %s" % \
                             (object_count, "s" if object_count > 1 else '', match_string)
                account.msg(string)
            else:
                account.msg('Found no objects flagged: "|g%s"' % args)
Ejemplo n.º 22
0
    def execute_cmd(self, session=None, txt=None, **kwargs):
        """
        Take incoming data and make the appropriate action. This acts as a
        CommandHandler of sorts for the various "type" of actions the Portal
        bot returns to the Server. This is triggered by the bot_data_in
        Inputfunc.
        Args:
            session (Session, optional): Session responsible for this
                command. Note that this is the bot.
            txt (str, optional):  Command string.
        Kwargs:
            user (str): The name of the user who sent the message.
            channel (str): The name of channel the message was sent to.
            nicklist (list, optional): Set if `type='nicklist'`. This is a
                                       list of nicks returned by calling
                                       the `self.get_nicklist`. It must look
                                       for a list `self._nicklist_callers`
                                       which will contain all callers waiting
                                       for the nicklist.
            timings (float, optional): Set if `type='ping'`. This is the return
                                       (in seconds) of a ping request triggered
                                       with `self.ping`. The return must look
                                       for a list `self._ping_callers` which
                                       will contain all callers waiting for
                                       the ping return.
            type (str): The type of response returned by the IRC bot.
                        Including:
                        "nicklist": Returned when first joining a channel.
                        "joined": Returned when a new user joins a channel.
                        "left": Returned when a user leaves a channel.
                        "privmsg": Returned when the bot is directly messaged.
                        "action": Returned when a user uses /me in IRC
                        Everything else is assumed to be text to speak.
        """

        if kwargs["type"] == "nicklist":
            """
            Returned when first joining a channel.
            """
            # Send Nicklist to requesting players
            if hasattr(self, "_nicklist_callers") and self._nicklist_callers:
                chstr = "%s (%s:%s)" % (self.db.irc_channel,
                                        self.db.irc_network, self.db.irc_port)
                nicklist = ", ".join(
                    sorted(kwargs["nicklist"], key=lambda n: n.lower()))
                for obj in self._nicklist_callers:
                    obj.msg("Nicks at %s:\n %s" % (chstr, nicklist))
                self._nicklist_callers = []
                return

            # Called by AccountBot to initiate puppets.
            else:
                self.prep_listener()

                # Prepare puppets
                self.db.puppetdict = {}
                for nick in kwargs["nicklist"]:
                    self.prep_puppet(ansi.strip_ansi(nick))

                # Hide stale puppets.
                for puppet in search.search_tag(self.key + "-puppet"):
                    if puppet.location is not None \
                            and puppet not in self.db.puppetdict.values():
                        puppet.move_to(None, to_none=True)
                return

        elif kwargs["type"] == "ping":
            """
            Returned by the ping command.
            """
            if hasattr(self, "_ping_callers") and self._ping_callers:
                chstr = "%s (%s:%s)" % (self.db.irc_channel,
                                        self.db.irc_network, self.db.irc_port)
                for obj in self._ping_callers:
                    obj.msg("IRC ping return from %s took %ss." %
                            (chstr, kwargs["timing"]))
                self._ping_callers = []
            return

        elif kwargs["type"] == "joined":
            """
            Returned when a new user joins a channel - Prepare Puppet
            """
            for nick in kwargs["nicklist"]:
                self.prep_puppet(ansi.strip_ansi(nick))
            return

        elif kwargs["type"] == "renamed":
            """
            Returned when IRC user changes nick.
            """
            puppetdict = self.db.puppetdict
            newname = kwargs["newname"]
            oldname = kwargs["oldname"]

            # List of puppet objects matching newname.
            puppetlist = [
                puppet for puppet in search.search_tag(self.key + "-puppet")
                if puppet.key == newname
            ]

            # Use an existing puppet.
            if puppetlist:
                # Set up new puppet
                puppetdict[newname] = puppetlist[0]
                if not puppetdict[newname].location == self.db.ev_location:
                    puppetdict[newname].move_to(self.db.ev_location,
                                                quiet=True)
                    self.db.ev_location.msg_contents(oldname + " has become " +
                                                     newname)
                # Pack up old puppet
                self.db.puppetdict[oldname].move_to(None, to_none=True)
                del self.db.puppetdict[oldname]

            # Else recycle old puppet.
            elif oldname in puppetdict:
                puppetdict[oldname].key = newname
                puppetdict[newname] = puppetdict.pop(oldname)
                self.db.ev_location.msg_contents(oldname + " has become " +
                                                 newname)
                return

        elif kwargs["type"] == "left":
            """
            Returned when a user leaves a channel - Pack up puppet.
            """
            for nick in kwargs["nicklist"]:
                nick = ansi.strip_ansi(nick)
                if nick in self.db.puppetdict:
                    self.db.puppetdict[nick].move_to(None, to_none=True)
                    self.db.ev_location.msg_contents(
                        self.db.puppetdict[nick].key +
                        self.db.puppetdict[nick].db.exit)
                    del self.db.puppetdict[nick]
            return

        elif kwargs["type"] == "action":
            """
            Returned when a user uses /me in IRC
            Causes in-game puppet to act out pose.
            """
            nick = ansi.strip_ansi(kwargs["user"])
            if nick in self.db.puppetdict:
                self.db.puppetdict[nick].execute_cmd("pose " + txt)
            return

        elif kwargs["type"] == "msg":
            """
            Returned when a user speaks in the IRC channel.
            Causes in-game puppet to say the message.
            """
            nick = ansi.strip_ansi(kwargs["user"])
            if nick in self.db.puppetdict:
                self.db.puppetdict[nick].execute_cmd("say " + txt)
            return

        elif kwargs["type"] == "privmsg":
            """
            Returned when the bot is directly messaged.
            Users can issue commands to the Server bot through IRC PM.
            "Look" - Look at the Evennia location and those within it.
            "whisper" - Whisper in-game account "whisper user = msg"
            All other messages return a help message.
            """
            user = ansi.strip_ansi(kwargs["user"])

            # Look command - Look at the Evennia location and those within it.
            if txt.lower().startswith("look"):
                # If given input:'look target' use target else use location.
                try:
                    txt = txt.split(" ", 1)[1]
                    result = search.object_search(
                        txt, candidates=self.db.ev_location.contents)
                    target = result[0] if result else None
                except IndexError:
                    target = self.db.ev_location

                if not target:
                    text = "'%s' could not be located." % txt
                else:
                    text = target.return_appearance(self.db.puppetdict[user])

                self.msg((text, {"type": "privmsg"}), from_obj=self, user=user)
                return

            # Whisper command - Whisper a user in game through a puppet.
            elif txt.lower().startswith("whisper"):
                # Parse input. Must be in form 'whisper nick = msg'
                txt = txt.split(" ", 1)[1]
                try:
                    nick, msg = txt.split("=")
                except Exception:
                    text = "Whisper Usage: 'Whisper Character = Msg'"
                    self.msg((text, {
                        "type": "privmsg"
                    }),
                             from_obj=self,
                             user=user)
                    return

                if not nick or not msg:
                    text = "Whisper Usage: 'Whisper Character = Msg'"
                    self.msg((text, {
                        "type": "privmsg"
                    }),
                             from_obj=self,
                             user=user)
                    return

                puppet = self.db.puppetdict[ansi.strip_ansi(user)]
                target = puppet.search(nick)

                if not target:
                    text = "Whisper Aborted: Character could not be found."
                    self.msg((text, {
                        "type": "privmsg"
                    }),
                             from_obj=self,
                             user=user)
                    return

                puppet.execute_cmd("whisper " + nick + "=" + msg)
                return

            # Default message - Acts as help information.
            else:
                text = """\
                Command list:
                -"Look": Look at the Evennia location and those within it. "look [object]"
                -"whisper": Whisper an in-game character as your puppet. "whisper Character = msg"
                - All other messages return this help message.\
                """
                # Return Message.
                self.msg((text, {"type": "privmsg"}), from_obj=self, user=user)