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()
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)
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
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
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)
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
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)
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)
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))
def objs(self): """Return the list of objects with the PObj's key.""" return search_tag(self.key, category="pobj")
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
def characters(self): """Return the list of characters with the PChar's key.""" return search_tag(self.key, category="pchar")
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")
def rooms(self): """Return the list of rooms of this prototype.""" return search_tag(self.key, category="proom")
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")
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)
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")
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.")
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.")
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
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)
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)