Added new IRC protocol implementation. Not tested yet.

This commit is contained in:
Griatch 2014-02-23 21:07:16 +01:00
parent 2ae5d56928
commit 2108506a8a
7 changed files with 362 additions and 217 deletions

View file

@ -9,9 +9,13 @@ from src.scripts.script import Script
from src.commands.command import Command
from src.commands.cmdset import CmdSet
from src.commands.cmdhandler import CMD_NOMATCH
from src.utils import search
_SESSIONS = None
# Bot helper utilities
class BotStarter(Script):
"""
This non-repeating script has the
@ -63,6 +67,8 @@ class BotCmdSet(CmdSet):
self.add(CmdBotListen())
# Bot base class
class Bot(Player):
"""
A Bot will start itself when the server
@ -70,20 +76,25 @@ class Bot(Player):
on a reload - that will be handled by the
normal Portal session resync)
"""
def at_player_creation(self):
def basetype_setup(self):
"""
Called when the bot is first created. It sets
up the cmdset and the botstarter script
This sets up the basic properties for the bot.
"""
# the text encoding to use.
self.db.encoding = "utf-8"
# A basic security setup
lockstring = "examine:perm(Wizards);edit:perm(Wizards);delete:perm(Wizards);boot:perm(Wizards);msg:all()"
self.locks.add(lockstring)
# set the basics of being a bot
self.cmdset.add_default(BotCmdSet)
script_key = "botstarter_%s" % self.key
self.scripts.add(BotStarter, key=script_key)
self.is_bot = True
def start(self):
def start(self, **kwargs):
"""
This starts the bot, usually by connecting
to a protocol.
This starts the bot, whatever that may mean.
"""
pass
@ -100,23 +111,54 @@ class Bot(Player):
pass
# Bot implementations
class IRCBot(Bot):
"""
Bot for handling IRC connections
Bot for handling IRC connections.
"""
def start(self):
"Start by telling the portal to start a new session"
global _SESSIONS
def start(self, ev_channel=None, irc_botname=None, irc_channel=None, irc_network=None, irc_port=None):
"""
Start by telling the portal to start a new session.
ev_channel - key of the Evennia channel to connect to
irc_botname - name of bot to connect to irc channel. If not set, use self.key
irc_channel - name of channel on the form #channelname
irc_network - url of network, like irc.freenode.net
irc_port - port number of irc network, like 6667
"""
global _SESSIONS, _CHANNELDB
if not _SESSIONS:
from src.server.sessionhandler import SESSIONS as _SESSIONS
# instruct the server and portal to create a new session
_SESSIONS.start_bot_session("src.server.portal.irc.IRCClient", self.id)
def connect_to_channel(self, botkey, channelname):
"""
Connect the bot to an Evennia channel
"""
pass
# if keywords are given, store (the BotStarter script
# will not give any keywords, so this should normally only
# happen at initialization)
self.db.irc_botname = irc_botname if irc_botname else self.key
if ev_channel:
# connect to Evennia channel
channel = search.channel_search(ev_channel)
if not channel:
raise RuntimeError("Evennia Channel '%s' not found." % ev_channel)
channel.connect(self)
self.db.ev_channel = channel
if irc_channel:
self.db.irc_channel = irc_channel
if irc_network:
self.db.irc_network = irc_network
if irc_port:
self.db.irc_port = irc_port
# cache channel
self.ndb.ev_channel = self.db.ev_channel
# instruct the server and portal to create a new session with
# the stored configuration
configdict = {"botname": self.db.irc_botname,
"channel": self.db.irc_channel ,
"network": self.db.irc_network,
"port": self.db.irc_port}
_SESSIONS.start_bot_session("src.server.portal.irc.IRCClient", self.id, configdict)
def msg(self, text=None, **kwargs):
"""
@ -129,6 +171,10 @@ class IRCBot(Bot):
text = "[%s] %s" % (ckey, text)
self.dbobj.msg(text=text)
def execute_cmd(self):
pass
def execute_cmd(self, text=None, sessid=None):
"""
Take incoming data and send it to connected channel. This is triggered
by the CmdListen command in the BotCmdSet.
"""
if self.ndb.channel:
self.ndb.channel.msg(text)

View file

@ -78,6 +78,7 @@ class PlayerDB(TypedObject, AbstractUser):
name - alias for user.username
sessions - sessions connected to this player
is_superuser - bool if this player is a superuser
is_bot - bool if this player is a bot and not a real player
"""
@ -419,12 +420,11 @@ class PlayerDB(TypedObject, AbstractUser):
"""
Do something as this player. This method is never called normally,
but only when the player object itself is supposed to execute the
command. It does not take nicks on eventual puppets into account.
command. It takes player nicks into account, but not nicks of
eventual puppets.
raw_string - raw command input coming from the command line.
"""
# nick replacement - we require full-word matching.
raw_string = utils.to_unicode(raw_string)
raw_string = self.nicks.nickreplace(raw_string,
categories=("inputline", "channel"), include_player=False)

View file

@ -136,8 +136,9 @@ class Player(TypeClass):
def execute_cmd(self, raw_string, sessid=None):
"""
Do something as this object. This command transparently
lets its typeclass execute the command. Evennia also calls
this method whenever the player sends a command on the command line.
lets its typeclass execute the command. This method
is -not- called by Evennia normally, it is here to be
called explicitly in code.
Argument:
raw_string (string) - raw command input