def bot_main(bot_class, debug=False, is_master=False, arena="#python"): """Use this method to test bots during development (to run bots in stand-alone mode) """ from Credentials import botowner, botname, botpassword try: logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) # set a format str_format = '%(asctime)s:%(name)s:%(levelname)s:%(message)s' formatter = logging.Formatter(str_format) # define a Handler which writes INFO messages or higher # to the sys.stderr console = logging.StreamHandler() console.setLevel(logging.DEBUG) # tell the handler to use this format console.setFormatter(formatter) # add the handler to the mainloop logger logger.addHandler(console) filehandler = logging.FileHandler(os.getcwd() + R"/" + __name__ + ".log", mode='a') filehandler.setLevel(logging.ERROR) filehandler.setFormatter(formatter) logger.addHandler(filehandler) ssbot = SubspaceBot(debug, is_master, None, logging.getLogger(__name__ + ".Core")) ssbot.set_bot_info(__name__, "TestBoT", botowner) # get the module object for the current file... module = sys.modules[globals()['__name__']] md = ModuleData("TesttBot", module, "None", "test.ini", "", logging.getLogger(__name__)) bot = bot_class(ssbot, md) ssbot.connect_to_server('66.36.247.83', 7900, botname, botpassword, arena) while ssbot.is_connected(): event = ssbot.wait_for_event() bot.handle_events(ssbot, event) except Exception as e: log_exception(logger) raise e finally: bot.cleanup() logger.critical("Testbot shutting down") filehandler.close()
def bot_main(bot_class, debug=False, is_master=False, arena="#python"): """Use this method to test bots during development (to run bots in stand-alone mode) """ from Credentials import botowner, botname, botpassword try: logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) # set a format str_format = '%(asctime)s:%(name)s:%(levelname)s:%(message)s' formatter = logging.Formatter(str_format) # define a Handler which writes INFO messages or higher # to the sys.stderr console = logging.StreamHandler() console.setLevel(logging.DEBUG) # tell the handler to use this format console.setFormatter(formatter) # add the handler to the mainloop logger logger.addHandler(console) filehandler = logging.FileHandler( os.getcwd() + R"/" + __name__ + ".log", mode='a') filehandler.setLevel(logging.ERROR) filehandler.setFormatter(formatter) logger.addHandler(filehandler) ssbot = SubspaceBot( debug, is_master, None, logging.getLogger(__name__ + ".Core")) ssbot.set_bot_info(__name__, "TestBoT", botowner) # get the module object for the current file... module = sys.modules[globals()['__name__']] md = ModuleData("TesttBot", module, "None", "test.ini", "", logging.getLogger(__name__)) bot = bot_class(ssbot, md) ssbot.connect_to_server( '66.36.247.83', 7900, botname, botpassword, arena) while ssbot.is_connected(): event = ssbot.wait_for_event() bot.handle_events(ssbot, event) except Exception as e: log_exception(logger) raise e finally: bot.cleanup() logger.critical("Testbot shutting down") filehandler.close()
def run(self): ssbot = None botlist = [] try: ssbot = SubspaceBot(False, False, self.MQueue, logging.getLogger( "ML." + self.type + ".Core")) ssbot.set_bot_info(self.type, self.description, self.owner) self.ssbot = ssbot ssbot.arena = self.arena # serexl's bots look at arena in init for m in self.modules: bot = load_bot( ssbot, m[0], m[1], self.inifile, self.args, logging.getLogger("ML." + self.type + "." + m[0]) ) if bot: botlist.append(bot) retry = 0 while self.keepgoing: ssbot.connect_to_server( self.host, self.port, self.bname, self.bpassword, self.arena ) while ssbot.is_connected() and self.keepgoing: retry = 0 event = ssbot.wait_for_event() for b in botlist: b.handle_events(ssbot, event) if ssbot.should_reconnect() and retry < 6: self.logger.debug("Disconnected...") ssbot.reset_state() retry += 1 time.sleep(60 * retry) self.logger.debug("Reconnecting...") else: break except: log_exception(self.logger) finally: if isinstance(ssbot, SubspaceBot) and ssbot.is_connected(): ssbot.disconnect_from_server() for b in botlist: b.cleanup()
def load_bot(ssbot, modulename, param, inifile, args, logger): bot = None try: module = load_module(modulename) if issubclass(module.Bot, BotInterface): md = ModuleData(modulename, module, param, inifile, args, logger) bot = module.Bot(ssbot, md) else: msg = ("%s.Bot() is not a subclass of BotInterface, " "and can't be loaded") logger.error(msg % modulename) bot = None except: msg = "Trying to instantiate %s caused Exception" logger.error(msg % modulename) log_exception(logger) bot = None finally: return bot
def load_bot(ssbot, modulename, param, inifile, args, logger): bot = None try: module = load_module(modulename) if issubclass(module.Bot, BotInterface): md = ModuleData(modulename, module, param, inifile, args, logger) bot = module.Bot(ssbot, md) else: msg = ( "%s.Bot() is not a subclass of BotInterface, " "and can't be loaded" ) logger.error(msg % modulename) bot = None except: msg = "Trying to instantiate %s caused Exception" logger.error(msg % modulename) log_exception(logger) bot = None finally: return bot
def MasterMain(): ssbot = None master = None BotList = None try: # other bots use logging i dont want it to spamm the main logger rootlogger = logging.getLogger('') rootlogger.addHandler(NullHandler()) rootlogger.setLevel(logging.DEBUG) # logging.basicConfig( # level=logging.ERROR, # format='%(asctime)s:%(name)s:%(levelname)s:%(message)s', # datefmt='%m-%d %H:%M' # ) logger = logging.getLogger("ML") logger.setLevel(logging.DEBUG) # set a format formatter = logging.Formatter( '%(asctime)s:%(name)s:%(levelname)s:%(message)s') # define a Handler which writes INFO messages or # higher to the sys.stderr console = logging.StreamHandler() console.setLevel(logging.DEBUG) # tell the handler to use this format console.setFormatter(formatter) # add the handler to the mainloop logger logger.addHandler(console) filehandler = logging.FileHandler( os.path.join(os.getcwd(), "Bots.log"), mode='a') filehandler.setLevel(logging.ERROR) filehandler.setFormatter(formatter) logger.addHandler(filehandler) # command Line Options parser = OptionParser() parser.add_option("-c", "--ConfigFile", dest="ConfigFile", help="Load Configuration from a non default file", default=os.path.join(os.getcwd(), "Bots.json")) parser.add_option( "-p", "--Password", dest="Password", help="pass sysop/smod pass by commandline instead of in config", default=None ) (options, args) = parser.parse_args() Queue = MasterQueue() ssbot = SubspaceBot( False, True, Queue, logging.getLogger("ML.Master.Core")) ssbot.set_bot_info("Master", "MasterBot Manages the starting/stopping of bots", None) BotList = [] config = GlobalConfiguration(options.ConfigFile, options.Password) # this adds dir's to pythonpath so we can run the dev code # out of seperate dirs for p in config.paths: sys.path.append(p) # get the module object for the current file... module = sys.modules[globals()['__name__']] # loads atleast the masterbot md = ModuleData( "Master", module, "None", config.ConfigurationFile, "", logging.getLogger("ML.Master") ) master = Bot(ssbot, md, config, Queue) BotList.append(master) # load any bots that are specified in the config bot = None for m in config.Modules: bot = load_bot( ssbot, m[0], m[1], config.ConfigurationFile, "", logging.getLogger("ML.Master." + m[0]) ) if bot: BotList.append(bot) bot = None wait_time = 0 while ssbot.should_reconnect(): ssbot.connect_to_server(config.Host, config.Port, config.MasterName, config.MasterPassword, config.MasterArena) while ssbot.is_connected(): wait_time = 0 event = ssbot.wait_for_event() for b in BotList: b.handle_events(ssbot, event) logger.critical("Master disconnected") if ssbot.should_reconnect(): ssbot.reset_state() wait_time += 60 # if wait is over 10 mins reset wait period if wait_time > 600: wait_time = 0 # wait a little longer if retry fails each time time.sleep(wait_time) logger.critical("Reconnecting") except (KeyboardInterrupt, SystemExit): logger.critical("CTRL-c or System.exit() detected") except: logger.critical("Unhandled Exception") log_exception(logger) finally: if ssbot and ssbot.is_connected(): ssbot.disconnect_from_server() logger.info("Master disconnected") logger.info("Waiting For Bots to stop") logger.critical("Master shutting down") if master: master.StopAllBots() logger.critical("Requested Stop for all active bots...") if BotList: for b in BotList: b.cleanup() logger.critical("Master Bot behaviors cleansed") filehandler.close() sys.exit(1)
def MasterMain(): ssbot = None master = None BotList = None try: # other bots use logging i dont want it to spamm the main logger rootlogger = logging.getLogger('') rootlogger.addHandler(NullHandler()) rootlogger.setLevel(logging.DEBUG) # logging.basicConfig( # level=logging.ERROR, # format='%(asctime)s:%(name)s:%(levelname)s:%(message)s', # datefmt='%m-%d %H:%M' # ) logger = logging.getLogger("ML") logger.setLevel(logging.DEBUG) # set a format formatter = logging.Formatter( '%(asctime)s:%(name)s:%(levelname)s:%(message)s') # define a Handler which writes INFO messages or # higher to the sys.stderr console = logging.StreamHandler() console.setLevel(logging.DEBUG) # tell the handler to use this format console.setFormatter(formatter) # add the handler to the mainloop logger logger.addHandler(console) filehandler = logging.FileHandler(os.path.join(os.getcwd(), "Bots.log"), mode='a') filehandler.setLevel(logging.ERROR) filehandler.setFormatter(formatter) logger.addHandler(filehandler) # command Line Options parser = OptionParser() parser.add_option("-c", "--ConfigFile", dest="ConfigFile", help="Load Configuration from a non default file", default=os.path.join(os.getcwd(), "Bots.json")) parser.add_option( "-p", "--Password", dest="Password", help="pass sysop/smod pass by commandline instead of in config", default=None) (options, args) = parser.parse_args() Queue = MasterQueue() ssbot = SubspaceBot(False, True, Queue, logging.getLogger("ML.Master.Core")) ssbot.set_bot_info("Master", "MasterBot Manages the starting/stopping of bots", None) BotList = [] config = GlobalConfiguration(options.ConfigFile, options.Password) # this adds dir's to pythonpath so we can run the dev code # out of seperate dirs for p in config.paths: sys.path.append(p) # get the module object for the current file... module = sys.modules[globals()['__name__']] # loads atleast the masterbot md = ModuleData("Master", module, "None", config.ConfigurationFile, "", logging.getLogger("ML.Master")) master = Bot(ssbot, md, config, Queue) BotList.append(master) # load any bots that are specified in the config bot = None for m in config.Modules: bot = load_bot(ssbot, m[0], m[1], config.ConfigurationFile, "", logging.getLogger("ML.Master." + m[0])) if bot: BotList.append(bot) bot = None wait_time = 0 while ssbot.should_reconnect(): ssbot.connect_to_server(config.Host, config.Port, config.MasterName, config.MasterPassword, config.MasterArena) while ssbot.is_connected(): wait_time = 0 event = ssbot.wait_for_event() for b in BotList: b.handle_events(ssbot, event) logger.critical("Master disconnected") if ssbot.should_reconnect(): ssbot.reset_state() wait_time += 60 # if wait is over 10 mins reset wait period if wait_time > 600: wait_time = 0 # wait a little longer if retry fails each time time.sleep(wait_time) logger.critical("Reconnecting") except (KeyboardInterrupt, SystemExit): logger.critical("CTRL-c or System.exit() detected") except: logger.critical("Unhandled Exception") log_exception(logger) finally: if ssbot and ssbot.is_connected(): ssbot.disconnect_from_server() logger.info("Master disconnected") logger.info("Waiting For Bots to stop") logger.critical("Master shutting down") if master: master.StopAllBots() logger.critical("Requested Stop for all active bots...") if BotList: for b in BotList: b.cleanup() logger.critical("Master Bot behaviors cleansed") filehandler.close() sys.exit(1)
def handle_events(self, ssbot, event): if event.type == EVENT_COMMAND: if event.command.id == self.CID_SPG: mt = self.getMessageTuple(event) # (qtype, message type to respond with, # target[playername if priv msg) qd = (self.QTYPE_SPG, mt[0], mt[1]) db = self._db db.query(( "select * from (" " select * from eg_Bots.population " " order by id desc limit 70) as pop " "order by id asc" ), None, qd) if event.command.id == self.CID_SP: # automatically addlimit or not if len(event.arguments) > 0: try: l = int(event.arguments[0]) except: l = 10 log_exception(self.logger) if l <= 100: limit = "limit " + str(l) else: limit = "limit 100" else: limit = "limit 10" mt = self.getMessageTuple(event) # (qtype, message type to respond with, # target[playername if priv msg) qd = (self.QTYPE_SQL, mt[0], mt[1]) db = self._db db.query( "select * from eg_Bots.population order by id desc " + limit, None, qd) if event.type == EVENT_MESSAGE: if event.message_type == MESSAGE_TYPE_SYSTEM: if event.message.find(" - Sysop - ") != -1: if event.message.startswith("DevBot") or \ event.message.startswith("Bot"): self.popStats.staff.bots += 1 else: self.popStats.staff.sysops += 1 elif event.message.find(" - Mod - ") != -1: self.popStats.staff.mods += 1 elif event.message.find(" - SMod - ") != -1: self.popStats.staff.smods += 1 if event.type == EVENT_ARENA_LIST: for a in event.arena_list: # a (arena, pop, here) if a[0][0] >= '0' and a[0][0] <= '9': self.popStats.arenas.pubCount += 1 self.popStats.arenas.pubPop += a[1] elif a[0][0] == '#': self.popStats.arenas.privCount += 1 self.popStats.arenas.privPop += a[1] elif a[0].find(":") != -1: self.popStats.arenas.peerCount += 1 self.popStats.arenas.peerPop += a[1] else: self.popStats.arenas.nonPubCount += 1 self.popStats.arenas.nonPubPop += a[1] self.popStats.pop += a[1] elif event.type == EVENT_TICK: timer_expired = self.timer_man.getExpired() # a timer expired if timer_expired: # check for results if timer_expired.data == self.TID_CHECK_RESULTS: r = self._db.getResults() # most of the time this will be None so check first if r: self.HandleResults(ssbot, event, r) # set it to check again in a sec self.timer_man.set(1, 1) elif timer_expired.data == self.TID_PING_DB: # ping db self._db.ping() self.timer_man.set(300, self.TID_PING_DB) # Clear stats and repopulate elif timer_expired.data == self.TID_PARSE_STATS: self.popStats.Reset() ssbot.send_public_message("*listmod") ssbot.send_public_message("?arena") # do it again in 30 mins self.timer_man.set(1800, self.TID_PARSE_STATS) # in 10 secs pop stats will be done send it to db self.timer_man.set(3, self.TID_LOG_STATS) elif timer_expired.data == self.TID_LOG_STATS: # put in db a = self.popStats.arenas s = self.popStats.staff query = ( "INSERT INTO eg_bots.Population (" " pubc, pubp, npubc, npubp, privc, privp, prc, " " prp, botsc, sysopsc, smodsc, modsc" ") VALUES (" " %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i" ")" ) qtp = ( a.pubCount, a.pubPop, a.nonPubCount, a.nonPubPop, a.privCount, a.privPop, a.peerCount, a.peerPop, s.bots, s.sysops, s.smods, s.mods ) ssbot.send_public_message(query % qtp) # (qtype, message type to respond with, # target[playername if priv msg) qdata = (self.QTYPE_ADDPOP, MESSAGE_TYPE_PUBLIC, None) db = self._db db.query(query % qtp, None, qdata) pass