async def on_member_join(member): channel = discord.utils.get(client.get_all_channels(), server__name=settings.serverName, name='announcements') role = discord.utils.get(member.server.roles, name="Member") await client.add_roles(member, role) funcs.log("Member joined : "+str(member)) await client.send_message(discord.utils.get(client.get_all_channels(), server__name=settings.serverName, name='general'), "Welcome "+member.mention+" to Halite Tournaments! Check out the section "+channel.mention+" for information about the upcoming tournaments! <:logo:416779058924355596>")
def unpin_bag_guys() -> None: for chat_id in db.get_pin_bad_gays(): try: bot.unpin_chat_message(chat_id.decode('utf-8')) except Exception: log('Can\'t unpin bad_guy message', 'warning') # <<< End bag guys >>
def start_connection(): """ .. notes:: Funk to connect to MySQL DB :return: connection :rtype: connection: pymysql.connect """ try: connection = pymysql.connect(**BD_CONNECT) return connection except pymysql.err.OperationalError: log('Ошибка подключения к БД!', 'error')
def send_news(index: int, chat_id: str) -> None: global daily_news_msg, daily_news_data keyboard = InlineKeyboardMarkup() keyboard.add( InlineKeyboardButton( text="⬅️️", callback_data=f"daily_move_to {index - 1 if index > 0 else 'pass'}" ), InlineKeyboardButton( text="➡️", callback_data=f"daily_move_to " f"{index + 1 if index < len(daily_news_data[chat_id]) - 1 else 'pass'}" )) if daily_news_data[chat_id][index]['urlToImage'] is None or daily_news_data[chat_id][index]['urlToImage'] == '' \ or daily_news_data[chat_id][index]['description'] is None: daily_news_data[chat_id].pop(index) send_news(index, chat_id) return try: if requests.get(daily_news_data[chat_id][index]["url"]).ok: keyboard.add( InlineKeyboardButton( 'Читать', url=daily_news_data[chat_id][index]["url"])) except (requests.exceptions.ConnectionError, requests.exceptions.MissingSchema) as ex: log(f'Error in news url\n{ex}', 'error') try: if requests.get(daily_news_data[chat_id][index]['urlToImage']).ok: req = request.Request( daily_news_data[chat_id][index]['urlToImage'], method='HEAD') f = request.urlopen(req) if f.headers['Content-Length'] is not None: if int(f.headers['Content-Length']) > 5242880: raise error.URLError except (requests.exceptions.ConnectionError, requests.exceptions.MissingSchema, error.URLError, UnicodeEncodeError): daily_news_data[chat_id].pop(index) send_news(index, chat_id) return except IndexError as ex: log(f'Index Error in daily news\n{ex}', 'warning') bot.edit_message_media( chat_id=chat_id, message_id=daily_news_msg[chat_id].message_id, media=InputMediaPhoto( daily_news_data[chat_id][index]['urlToImage'], caption= f"<b>{clear_link(daily_news_data[chat_id][index]['title'])}</b>" f"\n\n{clear_link(daily_news_data[chat_id][index]['description'])}" f"\n\n<i>{clear_date(daily_news_data[chat_id][index]['publishedAt'])}</i>" f" <b>{index + 1}/{len(daily_news_data[chat_id])}</b>стр.", parse_mode='HTML'), reply_markup=keyboard)
def parser_memes() -> None: """ .. notes:: Dayle pasre memes from redit :return: None """ log('Parser is done', 'info') soup = BeautifulSoup(requests.get(URLS['memes'], headers={'User-Agent': generate_user_agent()}).content, 'html.parser') links = set() for link in soup.find_all('a'): url = link.get('href') if url is not None and re.fullmatch(r'https?://i.redd.it/?\.?\w+.?\w+', url): links.add(url) db.add_memes(links)
def send_daily_news() -> None: global daily_news_data, daily_news_msg for group in db.get_id_from_where('Setting', 'news_mailing', 'On'): setting = db.get_from(group['id'], 'Setting') try: daily_news_data[group['id']] = requests.get( 'https://' + f'newsapi.org/v2/top-headlines?country=' f'{"us" if setting["news"] == "Us" else "ua" if setting["news"] == "Ua" else "ru"}' f'&pageSize=10&apiKey={API["News"]["Api_Key"]}').json( )['articles'] except (requests.exceptions.ConnectionError, requests.exceptions.MissingSchema, error.URLError, UnicodeEncodeError) as ex: log(f'Error in api request daily news\n{ex}', 'error') else: daily_news_msg[group['id']] = bot.send_photo( group['id'], API['News']['image']) send_news(0, group['id'])
def add_memes(data_memes: list) -> None: """ :param: data_memes :type: data_memes: list :rtype None .. notes:: Add new memes from daily parser """ connection = start_connection() with connection.cursor() as cursor: for en, meme in enumerate([ meme for meme in data_memes if cursor.execute( f'SELECT * FROM Memes WHERE url LIKE \'{meme}\'') == 0 ], 1): cursor.execute(f'INSERT INTO `Memes`(`url`) VALUES (\'{meme}\');') connection.commit() else: log(f'Мемов добавлено: {en}', 'info') connection.close()
def send_bad_guy() -> None: """ .. notes:: Select most active users un group :return: None """ log('Send bad guy is done', 'info') for chat_id, users in db.get_bad_guy().items(): text = '🎉<b>Пидор' + f"{'ы' if len(users) > 1 else ''}" + ' дня</b>🎉\n' + ''.join( f"🎊💙<i>{db.get_from(user['id'], 'Users_name')}</i>💙🎊\n" for user in users ) + f'Прийми{"те" if len(users) > 1 else ""} наши поздравления👍' try: msg = bot.send_message(chat_id, text, parse_mode='HTML') bot.pin_chat_message(msg.chat.id, msg.message_id, disable_notification=True) db.set_pin_bad_gays(chat_id) except Exception: log('Error in bad guy', 'error') db.reset_users()
async def on_message(message): server = discord.utils.get(client.servers, name=settings.serverName) backup = discord.utils.get(client.get_all_channels(), server__name=settings.serverName, name='halite-backup') try: if message.content.startswith("!submit"): """ This command submits a player's bot when submissions are opened. This command can be run in `battles`, `season-*` and via PMs to the bot. This command adds a queue to the handler, the handler then picks up the queue from the database and : - Checks if it's a valid submission - If the user isn't already running something - Installs external libraries (if required) - Compiles the code (if required) - Runs a test game against itself to make sure it works - Sends logs and compiler outputs via DM to the player """ isPlayer = False if not settings.opened: player = discord.utils.get(server.roles, name="Player") for m in server.members: if str(m) == str(message.author): roles = m.roles if player in roles: isPlayer = True if not settings.submit and isPlayer and not settings.opened: #if the submissions are closed if not message.channel.is_private: await client.delete_message(message) await client.send_message( message.channel, "**Submissions are closed at the moment!** " + message.author.mention) elif isPlayer or settings.opened: if str(message.channel) != "season-" + settings.season and str( message.channel ) != "battles" and not message.channel.is_private: #if message is in the wrong channel if not message.channel.is_private: await client.delete_message(message) await client.send_message( message.channel, "**Cannot use this command in this channel!** " + message.author.mention) else: try: await client.send_message( message.channel, "`Submitting, compiling and testing your bot...` " + message.author.mention) response, compileLog, sub = await funcs.uploadBot( message.attachments[0].get('url'), str(message.author), message.attachments[0].get('filename')) await client.send_message( message.channel, "`" + response + "` " + message.author.mention) if not message.channel.is_private: await client.delete_message(message) if compileLog != "": #if compiled and run successfully if message.channel.is_private: global haliteBackup await client.send_file(haliteBackup, sub, content=">store " + message.author.id) await client.send_message( message.author, "**Here your compile and run log for yout bot submission!**" ) await client.send_file(message.author, compileLog) except IndexError: #no attachments present await client.send_message( message.channel, "`No attachment present!` " + message.author.mention) else: await client.send_message( message.channel, "**You are not a Player! Sign up for the tournament first!** " + message.author.mention) elif message.content.startswith("!submissions"): #check submissions """ This command shows the current status of submissions. Depending on the status the message changes, this command also shows when the submissions will close/open """ if settings.submit: s, s2 = "opened", "close" else: s, s2 = "closed", "open" desc = "Current status of submissions : **" + s + "**,\nthe submissions will " + s2 + " : **" + settings.timeSub + "**" embed = discord.Embed(title="Submissions for Season-" + settings.season, description=desc, color=0xffae00) embed.set_thumbnail( url= "https://raw.githubusercontent.com/Splinter0/Tournament-Environment/master/imgs/logo.png" ) embed.set_footer(text=funcs.getTime() + " (UTC) - HTBot") await client.send_message(message.channel, embed=embed) elif message.content.startswith("!help"): #help function """ This command simply prints the name of all other commands with a brief explaination """ battles = discord.utils.get(client.get_all_channels(), server__name=settings.serverName, name='battles') embed = discord.Embed(title="Commands for HTBot", description="Currently on Season-" + settings.season, color=0xffae00) embed.set_thumbnail( url= "https://raw.githubusercontent.com/Splinter0/Tournament-Environment/master/imgs/logo.png" ) embed.set_footer(text=funcs.getTime() + " (UTC) - HTBot") for k, c in sorted(commands.items()): embed.add_field(name=k, value=c, inline=False) await client.send_message(message.channel, embed=embed) elif message.content.startswith("!utc"): text = "**Current UTC time :** *" + funcs.getTime() + "*" await client.send_message(message.channel, text) elif message.content.startswith("!matches"): #check upcoming matches """ This command allows everyone to check the upcoming matches. A player can also run : !matches @Splinter And this will return all the games that Splinter is in """ if settings.onTour: #if we are running in a tournament m = str(message.content).split() matches = settings.matches if matches is None or len(matches) < 2: await client.send_message(message.channel, "**No scheduled matches!**") elif len(m) == 1: #check all matches embed = discord.Embed( title="Matches", description="Here are the upcoming matches! " + settings.emojis["explosion"], color=0xffae00) embed.set_thumbnail( url= "https://raw.githubusercontent.com/Splinter0/Tournament-Environment/master/imgs/logo.png" ) embed.set_footer(text=funcs.getTime() + " (UTC) - HTBot") for k, v in sorted(matches.items()): if k == "placeholder": continue text = "**" + k + "** : \n" value = "" for r in v: value += "\t" + r + "\n" embed.add_field(name=text, value=value, inline=False) await client.send_message(message.channel, embed=embed) else: await client.send_message(message.channel, "**No scheduled matches!**") elif message.content.startswith("!battle"): """ This command allows the players to battle against themselves whenever they want when there's an ongoing tournament. This feature is to allow the players to try out the game environment and debug their bots properly. Example of a command : !battle @Splinter @FrankWhoee -d 292 180 -s 123456789 This command starts a game between FrankWhoee and Splinter with a map size of 292x180 amd the seed 123456789. -d and -s are optional """ #if we are in a tournament and in the right channel if settings.onTour and str(message.channel) == "battles": try: #get the players from mentions pp = [] for p in message.raw_mentions: pp.append(str(server.get_member(p))) tokens = message.content.split() seed = tokens[tokens.index('-s') + 1] if '-s' in tokens else None mode = 0 if '2v2' in tokens: if len(pp) == 1: for i in range(3): pp.append(pp[0]) elif len(pp) == 2: for i in range(2): pp.append(pp[i]) elif len(pp) == 3: pp.append(pp[-1]) elif len(pp) > 4: raise IndexError mode = 2 else: if len(pp) == 1: pp.append(pp[0]) elif len(pp) == 3: pp.append(pp[-1]) mode = 4 elif len(pp) == 4: mode = 4 try: #get the map sizes width = str(int(tokens[tokens.index('-d') + 1])) height = str(int(tokens[tokens.index('-d') + 2])) except: #if there is a problem set default size await client.send_message( message.channel, "*Using default size map : 240x160*") width = "240" height = "160" await client.send_message( message.channel, "*Running battle...* " + settings.emojis["logo"]) status, result, logs, replay = await funcs.battle( pp, width, height, mode, seed) await client.send_message(message.channel, status) if result != "": #if we have an output await client.send_message(message.channel, result) if replay != "": await client.send_file(message.channel, replay) #check if logs are present and send them for l in range(len(logs)): try: if logs[l] != "": await client.send_message( message.mentions[l], "**Here is the logfile of your bot : (timstamp battle : " + funcs.getTime() + ")**") await client.send_file( message.mentions[l], logs[l]) os.remove(logs[l]) else: await client.send_message( message.mentions[l], "**No log file present : (timstamp battle : " + funcs.getTime() + ")**") except: pass except (KeyError, IndexError): #formatting error await client.send_message( message.channel, "**Bad formatting! Run !help for info about commands**" ) elif str(message.channel) != "battles": #wrong channel! battles = discord.utils.get(client.get_all_channels(), server__name=settings.serverName, name='battles') await client.send_message( message.channel, "**Run this in the " + battles.mention + " channel!**") else: #tournament is closed await client.send_message( message.channel, "**Feature not avaible at the moment!**") elif message.content.startswith("!players"): """ This command allows to see all the players partecipating in this season and their submission status. (submitted/not) """ player = discord.utils.get(server.roles, name="Player") members = client.get_all_members() players = {} for m in members: if player in m.roles: p = settings.db.players.find_one( {"username": str(m).replace(' ', '')}) if p is None: players[str(m).replace(' ', '')] = False else: players[str(m).replace(' ', '')] = True if len(players) > 0: text = "**Here are all the players in this season :** " + settings.emojis[ "aspiring"] + "\n" for p, s in players.items(): r = "Yes" if s else "No" text += "\n`" + p + "`, has submitted : *" + r + "*" else: text = "**No registered player at the moment!** " + settings.emojis[ "aspiring"] await client.send_message(message.channel, text) elif message.content.startswith("!brackets"): #get current brackets """ Sends the current brackets for the season """ if settings.onTour: try: await client.send_file(message.channel, settings.brackets) except: await client.send_message( message.channel, "**Brackets are not up yet!** " + settings.emojis["paper"]) else: #if no tournament is running await client.send_message( message.channel, "**No tournament currently ongoing!** " + settings.emojis["explosion"]) elif message.content.startswith( "!languages"): #send all supported languages """ This command outputs all the languages that are currently supported. To check in specific a language : !languages python This will output the command used to compile the player's code, the command used to install the external libraries and the command used to run a test game """ m = message.content.split() if len(m) == 1: embed = discord.Embed(title="Languages", description="All languages supported " + settings.emojis["paper"], color=0xffae00) embed.set_thumbnail( url= "https://raw.githubusercontent.com/Splinter0/Tournament-Environment/master/imgs/logo.png" ) embed.set_footer(text=funcs.getTime() + " (UTC) - HTBot") for k, c in sorted(funcs.languages.items()): content = "Compile command : " content += "*" + c[1] + "*" if c[ 1] != "" else "*not needed*" content += "\nRun command : *" + c[2] + "*" embed.add_field(name=k, value=content, inline=False) await client.send_message(message.channel, embed=embed) else: content = "" for k, v in sorted(funcs.languages.items()): if m[1] == k: embed = discord.Embed(title=k, description="Specs for " + k + " " + settings.emojis["paper"], color=0xffae00) embed.set_thumbnail( url= "https://raw.githubusercontent.com/Splinter0/Tournament-Environment/master/imgs/logo.png" ) embed.set_footer(text=funcs.getTime() + " (UTC) - HTBot") content = "*" + v[1] + "*" if v[ 1] != "" else "*not needed*" embed.add_field(name="Compile command", value=content, inline=False) content = "*" + v[2] + "*" embed.add_field(name="Run command :", value=content, inline=False) await client.send_message(message.channel, embed=embed) break if content == "": content = "**Language not supported!**" await client.send_message(message.channel, content) elif message.content.startswith("!donations"): """ This command prints information on how to donate to this project """ embed = discord.Embed(title="Donations", description="Help the community grow!", color=0xffae00) embed.set_thumbnail( url= "https://raw.githubusercontent.com/Splinter0/Tournament-Environment/master/imgs/logo.png" ) embed.set_footer(text=funcs.getTime() + " (UTC) - HTBot") embed.add_field( name="PayPal", value= "Donations are used to help support Halite Tournaments. We use your contributions to run our servers and give cash prizes.\nDonate here: https://www.paypal.me/HaliteTournaments.\nDonating will give you the **Contributor** role which has access to the Contributors voice channel. More privileges for Contributors will be coming!\n" + settings.emojis["paper"], inline=False) embed.add_field( name="GitHub", value= "You can also contribute by working with us on our repositories! Check it out at : https://github.com/HaliteTournaments", inline=False) await client.send_message(message.channel, embed=embed) elif message.content.startswith("!specs"): """ This command prints the specs for the current season like : constants, map sizes and environment changes. """ try: with open(settings.specs, "r") as s: infos = s.read() infos = infos.replace("\\n", "\n") await client.send_message( message.channel, infos + "\n" + settings.emojis["logo"]) except FileNotFoundError: text = "**Specs for season-" + settings.season + " are still not out!** " + settings.emojis[ "paper"] await client.send_message(message.channel, text) elif message.content.startswith("!engine"): """ This will give the players access to the code of the Halite environment used in the ongoing tournament. It will also give away a percompiled version of it. """ if len(message.content.split()) > 1: engine = None try: if message.content.split()[1] == "win": engine = settings.engine[0] elif message.content.split()[1] == "mac": engine = settings.engine[1] elif message.content.split()[1] == "linux": engine = settings.engine[2] except: engine = None try: await client.send_file(message.author, engine) await client.send_message( message.channel, "*Sending precompiled engine in DMs* " + message.author.mention + " " + settings.emojis["engine"]) await client.send_message( message.author, "**Here is your precompiled engine for " + message.content.split()[1] + "**") except: await client.send_message( message.channel, "**Precompile engine for " + message.content.split()[1] + " is not avaible yet!** " + message.author.mention + " " + settings.emojis["engine"]) else: if settings.engineLink != "" and settings.onTour: await client.send_message( message.channel, "**Here is the link containing the info for the engine : " + settings.engineLink + "** " + settings.emojis["engine"]) else: await client.send_message( message.channel, "**Link still not avaible!** " + settings.emojis["paper"]) #admin commands elif str(message.author) in settings.admins: """ This commands are only avaible for the members in the `admins` group """ if message.content.startswith( "!type"): #make bot type in current channel """ This will send a message from HTBot """ await client.delete_message(message) await client.send_message( message.channel, str(message.content).replace("!type", "")) elif message.content.startswith("!match"): """ This command starts an official tournament match, if Vegas interaction is enabled it will also create a bet between the two players. This command will output the outcome of the games and a zip file containing all replays of the games run in the match """ if settings.onTour: try: #get the players from mentions pp = [] for p in message.raw_mentions: pp.append(str(server.get_member(p))) mode = 1 if message.content.split()[-1] == "2v2": if len(pp) == 1: for i in range(3): pp.append(pp[0]) elif len(pp) == 2: for i in range(2): pp.append(pp[i]) elif len(pp) == 3: pp.append(pp[-1]) elif len(pp) > 4: raise IndexError mode = 3 else: if len(pp) == 1: pp.append(pp[0]) elif len(pp) == 3: pp.append(pp[-1]) mode = 5 elif len(pp) == 4: mode = 5 await client.send_message( message.channel, "*Running match...* " + settings.emojis["logo"]) #if haliteVegas != None: # await client.send_message(haliteVegas, "!create "+message.mentions[0].mention+" "+message.mentions[1].mention) status, result, _, replay = await funcs.battle( pp, "", "", mode) await client.send_message(message.channel, status) if result != "": #if we have an output await client.send_message(message.channel, result) if replay != "": await client.send_file(message.channel, replay) except IndexError: #formatting error await client.send_message( message.channel, "**Bad formatting! Run !help for info about commands**" ) else: await client.send_message( message.channel, "**Feature not avaible at the moment!**") elif message.content.startswith("!admin"): #print admin commands """ A help command for admins """ text = "```\n" for k, c in sorted(adminCommands.items()): text += k + " : " + c + "\n" text += "```" await client.send_message(message.channel, text) elif message.content.startswith( "!clear"): #delete n messages in a channel """ This command allows to delete x messages in a y channel E.g : !clear 20 battles Will delete 20 messages in the battles channel """ try: n = int(message.content.split()[1]) #number of messages ch = message.content.split()[2] #channel if ch != "*": #current channel channel = discord.utils.get( client.get_all_channels(), server__name=settings.serverName, name=ch) else: channel = message.channel await client.purge_from(channel, limit=n) except IndexError: await client.send_message( discord.utils.get(client.get_all_channels(), server__name=settings.serverName, name='halite'), "**Wrong command formatting**") elif message.content.startswith( "!post"): #upload a file from server to channel """ This will upload a file from the server to the channel wanted. """ try: await client.delete_message(message) c = message.content.replace("!post", "") f, ch = c.split()[0], c.split()[1] if ch != "*": channel = discord.utils.get( client.get_all_channels(), server__name=settings.serverName, name=ch) else: channel = message.channel await client.send_file(channel, f, content=c.replace(f + " " + ch, "")) except FileNotFoundError: s = funcs.log("File " + f + " not found!") await client.send_message( discord.utils.get(client.get_all_channels(), server__name=settings.serverName, name='halite'), s) except IndexError: await client.send_message( discord.utils.get(client.get_all_channels(), server__name=settings.serverName, name='halite'), "**Wrong command formatting**") elif message.content.startswith( "!subs"): #change submissions status """ This command will change the submissions status E.g. : !subs False Will close the submissions """ s = message.content.replace("!subs", "").split() if s != "": try: boo = funcs.str_to_bool(s[0]) settings.db.settings.update_one( {}, {"$set": { "submit": boo }}) settings.submit = boo await client.send_message( message.channel, "**Setting : " + s[0] + " in submissions**") except IndexError: await client.send_message(message.channel, "!submissions") else: await client.send_message(message.channel, "!submissions") elif message.content.startswith("!open"): try: s = message.content.replace("!open", "").split() if s != "": boo = funcs.str_to_bool(s[0]) settings.db.settings.update_one( {}, {"$set": { "open": boo }}) settings.opened = boo await client.send_message( message.channel, "**Setting : " + s[0] + " in opened submissions**") except: await client.send_message(message.channel, "**Invalid command**") elif message.content.startswith("!ontour"): #chane onTour status """ This command will change the onTour status, same as !subs """ s = message.content.replace("!ontour", "").split() if s != "": boo = funcs.str_to_bool(s[0]) settings.db.settings.update_one({}, {"$set": { "onTour": boo }}) settings.onTour = boo await client.send_message( message.channel, "**Setting : " + s[0] + " in onTour**") else: await client.send_message(message.channel, "**Invalid command**") elif message.content.startswith( "!brk"): #upload new file to brackets """ This command will update the brackets, like !submit this command has to be run as a comment on the file """ try: os.system('wget -q -O ' + settings.brackets + ' ' + message.attachments[0].get('url')) await client.send_message(message.channel, "**Brackets updated**") except: await client.send_message( message.channel, "**Error while uploading the brackets**") elif message.content.startswith("!time"): """ This command will change the submissions time """ t = message.content.replace("!time", "") if t != "": settings.db.settings.update_one({}, {"$set": { "timeSub": t }}) settings.timeSub = t await client.send_message( message.channel, "**Setting : " + t + " in timeSub**") else: await client.send_message(message.channel, "**Invalid command**") elif message.content.startswith("!embed"): try: content = message.content.split()[1:] t = [] for w in content: if w == "|": break else: t.append(w) title = ' '.join(t) content = ' '.join(content[len(t) + 1:]) embed = discord.Embed(title=title, description=content, color=0xffae00) embed.set_thumbnail( url= "https://raw.githubusercontent.com/Splinter0/Tournament-Environment/master/imgs/logo.png" ) await client.send_message(message.channel, embed=embed) await client.delete_message(message) except: await client.send_message(message.channel, "**Invalid command**") elif message.content.startswith("!schedule"): """ This command will add a match to the scheduled matches """ try: r = message.content.split()[1] if r == "clear": settings.db.settings.update( {}, {"$unset": { "matches": {} }}) settings.db.settings.update({}, { "$set": { "matches": { "placeholder": ["placeholder"] } } }) await client.send_message( message.channel, "**Cleared schedule successfully**") else: pp = [] for p in message.raw_mentions: pp.append(str(server.get_member(p))) mode = "1v1" if message.content.split()[-1] == "2v2": if len(pp) == 1: for i in range(3): pp.append(pp[0]) elif len(pp) == 2: for i in range(2): pp.append(pp[i]) elif len(pp) == 3: pp.append(pp[-1]) elif len(pp) > 4: raise IndexError mode = "2v2" else: if len(pp) == 1: pp.append(pp[0]) elif len(pp) == 3: pp.append(pp[-1]) mode = "4FFA" elif len(pp) == 4: mode = "4FFA" name = "**" + mode + "**: " if mode == "2v2": name += pp[0] + "**-**" + pp[2] + "**VS**" + pp[ 1] + "**-**" + pp[3] elif mode == "4FFA": name += pp[0] + "**VS**" + pp[1] + "**VS**" + pp[ 2] + "**VS**" + pp[3] elif mode == "1v1": name += pp[0] + "**VS**" + pp[1] try: settings.matches[r].append(name) except: settings.matches.update({r: [name]}) settings.db.settings.update_one( {}, {"$set": { "matches": settings.matches }}, upsert=True) await client.send_message( message.channel, "**Scheduled match successfully**") importlib.reload(settings) except Exception as e: print(str(e)) await client.send_message(message.channel, "**Invalid command**") elif message.content.startswith("!handler"): try: command = message.content.split()[1] if command == "start": if funcs.checkPulse(): await client.send_message( message.channel, "**Handler already running**") else: funcs.manageHandler() await client.send_message( message.channel, "**Handler starting up...**") elif command == "stop": if not funcs.checkPulse(): await client.send_message( message.channel, "**Handler is not running!**") else: funcs.manageHandler(start=False) await client.send_message( message.channel, "**Handler going down...**") elif command == "restart": await client.send_message(message.channel, "**Restarting handler...**") if not funcs.checkPulse(): funcs.manageHandler() await client.send_message( message.channel, "**Handler starting up...**") else: funcs.manageHandler(start=False) await client.send_message( message.channel, "**Handler going down...**") funcs.manageHandler() await client.send_message( message.channel, "**Handler starting up...**") else: await client.send_message(message.channel, "**Invalid command**") except IndexError or KeyError: await client.send_message(message.channel, "**Invalid command**") except Exception as e: s = funcs.log(str(e)) await client.send_message( discord.utils.get(client.get_all_channels(), server__name=settings.serverName, name='halite'), s)
server__name=settings.serverName, name='general'), "Welcome " + member.mention + " to Halite Tournaments! Check out the section " + channel.mention + " for information about the upcoming tournaments! " + settings.emojis["logo"]) if __name__ == '__main__': try: #Custom settings if you want to run handler on different user handler = subprocess.Popen("python3 " + settings.path + "/handler.py", shell=True) handlerRunning = True client.run(settings.token) except KeyboardInterrupt: print("\nExiting...") handler.terminate() os._exit(1) except discord.errors.LoginFailure: if settings.token is None or settings.token == "": print("\nYou need to register a token in the database!") else: print("\nToken insered is not valid!") handler.terminate() os._exit(1) except Exception as e: funcs.log(str(e))
def casino(chat_id: int, data: dict) -> None: try: bot.unpin_chat_message(chat_id) except Exception: log('Error in unpin casino', 'Warning') nums = [num for num in range(0, 37)] start = random.randint(0, 32) msg_res[chat_id] = bot.send_message( chat_id, f'[{get_color(nums.pop(start))}] [{get_color(nums.pop(start))}] ' f'➡️[{get_color(nums.pop(start))}]⬅️ [{get_color(nums.pop(start))}] ' f'[{get_color(nums.pop(start))}]') for num in nums[start:-1 if start > 22 else start + 10]: time.sleep(0.75) text = msg_res[chat_id].text.replace('➡️', '').replace( '⬅️', '').replace('[', '').replace(']', '').split()[1:] text.append(get_color(num)) msg_res[chat_id] = bot.edit_message_text( f'[{text[0]}] [{text[1]}] ➡️[{text[2]}]⬅️ [{text[3]}] [{text[4]}]', msg_res[chat_id].chat.id, msg_res[chat_id].message_id) if len(nums) - start < 10: for num in nums[:10 - (len(nums) - start)]: time.sleep(0.75) text = msg_res[chat_id].text.replace('➡️', '').replace( '⬅️', '').replace('[', '').replace(']', '').split()[1:] text.append(get_color(num)) msg_res[chat_id] = bot.edit_message_text( f'[{text[0]}] [{text[1]}] ➡️[{text[2]}]⬅️ [{text[3]}] [{text[4]}]', msg_res[chat_id].chat.id, msg_res[chat_id].message_id) text = msg_res[chat_id].text.split()[2].replace("➡️[", "").replace("]⬅️", "") bid = get_bid_size(db.get_all_from(chat_id)) for user_id, bids in data.items(): summary[user_id] = 0 for type_, count in bids.items(): if text == '0️⃣' and type_ == '0' or text != '0️⃣' and (type_.isdigit() and text[-1].isdigit()) and \ text == get_color(int(type_)): summary[user_id] += (count * bid["simple_bid"]) * 27 db.change_karma(user_id, '+', (count * bid["simple_bid"]) * 27) elif text != '0️⃣' and (type_ == 'even' and int(text[:-1]) % 2 == 0) \ or (type_ == 'not_even' and int(text[:-1]) % 2 != 0) \ or (type_ == 'red' and text[-1] == '🔴') or (type_ == 'black' and text[-1] == '⚫'): summary[user_id] += count * bid["upper_bid"] db.change_karma(user_id, '+', (count * bid["upper_bid"])) else: if type_ == 'red' or type_ == 'black' or type_ == 'even' or type_ == 'not_even': summary[user_id] -= count * bid["upper_bid"] db.change_karma(user_id, '-', (count * bid["upper_bid"])) else: summary[user_id] -= count * bid["simple_bid"] db.change_karma(user_id, '-', (count * bid["simple_bid"])) list_d = list(summary.items()) list_d.sort(key=lambda i: i[1], reverse=True) users_text = '<i><b>Результаты</b></i>\n' + ''.join( f'<b>{db.get_from(user_id, "Users_name")}</b> <i>{"+" if res > 0 else ""}{res}</i> очков\n' for user_id, res in list_d) bot.edit_message_text( f'{msg_res[chat_id].text}\n\nВыпало <b>{text}</b>\n\n{users_text}', msg_res[chat_id].chat.id, msg_res[chat_id].message_id, parse_mode='HTML') summary.clear() try: del chips_msg[chat_id] del msg_res[chat_id] del chips_data[chat_id] except KeyError: log('Can\'t delete key in storage ', 'warning')
def daily_roulette(): global start_msg keyboard: InlineKeyboardMarkup = InlineKeyboardMarkup() keyboard.add(InlineKeyboardButton('36🔴', callback_data='roulette 36'), InlineKeyboardButton('35⚫', callback_data='roulette 35'), InlineKeyboardButton('34🔴', callback_data='roulette 34')) keyboard.add(InlineKeyboardButton('33⚫', callback_data='roulette 33'), InlineKeyboardButton('32🔴', callback_data='roulette 32'), InlineKeyboardButton('31⚫', callback_data='roulette 31')) keyboard.add(InlineKeyboardButton('30🔴', callback_data='roulette 30'), InlineKeyboardButton('29⚫', callback_data='roulette 29'), InlineKeyboardButton('28⚫', callback_data='roulette 28')) keyboard.add(InlineKeyboardButton('27🔴', callback_data='roulette 27'), InlineKeyboardButton('26⚫', callback_data='roulette 26'), InlineKeyboardButton('25🔴', callback_data='roulette 25')) keyboard.add(InlineKeyboardButton('24⚫', callback_data='roulette 24'), InlineKeyboardButton('23🔴', callback_data='roulette 23'), InlineKeyboardButton('22⚫', callback_data='roulette 22')) keyboard.add(InlineKeyboardButton('21🔴', callback_data='roulette 21'), InlineKeyboardButton('20⚫', callback_data='roulette 20'), InlineKeyboardButton('19🔴', callback_data='roulette 19')) keyboard.add(InlineKeyboardButton('18🔴', callback_data='roulette 18'), InlineKeyboardButton('17⚫', callback_data='roulette 17'), InlineKeyboardButton('16🔴', callback_data='roulette 16')) keyboard.add(InlineKeyboardButton('15⚫', callback_data='roulette 15'), InlineKeyboardButton('14🔴', callback_data='roulette 14'), InlineKeyboardButton('13⚫', callback_data='roulette 13')) keyboard.add(InlineKeyboardButton('12🔴', callback_data='roulette 12'), InlineKeyboardButton('11⚫', callback_data='roulette 11'), InlineKeyboardButton('10⚫', callback_data='roulette 10')) keyboard.add(InlineKeyboardButton('9🔴', callback_data='roulette 9'), InlineKeyboardButton('8⚫', callback_data='roulette 8'), InlineKeyboardButton('7🔴', callback_data='roulette 7')) keyboard.add(InlineKeyboardButton('6⚫', callback_data='roulette 6'), InlineKeyboardButton('5🔴', callback_data='roulette 5'), InlineKeyboardButton('4⚫', callback_data='roulette 4')) keyboard.add(InlineKeyboardButton('3🔴', callback_data='roulette 3'), InlineKeyboardButton('2⚫', callback_data='roulette 2'), InlineKeyboardButton('1🔴', callback_data='roulette 1')) keyboard.add(InlineKeyboardButton('0️⃣', callback_data='roulette 0')) keyboard.add(InlineKeyboardButton('🔴', callback_data='roulette red'), InlineKeyboardButton('⚫', callback_data='roulette black')) keyboard.add( InlineKeyboardButton('2️⃣', callback_data='roulette even'), InlineKeyboardButton('1️⃣', callback_data='roulette not_even')) time_end = str(dt.now() + timedelta(minutes=60.0)).split()[-1].split(':') for chat in db.get_id_from_where('Setting', 'roulette', 'On'): data = db.get_from(chat['id'], 'Setting') users_alert = '<b><i>Добро пожаловать в казино</i></b>🌃😎\n' if data['alert'] == 'On': users = db.get_all_from(chat['id']) users_alert += ''.join( f'<b>@{user["username"]}</b>, ' if len(users) != en else f'<b>@{user["username"]}</b>\n' for en, user in enumerate(users, 1) if user['username'] != 'None') bid = get_bid_size(db.get_all_from(chat['id'])) try: start_msg[chat['id']] = bot.send_message( chat['id'], f'{users_alert}' f'Ставки <b>{bid["simple_bid"]}</b>\<b>{bid["upper_bid"]}</b> очков\n' f'Конец в <b>{time_end[0]}:{time_end[1]}</b>\n' f'Правила <b>/casino_rule</b>', reply_markup=keyboard, parse_mode='HTML') bot.pin_chat_message(chat['id'], start_msg[chat['id']].message_id, disable_notification=True) except Exception: log('Error in daily roulette', 'error') else: Timer(3601.0, play_roulette).start()
async def on_message(message): try : if message.content.startswith("!submit"): """ This command submits a player's bot when submissions are opened. This command can be run in `battles`, `season-*` and via PMs to the bot. This command adds a queue to the handler, the handler then picks up the queue from the database and : - Checks if it's a valid submission - If the user isn't already running something - Installs external libraries (if required) - Compiles the code (if required) - Runs a test game against itself to make sure it works - Sends logs and compiler outputs via DM to the player """ if not settings.submit : #if the submissions are closed await client.delete_message(message) await client.send_message(message.channel, "**Submissions are closed at the moment!** "+message.author.mention) else: if str(message.channel) != "season-"+settings.season and str(message.channel) != "battles": #if message is in the wrong channel await client.delete_message(message) await client.send_message(message.channel, "**Cannot use this command in this channel!** "+message.author.mention) else: try: await client.send_message(message.channel, "`Submitting, compiling and testing your bot...` "+message.author.mention) response, compileLog = await funcs.uploadBot(message.attachments[0].get('url'), str(message.author), message.attachments[0].get('filename')) await client.delete_message(message) await client.send_message(message.channel, "`"+response+"` "+message.author.mention) if compileLog != "": #if compiled and run successfully await client.send_message(message.author, "**Here your compile and run log for yout bot submission!**") await client.send_file(message.author, compileLog) except IndexError : #no attachments present await client.send_message(message.channel, "`No attachment present!` "+message.author.mention) elif message.content.startswith("!submissions"): #check submissions """ This command shows the current status of submissions. Depending on the status the message changes, this command also shows when the submissions will close/open """ if settings.submit: s, s2 = "opened", "close" else : s, s2 = "closed", "open" await client.send_message(message.channel, "**Current status of submissions : "+s+", the submissions will "+s2+" : "+settings.timeSub+"**") elif message.content.startswith("!help"): #help function """ This command simply prints the name of all other commands with a brief explaination """ text = "```\n" for k,c in sorted(commands.items()): text += k + " : " + c + "\n" text += "```" await client.send_message(message.channel, text) elif message.content.startswith("!rules"): #print info about the tournament """ This command prints all the information about the tournament such as : dates, rules and prizes """ if settings.onTour: try : with open(settings.infos, "r") as f: infos = f.read() infos = infos.replace("\\n","\n") await client.send_message(message.channel, infos) except FileNotFoundError: await client.send_message(message.channel, "**Rules for current tournament are not ultimated!**") else: await client.send_message(message.channel, "**No tournament currently ongoing!**") elif message.content.startswith("!matches"): #check upcoming matches """ This command allows everyone to check the upcoming matches. A player can also run : !matches @Splinter And this will return all the games that Splinter is in """ if settings.onTour: #if we are running in a tournament m = str(message.content).split() if len(m) == 1: #check all matches text = "**Here are the upcoming matches!**\n\n" for k,v in sorted(settings.matches.items()): text += "**" + k + "** : \n" for p in v: text += "\t" + p + "\n" else: #check specific matches for player t = "" player = "" try : player = str(message.mentions[0]) except IndexError: text = "**Wrong formatting! Check `!help` for more info**" if player != "": for k,v in sorted(settings.matches.items()): for p in v: if player in p: t += "**" + k + "** : \n" t += "\t" + p + "\n" if t != "": text = "**Here are all the matches of : "+m[1]+"**\n"+t elif player != "" and t == "" : text = "**No matches scheduled for : "+m[1]+" !**" else : text = "**No scheduled matches!**" await client.send_message(message.channel, text) elif message.content.startswith("!battle"): """ This command allows the players to battle against themselves whenever they want when there's an ongoing tournament. This feature is to allow the players to try out the game environment and debug their bots properly. It also has an integration with our bot Vegas which allows the player to hide the results and then close the bets for a certain game. Example of a command : !battle @Splinter @FrankWhoee 292 180 bet This command starts a game between FrankWhoee and Splinter with a map size of 292x180, also setting up a bet. """ #if we are in a tournament and in the right channel if settings.onTour and str(message.channel) == "battles" : try: #get the two players from mentions p1 = str(message.mentions[0]) try: p2 = str(message.mentions[1]) except : p2 = str(message.mentions[0]) bet = False try : #get the map sizes width = message.content.split()[3] height = message.content.split()[4] try: if message.content.split()[5] == "bet": bet = True except: pass except : #if there is a problem set default size await client.send_message(message.channel, "*Using default size map : 240x160*") width = "240" height = "160" await client.send_message(message.channel, "*Running battle...* <:logo:416779058924355596>") status, result, log1, log2, replay = await funcs.battle(p1, p2, width, height, False) global haliteVegas if haliteVegas != None and bet: await client.send_message(haliteVegas, "!create "+message.mentions[0].mention+" "+message.mentions[1].mention) await client.send_message(message.channel, status) if result != "": #if we have an output if haliteVegas != None and bet and status.startswith("**Battle ran successfully"): global res results.update({str(res):{"author":str(message.author), "result":result, "battle":p1+"VS"+p2}}) result = "**Hiding results until bet isn't closed, check output and close with !result "+str(res)+"**" res += 1 await client.send_message(message.channel, result) if replay != "" and not bet: await client.send_file(message.channel, replay) #check if logs are present and send them if log1 != "": await client.send_message(message.mentions[0], "**Here is the logfile of your bot : (timstamp battle : "+funcs.getTime()+")**") await client.send_file(message.mentions[0], log1) os.remove(log1) if log2 != "": await client.send_message(message.mentions[1], "**Here is the logfile of your bot : (timstamp battle : "+funcs.getTime()+")**") await client.send_file(message.mentions[1], log2) os.remove(log2) except IndexError : #formatting error await client.send_message(message.channel, "**Bad formatting! Run !help for info about commands**") elif str(message.channel) != "battles": #wrong channel! battles = discord.utils.get(client.get_all_channels(), server__name=settings.serverName, name='battles') await client.send_message(message.channel, "**Run this in the "+battles.mention+" channel!**") else: #tournament is closed await client.send_message(message.channel, "**Feature not avaible at the moment!**") elif message.content.startswith("!results"): """ Command to show all the battles that are opened to bets. """ if len(results.items()) > 0: text = "**Here are all battles open to bets!**\n```\n" for num, r in results.items(): text += "- Number : "+num+", battle is "+r.get("battle")+"\n" text += "```" else: text = "**No battle with active bet at the moment!**" await client.send_message(message.channel, text) elif message.content.startswith("!result"): """ Command to show the result of a battle opened to bets, and close the bets """ #TODO Add vegas interaction try: n = message.content.split()[1] text = "" for num, r in results.items(): if r.get("author") == str(message.author) : if num == n: text = "**Here are the results of the battle n."+str(n)+":** \n"+r.get("result") del results[num] break else: text = "**No battle with bet for number "+str(n)+"**" else: text = "**No battle with bet created by you!**" await client.send_message(message.channel, text) except IndexError : #formatting error await client.send_message(message.channel, "**Bad formatting! Run !help for info about commands**") elif message.content.startswith("!players"): """ This command allows to see all the players partecipating in this season and their submission status. (submitted/not) """ pass elif message.content.startswith("!brackets"): #get current brackets """ Sends the current brackets for the season """ if settings.onTour: try: await client.send_file(message.channel, settings.brackets) except: await client.send_message(message.channel, "**Brackets are not up yet!**") else : #if no tournament is running await client.send_message(message.channel, "**No tournament currently ongoing!**") elif message.content.startswith("!languages"): #send all supported languages """ This command outputs all the languages that are currently supported. To check in specific a language : !languages python This will output the command used to compile the player's code, the command used to install the external libraries and the command used to run a test game """ m = message.content.split() if len(m) == 1: t = "**Here are the languages supported for your bot:**\n\n" for l in sorted(funcs.languages.keys()): t += l+", " t += "\n\nIf your language is **not supported** compile it in a `MyBot` file, or dm Splinter if you have problems" else: t = "" for k,v in funcs.languages.items(): if m[1] == k: if v[1] == "" : v[1] = "Not necessary" t += "**File extension : **`"+v[0]+"`, **Compile command : **`"+v[1]+"`, **Run command : **`"+v[2]+"`" if m[1] == "python": t+= "\n\n**External libraries installation command : **`pip3 install -r requirements.txt`" elif m[1] == "go": t += "\n\n**External libraries have to be included in your zip file properly**" elif m[1] == "javascript": t+= "\n\n**External libraries installation command : **`npm install`, which requires a **package.json** file!" break if t == "": t = "**Language not supported!**" await client.send_message(message.channel, t) elif message.content.startswith("!donations"): """ This command prints information on how to donate to this project """ text = "Donations are used to help support Halite Tournaments. We use your contributions to run our servers and give cash prizes. Donate here: https://www.paypal.me/HaliteTournaments. Donating will give you the **Contributor** role which has access to the Contributors voice channel. More privileges for Contributors will be coming!" await client.send_message(message.channel, text) elif message.content.startswith("!specs"): """ This command prints the specs for the current season like : constants, map sizes and environment changes. """ try : with open(settings.specs, "r") as s: text = s.read() except FileNotFoundError: text = "**Specs for season-"+settings.season+" are still not out**" await client.send_message(message.channel, text) elif message.content.startswith("!engine"): """ This will give the players access to the code of the Halite environment used in the ongoing tournament. It will also give away a percompiled version of it. """ #TODO Add precompiled options if settings.engineLink != "" and settings.onTour: await client.send_message(message.channel, "**Here is the link containing the info for the engine : "+settings.engineLink+"**") else: await client.send_message(message.channel, "**Link still not avaible!**") #admin commands elif str(message.author) in settings.admins: """ This commands are only avaible for the members in the `admins` group """ if message.content.startswith("!type"): #make bot type in current channel """ This will send a message from HTBot """ await client.delete_message(message) await client.send_message(message.channel, str(message.content).replace("!type", "")) elif message.content.startswith("!match"): """ This command starts an official tournament match, if Vegas interaction is enabled it will also create a bet between the two players. This command will output the outcome of the games and a zip file containing all replays of the games run in the match """ if settings.onTour : try: #get the two players from mentions p1 = str(message.mentions[0]) p2 = str(message.mentions[1]) await client.send_message(message.channel, "*Running match...*") if haliteVegas != None: await client.send_message(haliteVegas, "!create "+message.mentions[0].mention+" "+message.mentions[1].mention) status, result, _, _, replay = await funcs.battle(p1, p2, "", "", True) await client.send_message(message.channel, status) if result != "": #if we have an output await client.send_message(message.channel, result) if replay != "": await client.send_file(message.channel, replay) except IndexError : #formatting error await client.send_message(message.channel, "**Bad formatting! Run !help for info about commands**") else : await client.send_message(message.channel, "**Feature not avaible at the moment!**") elif message.content.startswith("!admin"): #print admin commands """ A help command for admins """ text = "```\n" for k,c in sorted(adminCommands.items()): text += k + " : " + c + "\n" text += "```" await client.send_message(message.channel, text) elif message.content.startswith("!clear"): #delete n messages in a channel """ This command allows to delete x messages in a y channel E.g : !clear 20 battles Will delete 20 messages in the battles channel """ try : n = int(message.content.split()[1]) #number of messages ch = message.content.split()[2] #channel if ch != "*": #current channel channel = discord.utils.get(client.get_all_channels(), server__name=settings.serverName, name=ch) else : channel = message.channel await client.purge_from(channel, limit=n) except IndexError: await client.send_message(discord.utils.get(client.get_all_channels(), server__name=settings.serverName, name='halite'), "**Wrong command formatting**") elif message.content.startswith("!post"): #upload a file from server to channel """ This will upload a file from the server to the channel wanted. """ try : await client.delete_message(message) c = message.content.replace("!post", "") f, ch = c.split()[0], c.split()[1] if ch != "*": channel = discord.utils.get(client.get_all_channels(), server__name=settings.serverName, name=ch) else : channel = message.channel await client.send_file(channel, f, content=c.replace(f+" "+ch, "")) except FileNotFoundError: s = funcs.log("File "+f+" not found!") await client.send_message(discord.utils.get(client.get_all_channels(), server__name=settings.serverName, name='halite'), s) except IndexError : await client.send_message(discord.utils.get(client.get_all_channels(), server__name=settings.serverName, name='halite'), "**Wrong command formatting**") elif message.content.startswith("!subs"): #change submissions status """ This command will change the submissions status E.g. : !subs False Will close the submissions """ s = message.content.replace("!subs", "").split() if s != "": try: boo = funcs.str_to_bool(s[0]) settings.db.settings.update_one({}, {"$set":{"submit":boo}}) settings.submit = boo await client.send_message(message.channel, "**Setting : "+s[0]+" in submissions**") except IndexError : await client.send_message(message.channel, "!submissions") else : await client.send_message(message.channel, "!submissions") elif message.content.startswith("!ontour"): #chane onTour status """ This command will change the onTour status, same as !subs """ s = message.content.replace("!ontour", "").split() if s != "": boo = funcs.str_to_bool(s[0]) settings.db.settings.update_one({}, {"$set":{"onTour":boo}}) settings.onTour = boo await client.send_message(message.channel, "**Setting : "+s[0]+" in onTour**") else : await client.send_message(message.channel, "**Invalid command**") elif message.content.startswith("!brk"): #upload new file to brackets """ This command will update the brackets, like !submit this command has to be run as a comment on the file """ try : os.system('wget -q -O '+settings.brackets+' ' + message.attachments[0].get('url')) await client.send_message(message.channel, "**Brackets updated**") except: await client.send_message(message.channel, "**Error while uploading the brackets**") elif message.content.startswith("!time"): """ This command will change the submissions time """ t = message.content.replace("!time", "") if t != "": settings.db.settings.update_one({}, {"$set":{"timeSub":t}}) settings.timeSub = t await client.send_message(message.channel, "**Setting : "+t+" in timeSub**") else: await client.send_message(message.channel, "**Invalid command**") except Exception as e: s = funcs.log(str(e)) await client.send_message(discord.utils.get(client.get_all_channels(), server__name=settings.serverName, name='halite'), s)