def __init__(self, config): self.jabbersecurity = config.get('jabber-security') volent.VolEntity.__init__(self, config.get('jid'), config.get('password'), config.get('jid-resource'), config.get('host'), secure=self.jabbersecurity) # Set the default shutdown conditions self.shutdowngraceful = True self.shutdownrestart = True self.shutdownrestartdelay = True self.canrestart = config.has_key('restart-script') self.restartfunc = config.get('restart-func-') # Locate the game class. ls = config.get('game').split('.') if (len(ls) < 2): raise ValueError('gameclass must be of the form module.gameclass') classname = ls[-1] modpath = '.'.join(ls[ : -1 ]) mod = __import__(modpath, globals(), locals(), [classname]) gameclass = getattr(mod, classname) self.gameclass = gameclass if (gameclass == game.Game or (type(gameclass) != types.ClassType) or (not issubclass(gameclass, game.Game))): raise ValueError('gameclass must be a subclass of volity.game.Game') if (not gameclass.gamename): raise TypeError('gameclass does not define class.gamename') if (not gameclass.ruleseturi): raise TypeError('gameclass does not define class.ruleseturi') # Locate the bot classes (if there are any). self.botclasses = [] botls = config.getall('bot') for botclassname in botls: ls = botclassname.split('.') if (len(ls) < 2): raise ValueError('botclass must be of the form module.botclass') classname = ls[-1] modpath = '.'.join(ls[ : -1 ]) mod = __import__(modpath, globals(), locals(), [classname]) botclass = getattr(mod, classname) self.botclasses.append(botclass) if (botclass == bot.Bot or (type(botclass) != types.ClassType) or (not issubclass(botclass, bot.Bot))): raise ValueError('botclass must be a subclass of volity.bot.Bot') if (botclass.gameclass == None or (type(botclass.gameclass) != types.ClassType) or (not issubclass(self.gameclass, botclass.gameclass))): raise ValueError('botclass does not play '+config.get('game')) if (not botclass.boturi): raise TypeError('botclass does not define class.boturi') if (botclass.boturi in [bc.boturi for bc in self.botclasses[:-1]]): raise TypeError('class.boturi used more than once') self.botfactories = [] for jidstr in config.getall('bot-factory'): self.botfactories.append(interface.JID(jidstr)) bookjidstr = config.get('bookkeeper', '[email protected]/volity') self.bookkeeperjid = interface.JID(bookjidstr) if (not self.bookkeeperjid.getresource()): self.bookkeeperjid.setresource('volity') # Set the administrative JID (if present) self.adminjids = [] if (config.get('admin')): val = config.get('admin') ls = [ interface.JID(subval.strip()) for subval in val.split(',') ] self.adminjids = ls # Various Jabber handlers. self.addhandler('end', self.endwork) self.conn.adddispatcher(self.handlepresence, name='presence') self.conn.adddispatcher(self.handlemessage, name='message') # Set up internal state. val = config.get('entity-name') if (not val): val = gameclass.gamename self.gamename = val self.log.warning('Game parlor running: %s', self.gamename) self.referees = {} self.muchost = interface.JID(config.get('muchost', 'conference.volity.net')) self.online = True self.startuptime = time.time() self.activitytime = None self.refereesstarted = 0 self.visibility = config.getbool('visible', True) self.actors = {} # Set up the disco service disco = self.conn.getservice('discoservice') info = disco.addinfo() info.addidentity('volity', 'parlor', self.gamename) info.addfeature(interface.NS_CAPS) info2 = disco.addinfo(volent.VOLITY_CAPS_URI+'#'+volent.volityversion) info2.addidentity('volity', 'parlor', self.gamename) info2.addfeature(interface.NS_CAPS) form = jabber.dataform.DataForm() self.dataform = form val = config.get('entity-desc') if (not val): val = gameclass.gamedescription form.addfield('description', val) form.addfield('ruleset', gameclass.ruleseturi) form.addfield('volity-role', self.volityrole) form.addfield('ruleset-version', gameclass.rulesetversion) val = gameclass.websiteurl if (not val): val = gameclass.ruleseturi form.addfield('website', val) if (config.get('contact-email')): form.addfield('contact-email', config.get('contact-email')) if (config.get('contact-jid')): form.addfield('contact-jid', config.get('contact-jid')) form.addfield('volity-version', volent.volityversion) if (self.visibility): val = '1' else: val = '0' form.addfield('visible', val) info.setextendedinfo(form) info2.setextendedinfo(form) infocap = jabber.disco.DiscoInfo() infocap.addfeature(volent.VOLITY_CAPS_URI+'#'+self.volityrole) disco.addinfo(volent.VOLITY_CAPS_URI+'#'+self.volityrole, infocap) # assumes resource didn't change items = disco.additems() items.additem(self.jid, node='ruleset', name='Ruleset URI') items.additem(self.jid, node='open_games', name='Open games at this parlor') items.additem(self.jid, node='bots', name='Bots available from this parlor') items = disco.additems('ruleset') items.additem( unicode(self.bookkeeperjid), node=gameclass.ruleseturi, name='Ruleset information (%s)' % gameclass.ruleseturi) items = disco.additems('open_games', self.listopengames) items = disco.additems('bots', self.listbots) # Set up the RPC service self.rpccli = self.conn.getservice('rpcclience') rpcserv = self.conn.getservice('rpcservice') assert isinstance(rpcserv.getopset(), volent.ClientRPCWrapperOpset) ops = rpcserv.getopset().getopset() dic = ops.getdict() dic['volity'] = ParlorVolityOpset(self) dic['admin'] = ParlorAdminOpset(self) # Set up a simple roster-handler to accept subscription requests. self.conn.adddispatcher(self.handlerosterquery, name='iq', type='set') # Set up the keepalive service keepaliveflag = False if (config.get('keepalive')): keepaliveflag = True keepaliveinterval = None if (config.get('keepalive-interval')): keepaliveinterval = int(config.get('keepalive-interval')) if (keepaliveflag or keepaliveinterval): if (keepaliveinterval): serv = jabber.keepalive.KeepAliveService(keepaliveinterval) else: serv = jabber.keepalive.KeepAliveService() self.conn.addservice(serv) self.addhandler('ready', serv.start) self.log.warning('sending keepalive messages to self at interval of %d seconds', serv.getinterval())
# because each list entry includes the JID, and we don't actually know # the JID until we're connected. (The JID from the command line may # not be correct, because the Jabber resource we get may not be the # one we asked for.) def itemfunc(): items = zymb.jabber.discodata.DiscoItems() selfjid = cl.getjid() items.additem(selfjid, 'Return "hello".', 'hello') items.additem(selfjid, 'Returns the argument passed to it.', 'id') items.additem(selfjid, 'Waits the requested number of seconds.', 'wait') items.additem(selfjid, 'Send a Jabber message.', 'message') items.additem(selfjid, 'Send a disco info query.', 'disco') items.additem(selfjid, 'Send a disco items query.', 'discit') items.additem(selfjid, 'Shut down this server.', 'exit') return items disco.additems(None, itemfunc) # Add a DiscoClience to our Jabber connection. This handles outgoing # disco queries (and their incoming results). This will be used by the # "disco" and "discit" RPC calls -- see above. discoc = zymb.jabber.disco.DiscoClience() cl.addservice(discoc) # Add a RPCService to our Jabber connection. This handles incoming # RPC calls. rpc = zymb.jabber.rpc.RPCService() # A MyMethodOpset instance handles the calls when they arrive. rpc.setopset(MyMethodOpset()) cl.addservice(rpc) # We do not need an RPCClience, because we do not plan to make any outgoing
def __init__(self, config): self.jabbersecurity = config.get('jabber-security') volent.VolEntity.__init__(self, config.get('jid'), config.get('password'), config.get('jid-resource'), config.get('host'), secure=self.jabbersecurity) # Set the default shutdown conditions self.shutdowngraceful = True self.shutdownrestart = True self.shutdownrestartdelay = True self.canrestart = config.has_key('restart-script') self.restartfunc = config.get('restart-func-') # Locate the game class. ls = config.get('game').split('.') if (len(ls) < 2): raise ValueError('gameclass must be of the form module.gameclass') classname = ls[-1] modpath = '.'.join(ls[:-1]) mod = __import__(modpath, globals(), locals(), [classname]) gameclass = getattr(mod, classname) self.gameclass = gameclass if (gameclass == game.Game or (type(gameclass) != types.ClassType) or (not issubclass(gameclass, game.Game))): raise ValueError( 'gameclass must be a subclass of volity.game.Game') if (not gameclass.gamename): raise TypeError('gameclass does not define class.gamename') if (not gameclass.ruleseturi): raise TypeError('gameclass does not define class.ruleseturi') # Locate the bot classes (if there are any). self.botclasses = [] botls = config.getall('bot') for botclassname in botls: ls = botclassname.split('.') if (len(ls) < 2): raise ValueError( 'botclass must be of the form module.botclass') classname = ls[-1] modpath = '.'.join(ls[:-1]) mod = __import__(modpath, globals(), locals(), [classname]) botclass = getattr(mod, classname) self.botclasses.append(botclass) if (botclass == bot.Bot or (type(botclass) != types.ClassType) or (not issubclass(botclass, bot.Bot))): raise ValueError( 'botclass must be a subclass of volity.bot.Bot') if (botclass.gameclass == None or (type(botclass.gameclass) != types.ClassType) or (not issubclass(self.gameclass, botclass.gameclass))): raise ValueError('botclass does not play ' + config.get('game')) if (not botclass.boturi): raise TypeError('botclass does not define class.boturi') if (botclass.boturi in [bc.boturi for bc in self.botclasses[:-1]]): raise TypeError('class.boturi used more than once') self.botfactories = [] for jidstr in config.getall('bot-factory'): self.botfactories.append(interface.JID(jidstr)) bookjidstr = config.get('bookkeeper', '[email protected]/volity') self.bookkeeperjid = interface.JID(bookjidstr) if (not self.bookkeeperjid.getresource()): self.bookkeeperjid.setresource('volity') # Set the administrative JID (if present) self.adminjids = [] if (config.get('admin')): val = config.get('admin') ls = [interface.JID(subval.strip()) for subval in val.split(',')] self.adminjids = ls # Various Jabber handlers. self.addhandler('end', self.endwork) self.conn.adddispatcher(self.handlepresence, name='presence') self.conn.adddispatcher(self.handlemessage, name='message') # Set up internal state. val = config.get('entity-name') if (not val): val = gameclass.gamename self.gamename = val self.log.warning('Game parlor running: %s', self.gamename) self.referees = {} self.muchost = interface.JID( config.get('muchost', 'conference.volity.net')) self.online = True self.startuptime = time.time() self.activitytime = None self.refereesstarted = 0 self.visibility = config.getbool('visible', True) self.actors = {} # Set up the disco service disco = self.conn.getservice('discoservice') info = disco.addinfo() info.addidentity('volity', 'parlor', self.gamename) info.addfeature(interface.NS_CAPS) info2 = disco.addinfo(volent.VOLITY_CAPS_URI + '#' + volent.volityversion) info2.addidentity('volity', 'parlor', self.gamename) info2.addfeature(interface.NS_CAPS) form = jabber.dataform.DataForm() self.dataform = form val = config.get('entity-desc') if (not val): val = gameclass.gamedescription form.addfield('description', val) form.addfield('ruleset', gameclass.ruleseturi) form.addfield('volity-role', self.volityrole) form.addfield('ruleset-version', gameclass.rulesetversion) val = gameclass.websiteurl if (not val): val = gameclass.ruleseturi form.addfield('website', val) if (config.get('contact-email')): form.addfield('contact-email', config.get('contact-email')) if (config.get('contact-jid')): form.addfield('contact-jid', config.get('contact-jid')) form.addfield('volity-version', volent.volityversion) if (self.visibility): val = '1' else: val = '0' form.addfield('visible', val) info.setextendedinfo(form) info2.setextendedinfo(form) infocap = jabber.disco.DiscoInfo() infocap.addfeature(volent.VOLITY_CAPS_URI + '#' + self.volityrole) disco.addinfo(volent.VOLITY_CAPS_URI + '#' + self.volityrole, infocap) # assumes resource didn't change items = disco.additems() items.additem(self.jid, node='ruleset', name='Ruleset URI') items.additem(self.jid, node='open_games', name='Open games at this parlor') items.additem(self.jid, node='bots', name='Bots available from this parlor') items = disco.additems('ruleset') items.additem(unicode(self.bookkeeperjid), node=gameclass.ruleseturi, name='Ruleset information (%s)' % gameclass.ruleseturi) items = disco.additems('open_games', self.listopengames) items = disco.additems('bots', self.listbots) # Set up the RPC service self.rpccli = self.conn.getservice('rpcclience') rpcserv = self.conn.getservice('rpcservice') assert isinstance(rpcserv.getopset(), volent.ClientRPCWrapperOpset) ops = rpcserv.getopset().getopset() dic = ops.getdict() dic['volity'] = ParlorVolityOpset(self) dic['admin'] = ParlorAdminOpset(self) # Set up a simple roster-handler to accept subscription requests. self.conn.adddispatcher(self.handlerosterquery, name='iq', type='set') # Set up the keepalive service keepaliveflag = False if (config.get('keepalive')): keepaliveflag = True keepaliveinterval = None if (config.get('keepalive-interval')): keepaliveinterval = int(config.get('keepalive-interval')) if (keepaliveflag or keepaliveinterval): if (keepaliveinterval): serv = jabber.keepalive.KeepAliveService(keepaliveinterval) else: serv = jabber.keepalive.KeepAliveService() self.conn.addservice(serv) self.addhandler('ready', serv.start) self.log.warning( 'sending keepalive messages to self at interval of %d seconds', serv.getinterval())