Made irc bot connect, but scripthandler lookup is causing traceback when searching for a player)
This commit is contained in:
parent
8b52591c2f
commit
6c45d76b56
11 changed files with 70 additions and 37 deletions
|
|
@ -826,7 +826,7 @@ class CmdIRC2Chan(MuxCommand):
|
||||||
|
|
||||||
if('disconnect' in self.switches or 'remove' in self.switches or
|
if('disconnect' in self.switches or 'remove' in self.switches or
|
||||||
'delete' in self.switches):
|
'delete' in self.switches):
|
||||||
matches = PlayerDB.filter(db_isbot=True, db_key=botname)
|
matches = PlayerDB.objects.filter(db_is_bot=True, db_key=botname)
|
||||||
if matches:
|
if matches:
|
||||||
matches[0].delete()
|
matches[0].delete()
|
||||||
self.msg("IRC connection destroyed.")
|
self.msg("IRC connection destroyed.")
|
||||||
|
|
@ -835,7 +835,15 @@ class CmdIRC2Chan(MuxCommand):
|
||||||
return
|
return
|
||||||
|
|
||||||
# create a new bot
|
# create a new bot
|
||||||
bot = create.create_player(botname, None, None, typeclass=bots.IRCBot)
|
bot = PlayerDB.objects.filter(username__iexact=botname)
|
||||||
|
if bot:
|
||||||
|
# re-use an existing bot
|
||||||
|
bot = bot[0].typeclass
|
||||||
|
if not bot.is_bot:
|
||||||
|
self.msg("Player '%s', which is not a bot, already exists." % botname)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
bot = create.create_player(botname, None, None, typeclass=bots.IRCBot)
|
||||||
bot.start(ev_channel=channel, irc_botname=irc_botname, irc_channel=irc_channel,
|
bot.start(ev_channel=channel, irc_botname=irc_botname, irc_channel=irc_channel,
|
||||||
irc_network=irc_network, irc_port=irc_port)
|
irc_network=irc_network, irc_port=irc_port)
|
||||||
self.msg("Connection created. Starting IRC bot.")
|
self.msg("Connection created. Starting IRC bot.")
|
||||||
|
|
|
||||||
|
|
@ -172,12 +172,8 @@ class Channel(TypeClass):
|
||||||
# note our addition of the from_channel keyword here. This could be checked
|
# note our addition of the from_channel keyword here. This could be checked
|
||||||
# by a custom player.msg() to treat channel-receives differently.
|
# by a custom player.msg() to treat channel-receives differently.
|
||||||
player.msg(msg.message, from_obj=msg.senders, from_channel=self.id)
|
player.msg(msg.message, from_obj=msg.senders, from_channel=self.id)
|
||||||
except AttributeError:
|
except AttributeError, e:
|
||||||
try:
|
logger.log_trace("%s\nCannot send msg to connection '%s'" % (e, player))
|
||||||
player.to_external(msg.message,
|
|
||||||
senders=msg.senders, from_channel=self)
|
|
||||||
except Exception:
|
|
||||||
logger.log_trace("Cannot send msg to connection '%s'" % player)
|
|
||||||
|
|
||||||
def msg(self, msgobj, header=None, senders=None, sender_strings=None,
|
def msg(self, msgobj, header=None, senders=None, sender_strings=None,
|
||||||
persistent=False, online=False, emit=False, external=False):
|
persistent=False, online=False, emit=False, external=False):
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,8 @@ class LockHandler(object):
|
||||||
elist = [] # errors
|
elist = [] # errors
|
||||||
wlist = [] # warnings
|
wlist = [] # warnings
|
||||||
for raw_lockstring in storage_lockstring.split(';'):
|
for raw_lockstring in storage_lockstring.split(';'):
|
||||||
|
if not raw_lockstring:
|
||||||
|
continue
|
||||||
lock_funcs = []
|
lock_funcs = []
|
||||||
try:
|
try:
|
||||||
access_type, rhs = (part.strip() for part in raw_lockstring.split(':', 1))
|
access_type, rhs = (part.strip() for part in raw_lockstring.split(':', 1))
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ class BotStarter(Script):
|
||||||
def at_start(self):
|
def at_start(self):
|
||||||
"Kick bot into gear"
|
"Kick bot into gear"
|
||||||
if not self.db.started:
|
if not self.db.started:
|
||||||
self.obj.start()
|
self.player.start()
|
||||||
self.db.started = False
|
self.db.started = False
|
||||||
|
|
||||||
def at_server_reload(self):
|
def at_server_reload(self):
|
||||||
|
|
@ -56,7 +56,7 @@ class CmdBotListen(Command):
|
||||||
key = CMD_NOMATCH
|
key = CMD_NOMATCH
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
text = self.cmdname + self.args
|
text = self.cmdstring + self.args
|
||||||
self.obj.execute_cmd(text, sessid=self.sessid)
|
self.obj.execute_cmd(text, sessid=self.sessid)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -84,7 +84,7 @@ class Bot(Player):
|
||||||
# the text encoding to use.
|
# the text encoding to use.
|
||||||
self.db.encoding = "utf-8"
|
self.db.encoding = "utf-8"
|
||||||
# A basic security setup
|
# A basic security setup
|
||||||
lockstring = "examine:perm(Wizards);edit:perm(Wizards);delete:perm(Wizards);boot:perm(Wizards);msg:all()"
|
lockstring = "examine:perm(Wizards);edit:perm(Wizards);delete:perm(Wizards);boot:perm(Wizards);msg:false()"
|
||||||
self.locks.add(lockstring)
|
self.locks.add(lockstring)
|
||||||
# set the basics of being a bot
|
# set the basics of being a bot
|
||||||
self.cmdset.add_default(BotCmdSet)
|
self.cmdset.add_default(BotCmdSet)
|
||||||
|
|
@ -134,12 +134,16 @@ class IRCBot(Bot):
|
||||||
# if keywords are given, store (the BotStarter script
|
# if keywords are given, store (the BotStarter script
|
||||||
# will not give any keywords, so this should normally only
|
# will not give any keywords, so this should normally only
|
||||||
# happen at initialization)
|
# happen at initialization)
|
||||||
self.db.irc_botname = irc_botname if irc_botname else self.key
|
if irc_botname:
|
||||||
|
self.db.irc_botname = irc_botname
|
||||||
|
elif not self.db.irc_botname:
|
||||||
|
self.db.irc_botname = self.key
|
||||||
if ev_channel:
|
if ev_channel:
|
||||||
# connect to Evennia channel
|
# connect to Evennia channel
|
||||||
channel = search.channel_search(ev_channel)
|
channel = search.channel_search(ev_channel)
|
||||||
if not channel:
|
if not channel:
|
||||||
raise RuntimeError("Evennia Channel '%s' not found." % ev_channel)
|
raise RuntimeError("Evennia Channel '%s' not found." % ev_channel)
|
||||||
|
channel = channel[0]
|
||||||
channel.connect(self)
|
channel.connect(self)
|
||||||
self.db.ev_channel = channel
|
self.db.ev_channel = channel
|
||||||
if irc_channel:
|
if irc_channel:
|
||||||
|
|
@ -154,11 +158,12 @@ class IRCBot(Bot):
|
||||||
|
|
||||||
# instruct the server and portal to create a new session with
|
# instruct the server and portal to create a new session with
|
||||||
# the stored configuration
|
# the stored configuration
|
||||||
configdict = {"botname": self.db.irc_botname,
|
configdict = {"uid":self.dbid,
|
||||||
|
"botname": self.db.irc_botname,
|
||||||
"channel": self.db.irc_channel ,
|
"channel": self.db.irc_channel ,
|
||||||
"network": self.db.irc_network,
|
"network": self.db.irc_network,
|
||||||
"port": self.db.irc_port}
|
"port": self.db.irc_port}
|
||||||
_SESSIONS.start_bot_session("src.server.portal.irc.IRCClient", self.id, configdict)
|
_SESSIONS.start_bot_session("src.server.portal.irc.IRCBotFactory", configdict)
|
||||||
|
|
||||||
def msg(self, text=None, **kwargs):
|
def msg(self, text=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -415,7 +415,7 @@ class PlayerDB(TypedObject, AbstractUser):
|
||||||
# deleting command)
|
# deleting command)
|
||||||
self.unpuppet_object(session.sessid)
|
self.unpuppet_object(session.sessid)
|
||||||
session.sessionhandler.disconnect(session, reason=_("Player being deleted."))
|
session.sessionhandler.disconnect(session, reason=_("Player being deleted."))
|
||||||
|
self.scripts.stop()
|
||||||
super(PlayerDB, self).delete(*args, **kwargs)
|
super(PlayerDB, self).delete(*args, **kwargs)
|
||||||
|
|
||||||
def execute_cmd(self, raw_string, sessid=None):
|
def execute_cmd(self, raw_string, sessid=None):
|
||||||
|
|
|
||||||
|
|
@ -44,13 +44,22 @@ class ScriptManager(TypedObjectManager):
|
||||||
if not obj:
|
if not obj:
|
||||||
return []
|
return []
|
||||||
obj = obj.dbobj
|
obj = obj.dbobj
|
||||||
|
player = obj.__class__.__name__ == "PlayerDB"
|
||||||
|
print "get_all_scripts_on_obj:", obj, player
|
||||||
if key:
|
if key:
|
||||||
dbref = self.dbref(key)
|
dbref = self.dbref(key)
|
||||||
if dbref or dbref == 0:
|
if dbref or dbref == 0:
|
||||||
script = self.filter(db_obj=obj, id=dbref)
|
if player:
|
||||||
|
script = self.filter(db_player=obj, id=dbref)
|
||||||
|
else:
|
||||||
|
script = self.filter(db_obj=obj, id=dbref)
|
||||||
if script:
|
if script:
|
||||||
return script
|
return script
|
||||||
|
elif player:
|
||||||
|
return self.filter(db_player=obj, db_key=key)
|
||||||
return self.filter(db_obj=obj.dbobj, db_key=key)
|
return self.filter(db_obj=obj.dbobj, db_key=key)
|
||||||
|
if player:
|
||||||
|
self.filter(db_player=obj)
|
||||||
return self.filter(db_obj=obj)
|
return self.filter(db_obj=obj)
|
||||||
|
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,13 @@ class ScriptHandler(object):
|
||||||
definition)
|
definition)
|
||||||
autostart - start the script upon adding it
|
autostart - start the script upon adding it
|
||||||
"""
|
"""
|
||||||
script = create.create_script(scriptclass, key=key, obj=self.obj,
|
if self.obj.dbobj.__class__.__name__ == "PlayerDB":
|
||||||
|
# we add to a Player, not an Object
|
||||||
|
script = create.create_script(scriptclass, key=key, player=self.obj,
|
||||||
|
autostart=autostart)
|
||||||
|
else:
|
||||||
|
# the normal - adding to an Object
|
||||||
|
script = create.create_script(scriptclass, key=key, obj=self.obj,
|
||||||
autostart=autostart)
|
autostart=autostart)
|
||||||
if not script:
|
if not script:
|
||||||
logger.log_errmsg("Script %s could not be created and/or started." % scriptclass)
|
logger.log_errmsg("Script %s could not be created and/or started." % scriptclass)
|
||||||
|
|
@ -75,12 +81,13 @@ class ScriptHandler(object):
|
||||||
num += script.start()
|
num += script.start()
|
||||||
return num
|
return num
|
||||||
|
|
||||||
def delete(self, scriptid):
|
def delete(self, scriptid=None):
|
||||||
"""
|
"""
|
||||||
Forcibly delete a script from this object.
|
Forcibly delete a script from this object.
|
||||||
|
|
||||||
scriptid can be a script key or the path to a script (in the
|
scriptid can be a script key or the path to a script (in the
|
||||||
latter case all scripts with this path will be deleted!)
|
latter case all scripts with this path will be deleted!)
|
||||||
|
If no scriptid is set, delete all scripts on the object.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
delscripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=scriptid)
|
delscripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=scriptid)
|
||||||
|
|
@ -91,7 +98,7 @@ class ScriptHandler(object):
|
||||||
num += script.stop()
|
num += script.stop()
|
||||||
return num
|
return num
|
||||||
|
|
||||||
def stop(self, scriptid):
|
def stop(self, scriptid=None):
|
||||||
"""
|
"""
|
||||||
Alias for delete. scriptid can be a script key or a script path string.
|
Alias for delete. scriptid can be a script key or a script path string.
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -472,8 +472,10 @@ class AMPProtocol(amp.AMP):
|
||||||
portal_sessionhandler.server_session_sync(data)
|
portal_sessionhandler.server_session_sync(data)
|
||||||
# set a flag in case we are about to shut down soon
|
# set a flag in case we are about to shut down soon
|
||||||
self.factory.server_restart_mode = True
|
self.factory.server_restart_mode = True
|
||||||
|
|
||||||
elif operation == SCONN: # server_force_connection (for irc/imc2 etc)
|
elif operation == SCONN: # server_force_connection (for irc/imc2 etc)
|
||||||
portal_sessionhandler.server_connect(**data)
|
portal_sessionhandler.server_connect(**data)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise Exception("operation %(op)s not recognized." % {'op': operation})
|
raise Exception("operation %(op)s not recognized." % {'op': operation})
|
||||||
return {}
|
return {}
|
||||||
|
|
|
||||||
|
|
@ -30,11 +30,16 @@ class IRCBot(irc.IRCClient, Session):
|
||||||
def signedOn(self):
|
def signedOn(self):
|
||||||
"""
|
"""
|
||||||
This is called when we successfully connect to
|
This is called when we successfully connect to
|
||||||
the network. We make sure to store ourself
|
the network. We make sure to now register with
|
||||||
on the factory.
|
the game as a full session.
|
||||||
"""
|
"""
|
||||||
self.join(self.channel)
|
self.join(self.channel)
|
||||||
self.factory.bot = self
|
self.factory.bot = self
|
||||||
|
self.init_session("ircbot", self.network, self.factory.sessionhandler)
|
||||||
|
# we link back to our bot and log in
|
||||||
|
self.uid = self.factory.uid
|
||||||
|
self.logged_in = True
|
||||||
|
self.factory.sessionhandler.connect(self)
|
||||||
|
|
||||||
def privmsg(self, user, channel, msg):
|
def privmsg(self, user, channel, msg):
|
||||||
"A message was sent to channel"
|
"A message was sent to channel"
|
||||||
|
|
@ -55,11 +60,6 @@ class IRCBot(irc.IRCClient, Session):
|
||||||
"Data from server-> IRC"
|
"Data from server-> IRC"
|
||||||
self.say(self.channel, text)
|
self.say(self.channel, text)
|
||||||
|
|
||||||
def start(self):
|
|
||||||
"Connect session to sessionhandler"
|
|
||||||
service = internet.TCPClient(self.network, int(self.port), self)
|
|
||||||
self.sessionhandler.portal.services.addService(service)
|
|
||||||
self.sessionhandler.connect(self)
|
|
||||||
|
|
||||||
class IRCBotFactory(protocol.ReconnectingClientFactory):
|
class IRCBotFactory(protocol.ReconnectingClientFactory):
|
||||||
"""
|
"""
|
||||||
|
|
@ -71,14 +71,14 @@ class IRCBotFactory(protocol.ReconnectingClientFactory):
|
||||||
factor = 1.5
|
factor = 1.5
|
||||||
maxDelay = 60
|
maxDelay = 60
|
||||||
|
|
||||||
def __init__(self, botname=None, channel=None, network=None, port=None):
|
def __init__(self, uid=None, botname=None, channel=None, network=None, port=None):
|
||||||
"Storing some important protocol properties"
|
"Storing some important protocol properties"
|
||||||
self.nickname = botname
|
self.uid = int(uid)
|
||||||
self.logger = logger
|
self.nickname = str(botname)
|
||||||
self.channel = channel
|
self.channel = str(channel)
|
||||||
self.network = network
|
self.network = str(network)
|
||||||
self.port = port
|
self.port = int(port)
|
||||||
self.bots = None
|
self.bot = None
|
||||||
|
|
||||||
def buildProtocol(self, addr):
|
def buildProtocol(self, addr):
|
||||||
"Build the protocol and assign it some properties"
|
"Build the protocol and assign it some properties"
|
||||||
|
|
@ -94,6 +94,10 @@ class IRCBotFactory(protocol.ReconnectingClientFactory):
|
||||||
"Tracks reconnections for debugging"
|
"Tracks reconnections for debugging"
|
||||||
logger.log_infomsg("(re)connecting to %s" % self.channel)
|
logger.log_infomsg("(re)connecting to %s" % self.channel)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
"Connect session to sessionhandler"
|
||||||
|
service = internet.TCPClient(self.network, self.port, self)
|
||||||
|
self.sessionhandler.portal.services.addService(service)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ class PortalSessionHandler(SessionHandler):
|
||||||
operation=PDISCONN)
|
operation=PDISCONN)
|
||||||
|
|
||||||
|
|
||||||
def server_connect(self, protocol_path="", uid=None, config=dict()):
|
def server_connect(self, protocol_path="", config=dict()):
|
||||||
"""
|
"""
|
||||||
Called by server to force the initialization of a new
|
Called by server to force the initialization of a new
|
||||||
protocol instance. Server wants this instance to get
|
protocol instance. Server wants this instance to get
|
||||||
|
|
@ -79,7 +79,6 @@ class PortalSessionHandler(SessionHandler):
|
||||||
protocol_path - full python path to the class factory
|
protocol_path - full python path to the class factory
|
||||||
for the protocol used, eg
|
for the protocol used, eg
|
||||||
'src.server.portal.irc.IRCClientFactory'
|
'src.server.portal.irc.IRCClientFactory'
|
||||||
uid - database uid to the connected player-bot
|
|
||||||
config - dictionary of configuration options, fed as **kwarg
|
config - dictionary of configuration options, fed as **kwarg
|
||||||
to protocol class' __init__ method.
|
to protocol class' __init__ method.
|
||||||
|
|
||||||
|
|
@ -91,6 +90,8 @@ class PortalSessionHandler(SessionHandler):
|
||||||
from src.utils.utils import variable_from_module as _MOD_IMPORT
|
from src.utils.utils import variable_from_module as _MOD_IMPORT
|
||||||
path, clsname = protocol_path.rsplit(".", 1)
|
path, clsname = protocol_path.rsplit(".", 1)
|
||||||
cls = _MOD_IMPORT(path, clsname)
|
cls = _MOD_IMPORT(path, clsname)
|
||||||
|
if not cls:
|
||||||
|
raise RuntimeError("ServerConnect: protocol factory '%s' not found." % protocol_path)
|
||||||
protocol = cls(**config)
|
protocol = cls(**config)
|
||||||
protocol.sessionhandler = self
|
protocol.sessionhandler = self
|
||||||
protocol.start()
|
protocol.start()
|
||||||
|
|
|
||||||
|
|
@ -259,7 +259,7 @@ class ServerSessionHandler(SessionHandler):
|
||||||
|
|
||||||
# server-side access methods
|
# server-side access methods
|
||||||
|
|
||||||
def start_bot_session(self, protocol_path, uid, configdict):
|
def start_bot_session(self, protocol_path, configdict):
|
||||||
"""
|
"""
|
||||||
This method allows the server-side to force the Portal to create
|
This method allows the server-side to force the Portal to create
|
||||||
a new bot session using the protocol specified by protocol_path,
|
a new bot session using the protocol specified by protocol_path,
|
||||||
|
|
@ -271,7 +271,6 @@ class ServerSessionHandler(SessionHandler):
|
||||||
Server.
|
Server.
|
||||||
"""
|
"""
|
||||||
data = {"protocol_path":protocol_path,
|
data = {"protocol_path":protocol_path,
|
||||||
"uid":uid,
|
|
||||||
"config":configdict}
|
"config":configdict}
|
||||||
self.server.amp_protocol.call_remote_PortalAdmin(0,
|
self.server.amp_protocol.call_remote_PortalAdmin(0,
|
||||||
operation=SCONN,
|
operation=SCONN,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue