Made irc bot connect, but scripthandler lookup is causing traceback when searching for a player)

This commit is contained in:
Griatch 2014-02-24 00:37:32 +01:00
parent 8b52591c2f
commit 6c45d76b56
11 changed files with 70 additions and 37 deletions

View file

@ -826,7 +826,7 @@ class CmdIRC2Chan(MuxCommand):
if('disconnect' in self.switches or 'remove' in self.switches or
'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:
matches[0].delete()
self.msg("IRC connection destroyed.")
@ -835,7 +835,15 @@ class CmdIRC2Chan(MuxCommand):
return
# 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,
irc_network=irc_network, irc_port=irc_port)
self.msg("Connection created. Starting IRC bot.")

View file

@ -172,12 +172,8 @@ class Channel(TypeClass):
# note our addition of the from_channel keyword here. This could be checked
# by a custom player.msg() to treat channel-receives differently.
player.msg(msg.message, from_obj=msg.senders, from_channel=self.id)
except AttributeError:
try:
player.to_external(msg.message,
senders=msg.senders, from_channel=self)
except Exception:
logger.log_trace("Cannot send msg to connection '%s'" % player)
except AttributeError, e:
logger.log_trace("%s\nCannot send msg to connection '%s'" % (e, player))
def msg(self, msgobj, header=None, senders=None, sender_strings=None,
persistent=False, online=False, emit=False, external=False):

View file

@ -201,6 +201,8 @@ class LockHandler(object):
elist = [] # errors
wlist = [] # warnings
for raw_lockstring in storage_lockstring.split(';'):
if not raw_lockstring:
continue
lock_funcs = []
try:
access_type, rhs = (part.strip() for part in raw_lockstring.split(':', 1))

View file

@ -31,7 +31,7 @@ class BotStarter(Script):
def at_start(self):
"Kick bot into gear"
if not self.db.started:
self.obj.start()
self.player.start()
self.db.started = False
def at_server_reload(self):
@ -56,7 +56,7 @@ class CmdBotListen(Command):
key = CMD_NOMATCH
def func(self):
text = self.cmdname + self.args
text = self.cmdstring + self.args
self.obj.execute_cmd(text, sessid=self.sessid)
@ -84,7 +84,7 @@ class Bot(Player):
# 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()"
lockstring = "examine:perm(Wizards);edit:perm(Wizards);delete:perm(Wizards);boot:perm(Wizards);msg:false()"
self.locks.add(lockstring)
# set the basics of being a bot
self.cmdset.add_default(BotCmdSet)
@ -134,12 +134,16 @@ class IRCBot(Bot):
# 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 irc_botname:
self.db.irc_botname = irc_botname
elif not self.db.irc_botname:
self.db.irc_botname = 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 = channel[0]
channel.connect(self)
self.db.ev_channel = channel
if irc_channel:
@ -154,11 +158,12 @@ class IRCBot(Bot):
# instruct the server and portal to create a new session with
# the stored configuration
configdict = {"botname": self.db.irc_botname,
configdict = {"uid":self.dbid,
"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)
_SESSIONS.start_bot_session("src.server.portal.irc.IRCBotFactory", configdict)
def msg(self, text=None, **kwargs):
"""

View file

@ -415,7 +415,7 @@ class PlayerDB(TypedObject, AbstractUser):
# deleting command)
self.unpuppet_object(session.sessid)
session.sessionhandler.disconnect(session, reason=_("Player being deleted."))
self.scripts.stop()
super(PlayerDB, self).delete(*args, **kwargs)
def execute_cmd(self, raw_string, sessid=None):

View file

@ -44,13 +44,22 @@ class ScriptManager(TypedObjectManager):
if not obj:
return []
obj = obj.dbobj
player = obj.__class__.__name__ == "PlayerDB"
print "get_all_scripts_on_obj:", obj, player
if key:
dbref = self.dbref(key)
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:
return script
elif player:
return self.filter(db_player=obj, 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)
@returns_typeclass_list

View file

@ -58,7 +58,13 @@ class ScriptHandler(object):
definition)
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)
if not script:
logger.log_errmsg("Script %s could not be created and/or started." % scriptclass)
@ -75,12 +81,13 @@ class ScriptHandler(object):
num += script.start()
return num
def delete(self, scriptid):
def delete(self, scriptid=None):
"""
Forcibly delete a script from this object.
scriptid can be a script key or the path to a script (in the
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)
@ -91,7 +98,7 @@ class ScriptHandler(object):
num += script.stop()
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.
"""

View file

@ -472,8 +472,10 @@ class AMPProtocol(amp.AMP):
portal_sessionhandler.server_session_sync(data)
# set a flag in case we are about to shut down soon
self.factory.server_restart_mode = True
elif operation == SCONN: # server_force_connection (for irc/imc2 etc)
portal_sessionhandler.server_connect(**data)
else:
raise Exception("operation %(op)s not recognized." % {'op': operation})
return {}

View file

@ -30,11 +30,16 @@ class IRCBot(irc.IRCClient, Session):
def signedOn(self):
"""
This is called when we successfully connect to
the network. We make sure to store ourself
on the factory.
the network. We make sure to now register with
the game as a full session.
"""
self.join(self.channel)
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):
"A message was sent to channel"
@ -55,11 +60,6 @@ class IRCBot(irc.IRCClient, Session):
"Data from server-> IRC"
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):
"""
@ -71,14 +71,14 @@ class IRCBotFactory(protocol.ReconnectingClientFactory):
factor = 1.5
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"
self.nickname = botname
self.logger = logger
self.channel = channel
self.network = network
self.port = port
self.bots = None
self.uid = int(uid)
self.nickname = str(botname)
self.channel = str(channel)
self.network = str(network)
self.port = int(port)
self.bot = None
def buildProtocol(self, addr):
"Build the protocol and assign it some properties"
@ -94,6 +94,10 @@ class IRCBotFactory(protocol.ReconnectingClientFactory):
"Tracks reconnections for debugging"
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)
#

View file

@ -69,7 +69,7 @@ class PortalSessionHandler(SessionHandler):
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
protocol instance. Server wants this instance to get
@ -79,7 +79,6 @@ class PortalSessionHandler(SessionHandler):
protocol_path - full python path to the class factory
for the protocol used, eg
'src.server.portal.irc.IRCClientFactory'
uid - database uid to the connected player-bot
config - dictionary of configuration options, fed as **kwarg
to protocol class' __init__ method.
@ -91,6 +90,8 @@ class PortalSessionHandler(SessionHandler):
from src.utils.utils import variable_from_module as _MOD_IMPORT
path, clsname = protocol_path.rsplit(".", 1)
cls = _MOD_IMPORT(path, clsname)
if not cls:
raise RuntimeError("ServerConnect: protocol factory '%s' not found." % protocol_path)
protocol = cls(**config)
protocol.sessionhandler = self
protocol.start()

View file

@ -259,7 +259,7 @@ class ServerSessionHandler(SessionHandler):
# 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
a new bot session using the protocol specified by protocol_path,
@ -271,7 +271,6 @@ class ServerSessionHandler(SessionHandler):
Server.
"""
data = {"protocol_path":protocol_path,
"uid":uid,
"config":configdict}
self.server.amp_protocol.call_remote_PortalAdmin(0,
operation=SCONN,