def cancel_task(name): if name in tasks: tasks.pop(name) if next_task == name: define_next_task() else: console.display("SCHEDULER| ERROR: No such task")
def init(): global conn, c, last_match dbexists = isfile("database.sqlite3") conn = sqlite3.connect("database.sqlite3") conn.row_factory = sqlite3.Row c = conn.cursor() #set up trueskill here: ts.setup(draw_probability=0.01) if dbexists: try: check_db() except Exception as e: console.display(e) console.terminate() return else: console.display("DATATBASE| Creating new database...") create_tables() c.execute("SELECT pickup_id from pickups ORDER BY pickup_id DESC LIMIT 1") result = c.fetchone() if result: last_match = result[0] else: last_match = -1
def reply(channel, member, msg): console.display("SEND| {0}> {1}, {2}".format(channel.name, member.nick or member.name, msg)) send_queue.append( [channel.send, { 'content': "<@{0}>, {1}".format(member.id, msg) }])
def new_channel(channel, admin): path = "channels/" + channel.id shutil.copytree("channels/default", path) c = bot.Channel(channel) c.update_config("ADMINID", admin.id) bot.channels.append(c) console.display("SYSTEM| CREATED NEW PICKUP CHANNEL: {0}>{1}".format( channel.server.name, channel.name))
async def on_ready(): global ready if not ready: process_connection() ready = True else: console.display("DEBUG| Unexpected on_ready event!") await c.change_presence(activity=discord.Game(name='pm !help'))
def run(frametime): if next_task: if frametime > tasks[next_task][0]: current_task = tasks.pop(next_task) try: current_task[1](*current_task[2]) except Exception as e: console.display("SCHEDULER| ERROR: Task function failed @ {0} {1}, Exception: {2}".format(current_task[1], current_task[2], e)) define_next_task()
def send(frametime): global lastsend, connected if len(send_queue) > 0 and frametime - lastsend > 1: destination, data = send_queue.pop(0) console.display('SEND| /{0}: {1}'.format(destination, data)) #only display messages in silent mode if not silent: Client.send_message(destination, data) lastsend = frametime
def get_empty_servers(): for serv in c.guilds: n = 0 for chan in serv.channels: if chan.id in [i.cfg['channel_id'] for i in bot.channels]: n = 1 break if not n: console.display("server name: {0}, id: {1}".format( serv.name, serv.id))
async def send(): #send messages in queue global send_queue if len(send_queue): for func, kwargs in send_queue: try: await func(**kwargs) except Exception as e: console.display("ERROR| could not send data ({0}). {1}".format( str(func), str(e))) send_queue = []
async def on_message(message): # if message.author.bot: # return if isinstance( message.channel, discord.abc.PrivateChannel) and message.author.id != c.user.id: console.display("PRIVATE| {0}>{1}>{2}: {3}".format( message.guild, message.channel, message.author.display_name, message.content)) private_reply(message.author, config.cfg.HELPINFO) elif message.content == '!enable_pickups': if message.channel.permissions_for(message.author).manage_channels: if message.channel.id not in [x.id for x in bot.channels]: newcfg = stats3.new_channel(message.guild.id, message.guild.name, message.channel.id, message.channel.name, message.author.id) bot.channels.append(bot.Channel(message.channel, newcfg)) reply(message.channel, message.author, config.cfg.FIRST_INIT_MESSAGE) else: reply(message.channel, message.author, "this channel allready have pickups configured!") else: reply( message.channel, message.author, "You must have permission to manage channels to enable pickups." ) elif message.content == '!disable_pickups': if message.channel.permissions_for(message.author).manage_channels: for chan in bot.channels: if chan.id == message.channel.id: bot.delete_channel(chan) reply(message.channel, message.author, "pickups on this channel have been disabled.") return reply(message.channel, message.author, "pickups on this channel has not been set up yet!") else: reply( message.channel, message.author, "You must have permission to manage channels to disable pickups." ) elif message.content != '': for channel in bot.channels: if message.channel.id == channel.id: try: await channel.processmsg(message) except: console.display( "ERROR| Error processing message: {0}".format( traceback.format_exc()))
def init(dirname=""): global cfg #load config try: cfg = SourceFileLoader('cfg', 'config.cfg').load_module() except Exception as e: console.display("ERROR| ERROR PARSING config.cfg FILE!!! {0}".format( str(e))) console.terminate() #check if we need to update from previous stats system if os.path.isdir('channels'): console.display( "OLD DATABASE FOLDER FOUND! PLEASE RUN 'updater.py' OR DELETE/RENAME 'channels' FOLDER." ) os._exit(0)
def bot_run(): while not c.is_closed and console.alive: frametime = time.time() bot.run(frametime) scheduler.run(frametime) console.run() if not c.is_closed: if len(client.send_queue) > 0: data = client.send_queue.pop(0) if data[0] == 'msg': destination, content = data[1], data[2] console.display('SEND| /{0}: {1}'.format(destination, content)) if not client.silent: try: yield from c.send_message(destination, content) except: console.display("ERROR| Could not send the message. "+str(sys.exc_info())) elif data[0] == 'topic': content = data[1] if not client.silent: try: yield from c.edit_channel(client.channel, topic=content) except: console.display("ERROR| Could not change topic."+str(sys.exc_info())) elif data[0] == 'leave_server': for serv in c.servers: if serv.id == data[1]: console.display("Leaving {0}...".format(serv.name)) yield from c.leave_server(serv) break else: console.display("ERROR| Connection to server has been closed unexpectedly.") console.terminate() yield from asyncio.sleep(0.5) # task runs every 0.5 seconds #quit gracefully try: yield from Client.logout() except: pass console.log.close() print("QUIT NOW.") os._exit(0)
def on_message(message): if message.channel.is_private and message.author.id != c.user.id: console.display("PRIVATE| {0}>{1}>{2}: {3}".format(message.server, message.channel, message.author.display_name, message.content)) client.send_queue.append(['msg', message.channel, config.cfg.HELPINFO]) if message.content == '!enable_pickups': if message.channel.permissions_for(message.author).manage_channels: if message.channel.id not in [x.id for x in bot.channels]: newcfg = stats3.new_channel(message.server.id, message.server.name, message.channel.id, message.channel.name, message.author.id) bot.channels.append(bot.Channel(message.channel, newcfg)) client.reply(message.channel, message.author, config.cfg.FIRST_INIT_MESSAGE) else: client.reply(message.channel, message.author, "this channel allready have pickups configured!") else: client.reply(message.channel, message.author, "You must have permission to manage channels to enable pickups.") elif message.content == '!disable_pickups': if message.channel.permissions_for(message.author).manage_channels: for chan in bot.channels: if chan.id == message.channel.id: stats3.delete_channel(message.channel.id) bot.channels.remove(chan) client.reply(message.channel, message.author, "pickups on this channel have been disabled.") return client.reply(message.channel, message.author, "pickups on this channel has not been set up yet!") else: client.reply(message.channel, message.author, "You must have permission to manage channels to disable pickups.") else: for channel in bot.channels: if message.channel.id == channel.id: console.display("CHAT| {0}>{1}>{2}: {3}".format(message.server, message.channel, message.author.display_name, message.content)) try: channel.processmsg(message.content, message.author) except: console.display("ERROR| Error processing message: {0}".format(traceback.format_exc()))
def on_ready(): if not client.ready: client.process_connection() console.display("SYSTEM| Setting status message...") yield from c.change_presence(game=discord.Game(name='pm !help')) console.display("SYSTEM| Initialization complete!") loop.create_task(bot_run()) else: console.display("DEBUG| Unexpected on_ready event!") yield from c.change_presence(game=discord.Game(name='pm !help'))
def run(): while True: try: if config.cfg.DISCORD_TOKEN != "": console.display("SYSTEM| logging in with token...") c.loop.run_until_complete(c.start(config.cfg.DISCORD_TOKEN)) else: console.display( "SYSTEM| logging in with username and password...") c.loop.run_until_complete( c.start(config.cfg.USERNAME, config.cfg.PASSWORD)) c.loop.run_until_complete(c.connect()) except KeyboardInterrupt: console.display("ERROR| Keyboard interrupt.") console.terminate() c.loop.run_until_complete(close()) print("QUIT NOW.") break except Exception as e: console.display("ERROR| Disconnected from the server: " + str(e) + "\nReconnecting in 15 seconds...") time.sleep(15)
def process_connection(): global ready console.display('SYSTEM| Logged in as: {0}, ID: {1}'.format( c.user.name, c.user.id)) channels = stats3.get_channels() for cfg in channels: discord_channel = c.get_channel(cfg['channel_id']) if discord_channel == None: console.display( "SYSTEM| Could not find channel '{0}>{1}#' with CHANNELID '{2}'! Scipping..." .format(cfg['server_name'], cfg['channel_name'], cfg['channel_id'])) #todo: delete channel else: chan = bot.Channel(discord_channel, cfg) bot.channels.append(chan) console.display( "SYSTEM| '{0}>{1}#' channel init successfull".format( chan.cfg['server_name'], chan.cfg['channel_name'])) ready = True
def edit_message(msg, new_content): console.display("EDIT| {0}> {1}".format(msg.channel.name, new_content)) send_queue.append([msg.edit, {'content': new_content}])
def private_reply(member, msg): console.display("SEND_PM| {0}> {1}".format(member.name, msg)) send_queue.append([member.send, {'content': msg}])
channel.processmsg(message.content, message.author) except: console.display("ERROR| Error processing message: {0}".format(traceback.format_exc())) @c.event @asyncio.coroutine def on_member_update(before, after): #console.display("DEBUG| {0} changed status from {1} to -{2}-".format(after.name, before.status, after.status)) if str(after.status) in ['idle', 'offline']: bot.update_member(after) loop = asyncio.get_event_loop() try: if config.cfg.DISCORD_TOKEN != "": console.display("SYSTEM| logging in with token...") loop.run_until_complete(c.login(config.cfg.DISCORD_TOKEN)) else: console.display("SYSTEM| logging in with username and password...") loop.run_until_complete(c.login(config.cfg.USERNAME, config.cfg.PASSWORD)) loop.run_until_complete(c.connect()) except Exception as e: console.display("ERROR| Disconnected from the server: "+str(e)) loop.run_until_complete(c.close()) finally: loop.close() console.terminate() print("QUIT NOW.") os._exit(0)
def add_task(name, delay, func, args, comment=None): if name not in tasks: tasks[name] = [time.time()+delay, func, args, comment] #time to run task, func define_next_task() else: console.display("SCHEDULER| ERROR: Task with this name already exist!")
def check_db(): c.execute("SELECT name FROM sqlite_master WHERE type='table'") tables = [i[0] for i in c.fetchall()] if "utility" not in tables: c.execute("""CREATE TABLE `utility` ( `variable` TEXT, `value` TEXT, PRIMARY KEY(`variable`) )""") c.execute("SELECT value FROM utility WHERE variable='version'") db_version = c.fetchone() if db_version: db_version = Decimal(db_version[0]) else: db_version = -1 if db_version < version: console.display( "DATABASE| Updating database from '{0}' to '{1}'...".format( db_version, version)) if db_version < 2: c.execute("""ALTER TABLE `pickup_configs` ADD COLUMN `allow_offline` INTEGER DEFAULT 0 """) if db_version < 3: c.execute("""ALTER TABLE `pickup_configs` ADD COLUMN `promotemsg` TEXT """) c.execute("""ALTER TABLE `channels` ADD COLUMN `promotemsg` TEXT """) if db_version < 4: c.execute("""ALTER TABLE `channels` ADD COLUMN `ranked_multiplayer` INTEGER DEFAULT 32; """) c.execute("""ALTER TABLE `channels` ADD COLUMN `ranked_calibrate` INTEGER DEFAULT 1; """) c.execute("""ALTER TABLE `pickups` ADD COLUMN `is_ranked` BOOL""") c.execute("""ALTER TABLE `player_pickups` ADD COLUMN `is_ranked` BOOL""") c.execute("""ALTER TABLE `player_pickups` ADD COLUMN `rank_after` INTEGER""") c.execute("""ALTER TABLE `player_pickups` ADD COLUMN `rank_change` INTEGER""") #rename points to rank and add wins and loses counters c.executescript( """ALTER TABLE channel_players RENAME TO tmp_channel_players; CREATE TABLE channel_players(`channel_id` TEXT, `user_id` TEXT, `nick` TEXT, `rank` INTEGER, `wins` INTEGER, `loses` INTEGER, `phrase` TEXT, PRIMARY KEY(`channel_id`, `user_id`)); INSERT INTO channel_players(channel_id, user_id, phrase) SELECT channel_id, user_id, phrase FROM tmp_channel_players; DROP TABLE tmp_channel_players""") if db_version < 5: #got to change all the ID's to INTEGER from TEXT to migrate to discord.py 1.0+ if db_version < 4: c.execute( "INSERT OR REPLACE INTO utility (variable, value) VALUES ('version', ?)", (str(version), )) conn.commit() raise (Exception( "In order to migrate to discord.py 1.0+ database tables must be rebuilded. Please backup your database (database.sqlite3 file) and run updater.py." )) if db_version < 6: #add custom team emojis c.execute("""ALTER TABLE `pickup_configs` ADD COLUMN `team_emojis` TEXT """) c.execute("""ALTER TABLE `channels` ADD COLUMN `team_emojis` TEXT """) if db_version < 7: c.execute("""ALTER TABLE `channel_players` ADD COLUMN `streak` INTEGER """) c.execute("""ALTER TABLE `channel_players` ADD COLUMN `is_seeded` BLOB """) if db_version < 8: #add custom team names c.execute("""ALTER TABLE `pickup_configs` ADD COLUMN `team_names` TEXT """) c.execute("""ALTER TABLE `channels` ADD COLUMN `team_names` TEXT """) if db_version < 9: c.execute("""ALTER TABLE `channels` ADD COLUMN `global_expire` INTEGER """) c.execute("""ALTER TABLE `channels` ADD COLUMN `ranked_streaks` INTEGER DEFAULT 1 """) if db_version < 10: c.execute("""ALTER TABLE `channels` ADD COLUMN `match_livetime` INTEGER """) if db_version < 11: c.execute("""ALTER TABLE `channels` ADD COLUMN `initial_rating` INTEGER """) c.execute( "INSERT OR REPLACE INTO utility (variable, value) VALUES ('version', ?)", (str(version), )) conn.commit()
def notice(channel, msg): console.display("SEND| {0}> {1}".format(channel.name, msg)) send_queue.append([channel.send, {'content': msg}])