Make the irc bot accept who command from the IRC side.

This commit is contained in:
Griatch 2017-02-12 01:55:34 +01:00
parent 65a4e507f7
commit 63df95e4da
2 changed files with 110 additions and 21 deletions

View file

@ -4,11 +4,12 @@ Player that are controlled by the server.
""" """
from __future__ import print_function from __future__ import print_function
import time
from django.conf import settings from django.conf import settings
from evennia.players.players import DefaultPlayer from evennia.players.players import DefaultPlayer
from evennia.scripts.scripts import DefaultScript from evennia.scripts.scripts import DefaultScript
from evennia.utils import search from evennia.utils import search
from evennia.utils import utils
_IDLE_TIMEOUT = settings.IDLE_TIMEOUT _IDLE_TIMEOUT = settings.IDLE_TIMEOUT
@ -255,7 +256,7 @@ class IRCBot(Bot):
self.ndb.ev_channel = self.db.ev_channel self.ndb.ev_channel = self.db.ev_channel
if "from_channel" in options and text and self.ndb.ev_channel.dbid == options["from_channel"]: if "from_channel" in options and text and self.ndb.ev_channel.dbid == options["from_channel"]:
if not from_obj or from_obj != [self.id]: if not from_obj or from_obj != [self.id]:
super(IRCBot, self).msg(text=text, options={"bot_data_out": True}) super(IRCBot, self).msg(channel=text)
def execute_cmd(self, session=None, txt=None, **kwargs): def execute_cmd(self, session=None, txt=None, **kwargs):
""" """
@ -264,7 +265,7 @@ class IRCBot(Bot):
Args: Args:
session (Session, optional): Session responsible for this session (Session, optional): Session responsible for this
command. command. Note that this is the bot.
txt (str, optional): Command string. txt (str, optional): Command string.
Kwargs: Kwargs:
user (str): The name of the user who sent the message. user (str): The name of the user who sent the message.
@ -296,19 +297,47 @@ class IRCBot(Bot):
self._ping_callers = [] self._ping_callers = []
return return
elif kwargs["type"] == "action": elif kwargs["type"] == "privmsg":
# An action (irc pose) # A private message to the bot - a command.
text = "%s@%s %s" % (kwargs["user"], kwargs["channel"], txt) user = kwargs["user"]
print ("Private bot message received from %s: %s" % (user, txt))
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
player = sess.get_player()
whos.append("%s (%s/%s)" % (utils.crop("|w%s|n" % player.name, width=25),
utils.time_format(delta_conn, 0),
utils.time_format(delta_cmd, 1)))
text = "Who list (online/idle): %s" % ", ".join(whos)
elif txt.lower().startswith("about"):
# some bot info
text = "This is an Evennia IRC bot connecting from the game '%s'." % settings.SERVERNAME
else:
text = "I understand 'who' and 'about'"
super(IRCBot, self).msg(privmsg=((text,), {"user":user}))
else: else:
# A normal channel message # something to send to the main channel
text = "%s@%s: %s" % (kwargs["user"], kwargs["channel"], txt) if kwargs["type"] == "action":
# An action (irc pose)
text = "%s@%s %s" % (kwargs["user"], kwargs["channel"], txt)
if not self.ndb.ev_channel and self.db.ev_channel: else:
# cache channel lookup # msg - A normal channel message
self.ndb.ev_channel = self.db.ev_channel text = "%s@%s: %s" % (kwargs["user"], kwargs["channel"], txt)
if self.ndb.ev_channel:
self.ndb.ev_channel.msg(text, senders=self.id) if not self.ndb.ev_channel and self.db.ev_channel:
# cache channel lookup
self.ndb.ev_channel = self.db.ev_channel
if self.ndb.ev_channel:
self.ndb.ev_channel.msg(text, senders=self.id)
# RSS # RSS

View file

@ -46,6 +46,7 @@ IRC_GRAY = "15"
# {[rredbg {[ggreenbg {[yyellowbg {[bbluebg {[mmagentabg {[ccyanbg {[wlgreybg {[xblackbg # {[rredbg {[ggreenbg {[yyellowbg {[bbluebg {[mmagentabg {[ccyanbg {[wlgreybg {[xblackbg
IRC_COLOR_MAP = dict([ IRC_COLOR_MAP = dict([
# obs - {-type colors are deprecated but still used in many places.
(r'{n', IRC_RESET), # reset (r'{n', IRC_RESET), # reset
(r'{/', ""), # line break (r'{/', ""), # line break
(r'{-', " "), # tab (r'{-', " "), # tab
@ -78,7 +79,42 @@ IRC_COLOR_MAP = dict([
(r'{[m', IRC_COLOR + IRC_NORMAL + "," + IRC_DMAGENTA), (r'{[m', IRC_COLOR + IRC_NORMAL + "," + IRC_DMAGENTA),
(r'{[c', IRC_COLOR + IRC_NORMAL + "," + IRC_DCYAN), (r'{[c', IRC_COLOR + IRC_NORMAL + "," + IRC_DCYAN),
(r'{[w', IRC_COLOR + IRC_NORMAL + "," + IRC_GRAY), # light grey background (r'{[w', IRC_COLOR + IRC_NORMAL + "," + IRC_GRAY), # light grey background
(r'{[x', IRC_COLOR + IRC_NORMAL + "," + IRC_BLACK) # pure black background (r'{[x', IRC_COLOR + IRC_NORMAL + "," + IRC_BLACK), # pure black background
# |-type formatting is the thing to use.
(r'|n', IRC_RESET), # reset
(r'|/', ""), # line break
(r'|-', " "), # tab
(r'|_', " "), # space
(r'|*', ""), # invert
(r'|^', ""), # blinking text
(r'|r', IRC_COLOR + IRC_RED),
(r'|g', IRC_COLOR + IRC_GREEN),
(r'|y', IRC_COLOR + IRC_YELLOW),
(r'|b', IRC_COLOR + IRC_BLUE),
(r'|m', IRC_COLOR + IRC_MAGENTA),
(r'|c', IRC_COLOR + IRC_CYAN),
(r'|w', IRC_COLOR + IRC_WHITE), # pure white
(r'|x', IRC_COLOR + IRC_DGREY), # dark grey
(r'|R', IRC_COLOR + IRC_DRED),
(r'|G', IRC_COLOR + IRC_DGREEN),
(r'|Y', IRC_COLOR + IRC_DYELLOW),
(r'|B', IRC_COLOR + IRC_DBLUE),
(r'|M', IRC_COLOR + IRC_DMAGENTA),
(r'|C', IRC_COLOR + IRC_DCYAN),
(r'|W', IRC_COLOR + IRC_GRAY), # light grey
(r'|X', IRC_COLOR + IRC_BLACK), # pure black
(r'|[r', IRC_COLOR + IRC_NORMAL + "," + IRC_DRED),
(r'|[g', IRC_COLOR + IRC_NORMAL + "," + IRC_DGREEN),
(r'|[y', IRC_COLOR + IRC_NORMAL + "," + IRC_DYELLOW),
(r'|[b', IRC_COLOR + IRC_NORMAL + "," + IRC_DBLUE),
(r'|[m', IRC_COLOR + IRC_NORMAL + "," + IRC_DMAGENTA),
(r'|[c', IRC_COLOR + IRC_NORMAL + "," + IRC_DCYAN),
(r'|[w', IRC_COLOR + IRC_NORMAL + "," + IRC_GRAY), # light grey background
(r'|[x', IRC_COLOR + IRC_NORMAL + "," + IRC_BLACK) # pure black background
]) ])
RE_IRC_COLOR = re.compile(r"|".join([re.escape(key) for key in viewkeys(IRC_COLOR_MAP)]), re.DOTALL) RE_IRC_COLOR = re.compile(r"|".join([re.escape(key) for key in viewkeys(IRC_COLOR_MAP)]), re.DOTALL)
RE_MXP = re.compile(r'\{lc(.*?)\{lt(.*?)\{le', re.DOTALL) RE_MXP = re.compile(r'\{lc(.*?)\{lt(.*?)\{le', re.DOTALL)
@ -176,7 +212,12 @@ class IRCBot(irc.IRCClient, Session):
msg (str): The message arriving from channel. msg (str): The message arriving from channel.
""" """
if not msg.startswith('***'): if channel == self.nickname:
# private message
user = user.split('!', 1)[0]
self.data_in(text=msg, type="privmsg", user=user, channel=channel)
elif not msg.startswith('***'):
# channel message
user = user.split('!', 1)[0] user = user.split('!', 1)[0]
user = ansi.raw(user) user = ansi.raw(user)
self.data_in(text=msg, type="msg", user=user, channel=channel) self.data_in(text=msg, type="msg", user=user, channel=channel)
@ -224,7 +265,7 @@ class IRCBot(irc.IRCClient, Session):
Called with the return timing from a PING. Called with the return timing from a PING.
Args: Args:
user (str): Njame of user user (str): Name of user
time (float): Ping time in secs. time (float): Ping time in secs.
""" """
@ -242,21 +283,40 @@ class IRCBot(irc.IRCClient, Session):
""" """
self.sessionhandler.data_in(self, bot_data_in=[text, kwargs]) self.sessionhandler.data_in(self, bot_data_in=[text, kwargs])
def send_text(self, *args, **kwargs): def send_channel(self, *args, **kwargs):
""" """
Send channel text to IRC Send channel text to IRC channel (visible to all). Note that
we don't handle the "text" send (it's rerouted to send_default
which does nothing) - this is because the IRC bot is a normal
session and would otherwise report anything that happens to it
to the IRC channel (such as it seeing server reload messages).
Args: Args:
text (str): Outgoing text text (str): Outgoing text
"""
text = args[0] if args else ""
if text:
text = parse_irc_colors(text)
self.say(self.channel, text)
def send_privmsg(self, *args, **kwargs):
"""
Send message only to specific user.
Args:
text (str): Outgoing text.
Kwargs: Kwargs:
bot_data_out (bool): If True, echo to channel. user (str): the nick to send
privately to.
""" """
text = args[0] if args else "" text = args[0] if args else ""
if text and kwargs['options'].get("bot_data_out", False): user = kwargs.get("user", None)
if text and user:
text = parse_irc_colors(text) text = parse_irc_colors(text)
self.say(self.channel, text) self.msg(user, text)
def send_request_nicklist(self, *args, **kwargs): def send_request_nicklist(self, *args, **kwargs):
""" """