async def emoji(text, channel): hero = aliases( text[0] ) #Emoji pages are case sensitive. Sadly, capitalizing also ruins non-hero emojis (Nexus pack etc). emojiCode = text[1].replace('lol', 'rofl').replace('wow', 'surprised') emojiPackCode = '2_' if hero in ['Nexus', 'Chomp']: emojiPackCode = '' elif emojiCode in ['happy', 'rofl', 'sad', 'silly', 'meh']: emojiPackCode = '1_' emojiCode = emojiCode.capitalize() if emojiCode == 'Rofl': emojiCode = 'ROFL' imageFormat = '.png' if hero in ['Chomp']: imageFormat = '.gif' emojiPage = 'https://heroesofthestorm.gamepedia.com/File:Emoji_' + hero + '_Pack_' + emojiPackCode + hero + '_' + emojiCode + imageFormat html = urlopen(emojiPage) bs = BeautifulSoup(html, 'html.parser') images = bs.find_all('img', {'src': re.compile(imageFormat)}) emojiImagePage = images[0]['src'] async with aiohttp.ClientSession() as session: async with session.get(emojiImagePage) as resp: if resp.status != 200: pass data = io.BytesIO(await resp.read()) await channel.send(file=discord.File(data, 'cool_image.png'))
async def printCompactBuild(client, channel, text): #bot channel: posts whole thing #outside bot channel: post formatted query and name of talents, and reacts :thumb up: #when reacted to, print whole thing build, hero = text.split(',') #Example: T0230303,DVa hero = aliases(hero) (abilities, talents) = client.heroPages[hero] build = build.replace('q', '1').replace('w', '2').replace('e', '3').replace( 'r', '4').replace('t', '5') #Check for malicious input, since the build will be repeated back for i in build[1:]: if i not in '0123456789': return if channel.id in client.botChannels.values(): await printBuild(channel, build, talents) return output = 'Talent build [T' + build[1:] + ',' + hero + ']: ' talentsToPrint = [] for j, i in enumerate(build[1:]): if i == '0': continue talentsToPrint.append( talents[j][int(i) - 1].split('**')[1].split('] ')[1].replace( ':', '')) output += ', '.join(talentsToPrint) message = await channel.send(output) await message.add_reaction('๐')
async def emoji(client, text, channel, message='NONE'): text[0] = text[0].replace(':', '').replace('~1', '') if text[0] == 'carbot': await carbotSpray(text[1], channel) return if text[0] == 'proxy': await channel.send('Use these proxied emojis with [:emojiName]') hiddenEmojis = ['wheeze', 'volumeup'] await channel.send(''.join([ i[1] for i in client.proxyEmojis.items() if i[1].split(':')[1] not in hiddenEmojis ])) return if text[0] in client.proxyEmojis: if len(text) == 2: await proxyReact(client, text, message) else: await channel.send(client.proxyEmojis[text[0]]) return if len(text) == 2: hero = aliases(text[0]).replace('_', ' ').replace('The Butcher', 'Butcher') emojiCode = text[1].replace('lol', 'rofl').replace( 'wow', 'surprised').replace('smile', 'happy') file = hero + ' ' + emojiCode else: file = text[0] await sendEmoji('Emojis/' + file.capitalize(), channel)
def downloadQuotes(): noQuoteOnPage = [ 'Anduin', 'Imperius', 'Mephisto', 'Murky', 'Probius', 'Qhira', 'The_Butcher', 'Whitemane' ] theirQuote = [ 'For the Alliance above all!', 'I yearn for battle.', '*(Hisses)*', 'Mrrgll', '*(Probe sounds)*', "I'm in.", 'Fresh meat!', 'Let the inquisition commence!' ] with open('Text files/quotes.txt', 'w+') as f: for hero in getHeroes(): hero = aliases(hero) print(hero) if hero in noQuoteOnPage: quote = theirQuote[noQuoteOnPage.index(hero)] else: page = ''.join([ i.strip().decode('utf-8') for i in urlopen( 'https://heroesofthestorm.gamepedia.com/' + hero) ]) page = page[page.index('<p><i>"') + 7:] quote = page[:page.index('"')] output = hero + '; ' + quote f.write(output + '\n')
async def carbotSpray(hero, channel): hero = aliases(hero) imageFormat = '.gif' if hero == 'Deflect': hero = 'Ninja_Skills' elif hero == 'Parry': hero = "Paryin'_with_Varian" elif hero == 'Evade': hero = 'Evade_This...' elif hero == 'Haha': hero = 'Ha_HA_ha_HA!' elif hero == 'Sleep': hero = 'Sleeping_Dragon' elif hero == 'Shield': hero = "Can't_Touch_This" else: hero = 'Carbot_' + hero imageFormat = '.png' emojiPage = 'https://heroesofthestorm.gamepedia.com/File:' + hero + '_Spray' + imageFormat html = urlopen(emojiPage) bs = BeautifulSoup(html, 'html.parser') images = bs.find_all('img', {'src': re.compile(imageFormat)}) emojiImagePage = images[1 if imageFormat == '.gif' else 2]['src'] async with aiohttp.ClientSession() as session: async with session.get(emojiImagePage) as resp: if resp.status != 200: pass data = io.BytesIO(await resp.read()) await channel.send(file=discord.File(data, 'cool_image' + imageFormat))
async def printBuild(client, channel, text): build, hero = text.split(',') #Example: T0230303,DVa hero = aliases(hero) (abilities, talents) = client.heroPages[hero] build = build.replace('q', '1').replace('w', '2').replace('e', '3').replace( 'r', '4').replace('t', '5') output = [] for j, i in enumerate(build[1:]): if i == '0': continue output.append(talents[j][int(i) - 1]) await printLarge(channel, '\n'.join(output))
async def patchNotes(channel,text): if len(text)!=2: await channel.send('Use with [patchnotes/hero,X], where X is number of patches ago, or a search term.') return async with channel.typing(): text=text[1] splitText=text.split(',') hero=aliases(splitText.pop(0)).replace('รบ','u').lower().translate({ord(i):None for i in "' _-."}).replace('thebutcher','butcher') async with aiohttp.ClientSession() as session: page = await fetch(session, 'https://heroespatchnotes.com/hero/'+hero+'.html') patches=page.split('<h3>') if splitText: text=splitText.pop(0) if text.isdigit(): if int(text)<len(patches): patch=patches[int(text)] else: await channel.send("The hero doesn't have "+text+' patches yet.') return else: for trialPatch in patches[1:]: if text.lower() in trialPatch.lower(): patch=trialPatch break else: await channel.send('That has never been changed!') return else: patch=patches[1] remove=['<small class="hidden-xs">',' ','<li>','<p>','<em>','</li>','</p>','</em>','</ul>','<blockquote>','</blockquote>','<span class="text-warning">','amp;'] for i in remove: patch=patch.replace(i,'') output='**'+patch.split('<')[0]+'**' #Date and version patch='>'.join(patch.split('<h4')[1].split('>')[1:]) #output+=patch.split('<')[0]+':' #Type (bug fix, hero update) patch='>'.join(patch.split('>')[1:]) patch=patch.split('</div>')[0] patch=patch.replace('\n',' ').replace('<strong>Developer Comment:</strong> ','\n***Developer Comment***: *').replace('<strong>','\n**').replace('</strong>',':** ').replace('<ul>',' ') patch=patch.replace('\n**Talents:**','').replace('\n**Abilities:**','').replace('**Stats:**','').replace(' Health Regen ',', Health Regen ') if '</span> <a class="label label-warning"' in patch:#Undocumented HTML patch=patch.split('</span> <a class="label label-warning"') patch='\n'.join([patch[0]]+[i.split('Undocumented <i class="fa fa-external-link"></i></a> ')[1] for i in patch[1:]]) output+=patch if 'Developer Comment' in output: output=output.strip()+'*' await printLarge(channel,output)
def emoji(text): hero = aliases( text[0] ) #Emoji pages are case sensitive. Sadly, capitalizing also ruins non-hero emojis (Nexus pack etc). emojiCode = text[1].replace('lol', 'rofl').replace('wow', 'surprised') emojiPackCode = '2' if emojiCode in ['happy', 'rofl', 'sad', 'silly', 'meh']: emojiPackCode = '1' emojiCode = emojiCode.capitalize() if emojiCode == 'Rofl': emojiCode = 'ROFL' emojiPage = 'https://heroesofthestorm.gamepedia.com/File:Emoji_' + hero + '_Pack_' + emojiPackCode + '_' + hero + '_' + emojiCode + '.png' html = urlopen(emojiPage) bs = BeautifulSoup(html, 'html.parser') images = bs.find_all('img', {'src': re.compile('.png')}) emojiImagePage = images[0]['src'] e = discord.Embed() e.set_image(url=emojiImagePage) return e
async def mainProbius(client, message, texts): global exitBool for draftAlias in draftAliases: #Don't want to log draft commands because they really spam. if 'new' in message.content.lower(): continue if '[' + draftAlias + '/' in message.content.lower(): break else: #The elusive for else control flow guildname = message.channel.guild.name guildname = 'Nexus school' if guildname == 'Nexus Schoolhouse' else guildname #Nexus Schoolhouse is too long guildname = 'Schuifpui' if guildname == 'De Schuifpui Schavuiten' else guildname channelName = message.channel.name channelName = 'hots' if channelName == 'heroes-got-canceled' else channelName loggingMessage = guildname + ' ' * ( 15 - len(guildname)) + channelName + ' ' + ' ' * ( 17 - len(channelName)) + str(message.author.name) + ' ' * ( 18 - len(str(message.author.name))) + ' ' + message.content print(loggingMessage) await client.get_channel(DiscordChannelIDs['LoggingChannel'] ).send('`{}`'.format(loggingMessage)) for text in texts: command = text[0].replace(' ', '') if command in ['trait', 'r', 'w', 'e', 'passive', 'react', '...']: #Do nothing continue if command in ['scaling']: await message.channel.send( 'https://cdn.discordapp.com/attachments/741762417976934460/906568639304585247/unknown.png' ) continue if command in ['time', 't']: await countdown(message, text) continue if command in randomBuildAliases and len(text) == 2: await randomBuild(client, message.channel, aliases(text[1])) continue if command in coachingAliases: await coaching(message) return if command in ['avatarcolour', 'avatarcolor']: #Hogs CPU resources #await avatarColour(client,message.channel,text[1]) continue if command in ['event', 'season']: await event(message.channel) continue if command in ['armor', 'armour', 'ehp']: await message.channel.send( 'https://cdn.discordapp.com/attachments/741762417976934460/801905601809612821/unknown.png' ) continue if command == 'hoggerangles': await message.channel.send( 'https://editor.p5js.org/Asddsa76/sketches/CmGYMS2j1') continue if command in ['schedule', 'patchschedule']: await schedule(message) continue if command == 'sortlist': if message.guild.get_role(DiscordRoleIDs['Olympian'] ) not in message.author.roles: #Not mod await message.channel.send(message.author.mention + ' <:bonk:761981366744121354>') else: await sortList(message) continue if command in ['name', 'names', 'n']: names = [ (i.nick or i.name) + (' (' + i.name + ')') * int(bool(i.nick)) for i in message.guild.members if text[1].lower() in i.name.lower() or i.nick and text[1].lower() in i.nick.lower() ] await message.channel.send('\n'.join(names) + '\n' + str(len(names)) + ' ' + text[1].capitalize() + 's') continue if command in heroAliases + [i + 's' for i in heroAliases]: await heroes(message, text, message.channel, client) continue if command == 'ping': await ping(message.channel) continue if command == 'membercount': await memberCount(message.channel) continue if command in confidenceAliases: await confidence(message.channel, text) continue if command == 'exit' and message.author.id == DiscordUserIDs['Asddsa']: exitBool = 1 await client.close() if command in restartAliases: exitBool = 0 await client.logout() if command in mapImageAliases: await mapImage(message.channel, text[1]) continue if command == 'core': await coreAbilities(message.channel, await mapAliases(text[1])) continue if command in listAliases: await waitList(message, text, client) continue if command in lfgAlises: await lfg(message.channel, text[1], client) continue if command in deleteAliases: await deleteMessages(message.author, text[1], client) continue if command in patchNotesAliases: await patchNotes(message.channel, text) continue if command in talentAliases: await message.channel.send( "Call a hero's talent tier with [hero/level]") continue if command in updatePokedexAliases: if client.isEditingPokedex: await message.channel.send( 'Please wait, the pokedex is already being edited!') continue client.isEditingPokedex = 1 await updatePokedex(client, text, message) client.isEditingPokedex = 0 continue if command in rollAliases: await roll(text, message) continue if command == 'sort': await sortFromMessage(text[1], message, client) continue if command in pokedexAliases: await pokedex(client, message.channel, aliases(text[1])) continue if command == ':disapproval': await message.channel.send('ะฏโะฐ_ะฏโะฐ') continue if command in [':summon', 'summon']: if len(text) == 1: await message.channel.send('ะฏโโ ัะั ะ ะะ\_ะ ะะ ะฏโะนัะั') elif '@' in text[1]: await message.channel.send( '{0} {0} Summon {1}! {0} {0}'.format( 'ะฏโโ ัะั ะ ะะ\_ะ ะะ ะฏโะนัะั', message.author.mention)) else: await message.channel.send( '{0} {0} Summon {1}! {0} {0}'.format( 'ะฏโโ ัะั ะ ะะ\_ะ ะะ ะฏโะนัะั', message.content.split('[')[1].split('/')[1].split(']') [0])) #text[1] is all lowercase etc. continue if command in colourAliases: await message.channel.send(file=discord.File('WS colours.png')) continue if message.author.id == DiscordUserIDs[ 'Asddsa'] or message.author.id == DiscordUserIDs['MindHawk']: if command == 'serverchannels': await message.channel.send([ channel.name for channel in message.channel.guild.channels ]) continue if command == 'repeat' and len(text) == 2: await message.channel.send( message.content.split('[')[1].split('/')[1].split(']')[0] ) #text[1] is all lowercase await message.delete() continue if command == 'unsorted' and message.channel.guild.name == 'Wind Striders': if DiscordRoleIDs['Olympian'] in [ role.id for role in message.author.roles ]: #Olympian channel = client.get_channel( DiscordChannelIDs['General']) #WSgeneral role = channel.guild.get_role( DiscordRoleIDs['Unsorted']) #UNSORTED rulesChannel = channel.guild.get_channel( DiscordChannelIDs['ServerRules']) #server-rules await channel.send('Note to all ' + role.mention + ': ' + client.welcomeMessage) await channel.send( content= 'https://cdn.discordapp.com/attachments/576018992624435220/743917827718905896/sorting.gif', file=discord.File('WS colours.png')) continue if command == 'byprobiusbepurged' and message.channel.guild.name == 'Wind Striders': if DiscordRoleIDs['Olympian'] in [ role.id for role in message.author.roles ]: people = [ i for i in message.channel.guild.members if DiscordRoleIDs['Unsorted'] in [role.id for role in i.roles] ] for person in people: await message.channel.guild.kick( person, reason='Did not sort in time!') continue if command == 'vote': await vote(message, text) continue if command in coinsAliases: await message.channel.send(random.choice(['Heads', 'Tails'])) continue if command in redditAliases: await reddit(client, message, text) continue if command in ['avatar', 'a']: await message.channel.send(await getAvatar(client, message.channel, text[1])) continue if command == '': #Empty string. Aliases returns Abathur when given this. continue if command in draftAliases: await draft(drafts, message.channel, message.author, text, lastDraftMessageDict, draftNames) continue if command in randomAliases: if len(text) == 1: await message.channel.send(getQuote(random.choice(getHeroes())) ) continue command = random.choice(getHeroes()) if command in helpAliases: if len(text) == 2 and command in heroStatsAliases: #[info/hero] await heroStats(aliases(text[1]), message.channel) else: await message.channel.send(helpMessage()) continue if command in buildsAliases: if len(text) == 2: if message.channel.guild.id == DiscordGuildIDs[ 'WindStriders'] and message.channel.id != DiscordChannelIDs[ 'Probius'] and message.content[ 0] == '[': #In WS, not in #probius, first character is [ if message.guild.get_role( DiscordRoleIDs['CoreMember'] ) not in message.author.roles: #Not core member await wrongChannelBuild(message) await guide( aliases(text[1]), message.guild.get_channel( DiscordChannelIDs['Probius'])) continue await guide(aliases(text[1]), message.channel) else: await message.channel.send( "Elitesparkle's builds: <https://elitesparkle.wixsite.com/hots-builds>" ) continue if command in rotationAlises: await rotation(message.channel) continue if command == 'goodbot': await emoji(client, ['Probius', 'love'], message.channel) continue if command == 'badbot': if message.author.id in ProbiusPrivilegesIDs: await emoji(client, ['Probius', 'sad'], message.channel) else: await emoji(client, [':pylonbat'], message.channel) continue if ':' in command: await emoji(client, text, message.channel, message) continue if ']' in command: continue if command in ['chogall', "cho'gall", 'cg', 'cho gall', 'cho-gall']: await message.channel.send( "Cho and Gall are 2 different heroes. Choose one of them") print('Dual hero') continue if command in quotesAliases: if len(text) == 2: await message.channel.send(getQuote(aliases(text[1]))) elif text[ 0] != 'q': #Calling [q] alone shouldn't show link, but [q/hero] works, as well as [quotes] await message.channel.send( 'All hero select quotes: <https://github.com/Asddsa76/Probius/blob/master/quotes.txt>' ) continue if command in aliasesAliases: await message.channel.send( 'All hero alternate names: <https://github.com/Asddsa76/Probius/blob/master/aliases.py>' ) continue if command == 'all': await printAll(client, message, text[1], True) continue if command in emojiAliases: await message.channel.send( 'Emojis: [:hero/emotion], where emotion is of the following: happy, lol, sad, silly, meh, angry, cool, oops, love, or wow.' ) continue try: if len(text) == 1 and command[0] == 't' and command[ 8] == ',': #[t3221323,sam] await printCompactBuild(client, message.channel, command) continue if len(text) == 2 and command[0] == 't' and len( command) == 8 and command != 'tassadar': #[t3221323/sam] await printCompactBuild(client, message.channel, ','.join(text)) continue except: pass #From here it's actual heroes, or a search hero = command if len(hero) == 1 or ( len(hero) == 2 and ('1' in hero or '2' in hero) ): #Patch notes have abilities in []. Don't want spammed triggers again. Numbers for R1, R2, etc. continue hero = aliases(hero) if len(text) == 2: #If user switches to hero first, then build/quote if text[1] in buildsAliases: if message.channel.guild.id == DiscordGuildIDs[ 'WindStriders'] and message.channel.id != DiscordChannelIDs[ 'Probius']: #In WS, not in #probius if message.guild.get_role( DiscordRoleIDs['CoreMember'] ) not in message.author.roles: #Not core member await wrongChannelBuild(message) await guide( hero, message.guild.get_channel( DiscordChannelIDs['Probius'])) continue await guide(hero, message.channel) continue if text[1] in quotesAliases and text[1] != 'q': await message.channel.send(getQuote(hero)) continue if text[1] in heroStatsAliases: await heroStats(hero, message.channel) continue try: (abilities, talents) = client.heroPages[hero] except: try: #If no results, then "hero" isn't a hero await printAll(client, message, text[0]) except: pass continue output = '' try: tier = text[ 1] #If there is no identifier, then it throws exception if tier in randomAliases: await message.channel.send( printTier(talents, random.randint(0, 6))) continue if tier in randomBuildAliases: await randomBuild(client, message.channel, hero) continue except: quote = getQuote(hero) output = '\n'.join(abilities) await printLarge(message.channel, quote + output) await heroStats(hero, message.channel) continue if output == '': if ',' in tier and any(i in tier for i in talentAliases): await printAbilityTalents(message, abilities, talents, tier.split(',')[0], hero) continue if tier.isdigit(): #Talent tier tier = int(tier) output = printTier( talents, int(tier / 3) + int(hero == 'Chromie' and tier not in [1, 18]) ) #Talents for Chromie come 2 lvls sooner, except lvl 1 elif tier in ['mount', 'z']: await message.channel.send(printAbility(abilities, 'z')) continue elif tier == 'extra': await message.channel.send(printAbility(abilities, '1')) continue elif tier == 'r': #Ultimate if hero == 'Tracer': #She starts with her heroic already unlocked, and only has 1 heroic output = abilities[3] else: output = printTier( talents, 3 - 2 * int(hero == 'Varian')) #Varian's heroics are at lvl 4 if hero == 'Deathwing': output = abilities[ 3] + '\n' + output #Deathwing has Cataclysm baseline elif len(tier) == 1 and tier in 'dqwe': #Ability (dqwe) output = printAbility(abilities, tier) elif tier == 'trait': output = printAbility(abilities, 'd') elif tier == 'all': await printEverything(client, message, abilities, talents) return elif tier in wikipageAliases: #Linking user to wiki instead of printing everything await message.channel.send( '<https://heroesofthestorm.gamepedia.com/Data:' + hero + '#Skills>') continue else: output = await printSearch(abilities, talents, tier, hero, True) if len( output ) == 2: #If len is 2, then it's an array with output split in half if message.channel.name == 'rage': await message.channel.send(output[0].upper()) await message.channel.send(output[1].upper()) else: await message.channel.send(output[0]) await message.channel.send(output[1]) else: if message.channel.name == 'rage': output = output.upper() try: await message.channel.send(output) except: if output == '': try: #If no results, it's probably an emoji with : forgotten. Prefer to call with : to avoid loading abilities and talents page await emoji(client, [hero, tier], message.channel) continue except: pass if message.channel.name == 'rage': await message.channel.send( 'ERROR: {} DOES NOT HAVE "{}".'.format( hero, tier).upper()) else: await message.channel.send( 'Error: {} does not have "{}".'.format(hero, tier)) print('No results') else: if message.channel.name == 'rage': await printLarge(message.channel, output.upper()) else: await printLarge(message.channel, output)
async def updatePokedex(client, text, message): if 557521663894224912 not in [role.id for role in message.author.roles]: await message.channel.send( 'You need to be a mod to update the Pokedex!') return if len(text) != 2: await message.channel.send('Syntax is [updatepokedex/hero, ping].') return heroPing = text[1].split(',') if len(heroPing) != 2: await message.channel.send('Syntax is [updatepokedex/hero, ping].') return if heroPing[0] in ['remove', 'delete', 'all']: await removePokedex( client, heroPing[1].replace(' ', '').replace('!', '')[2:-1]) await message.channel.send( heroPing[1] + ' has been removed from all pokedex entries.') return hero = aliases(heroPing[0]) if hero not in getHeroes(): await message.channel.send('Invalid hero!') return user = heroPing[1].replace(' ', '') if '<@' not in user: await message.channel.send('Invalid ping!') return pokedex_channel = client.get_channel(597140352411107328) pokedex_messages = [] # We're unlikely to ever go above 50 messages in the pokedex. async for pokedex_message in pokedex_channel.history(limit=50): pokedex_messages.append(pokedex_message.content) pokedex_as_string = '' for pokedex_message in pokedex_messages: # Prepend the strings pokedex_as_string = pokedex_message + '\n' + pokedex_as_string # Let's update the message before splitting it hero = hero.replace('_', ' ') pokedex_as_individual_hero_strings = pokedex_as_string.split('\n') pokedex_as_individual_hero_strings_new = [] for hero_mains_string in pokedex_as_individual_hero_strings: if hero in hero_mains_string: removal = False if user in hero_mains_string: removal = True pokedex_as_individual_hero_strings_new.append( hero_mains_string.replace(' ' + user, '')) else: pokedex_as_individual_hero_strings_new.append( hero_mains_string + ' ' + user) else: pokedex_as_individual_hero_strings_new.append(hero_mains_string) # Sort the string array alphabetically. Makes sure we're always in the right order. pokedex_as_individual_hero_strings_new.sort() pokedex_as_string_array = [] i = 0 pokedex_as_string_array.append('\n') for hero_mains_string in pokedex_as_individual_hero_strings_new: if (len(pokedex_as_string_array[i] + hero_mains_string + '\n') < 2000): pokedex_as_string_array[i] += (hero_mains_string + '\n') else: i += 1 pokedex_as_string_array.append(hero_mains_string + '\n') i = (len(pokedex_as_string_array) - 1) async for pokedex_message in pokedex_channel.history(limit=50): await pokedex_message.edit(content=pokedex_as_string_array[i]) i -= 1 # We've run out of messages, do we have content left? # We're never going to add two messages from 1 edit call, no need to worry about that. if i == 0: message_to_edit = await pokedex_channel.send( 'This will be edited soon.') await message_to_edit.edit(content=pokedex_as_string_array[i]) if removal: await message.channel.send(user + ' has been removed from ' + hero) else: await message.channel.send(user + ' has been added to ' + hero)
async def downloadHero(hero, client, patch): async with aiohttp.ClientSession() as session: if patch == '': page = await fetch( session, 'https://raw.githubusercontent.com/heroespatchnotes/heroes-talents/master/hero/' + hero + '.json') #page = await fetch(session, 'https://raw.githubusercontent.com/MGatner/heroes-talents/83004/hero/'+hero+'.json') else: page = await fetch( session, 'https://raw.githubusercontent.com/MGatner/heroes-talents/' + patch + '/hero/' + hero + '.json') #client.heroPages={...'genji':[abilities,talents], ...} page = loads(page) abilities = [] if hero in ['ltmorales', 'valeera', 'deathwing', 'zarya']: resource = 'energy' elif hero == 'chen': resource = 'brew' elif hero == 'sonya': resource = 'fury' else: resource = 'mana' for i in page['abilities'].keys(): for ability in page['abilities'][i]: if 'hotkey' in ability: output = '**[' + ability['hotkey'] + '] ' else: output = '**[D] ' output += ability['name'] + ':** ' if 'cooldown' in ability or 'manaCost' in ability: output += '*' if 'cooldown' in ability: output += str(ability['cooldown']) + ' seconds' if 'manaCost' in ability: output += ', ' if 'manaCost' in ability: output += str(ability['manaCost']) + ' ' + resource output += ';* ' output += await descriptionFortmatting(ability['description']) output = await fixTooltips(hero, ability['name'], output) abilities.append(output) if hero == 'samuro': abilities.append( "**[D] Image Transmission:** *14 seconds;* Activate to switch places with a target Mirror Image, removing most negative effects from Samuro and the Mirror Image.\n**Advancing Strikes:** Basic Attacks against enemy Heroes increase Samuro's Movement Speed by 25% for 2 seconds." ) talents = [] keys = sorted(list(page['talents'].keys()), key=lambda x: int(x)) for key in keys: tier = page['talents'][key] talentTier = [] for talent in tier: output = '**[' + str( int(key) - 2 * int(hero == 'chromie' and key != '1')) + '] ' output += talent['name'] + ':** ' if 'cooldown' in talent: output += '*' + str(talent['cooldown']) + ' seconds;* ' output += await descriptionFortmatting(talent['description']) output = await fixTooltips(hero, talent['name'], output) talentTier.append(output) talents.append(talentTier) client.heroPages[aliases(hero)] = (abilities, talents)
async def on_message(self, message): #Don't respond to ourselves if message.author == self.user: return if '[' in message.content and ']' in message.content: print(message.channel.name + ' ' + str(message.author) + ': ' + message.content) text = message.content.lower() if text in ['[help]', '[info]']: await message.channel.send(helpMessage()) return elif ':' in text: await emoji( text[text.index('[') + 1:text.index(']')].replace( ':', '').split('/'), message.channel) return text = text[text.index('[') + 1:text.index(']')].split('/') hero = text[0] hero = aliases(hero) [abilities, talents] = heroAbilitiesAndTalents(hero) abilities = extraD(abilities, hero) if hero in ['Chogall', "Cho'gall", 'Cg', 'Cho gall', 'Cho-gall']: await message.channel.send( "Cho and Gall are 2 different heroes. Choose one of them") print('Dual hero') return if abilities == 404: try: #If no results, it's probably an emoji with : forgotten. Prefer to call with : to avoid loading abilities and talents page await emoji([hero, text[1]], message.channel) return except: pass output = 'No hero "' + hero + '"' if message.channel.name == 'rage': output = output.upper() await message.channel.send(output) print('No hero') return output = '' try: tier = text[ 1] #If there is no identifier, then it throws exception except: output = printAbilities(abilities) await emoji([text[0], 'happy'], message.channel) if output == '': if tier.isdigit(): #Talent tier tier = int(tier) output = printTier( talents, int(tier / 3) + int(hero == 'Chromie' and tier != 1) ) #Talents for Chromie come 2 lvls sooner, except lvl 1 elif tier == 'r': #Ultimate output = printTier( talents, 3 - 2 * int(hero == 'Varian')) #Varian's heroics are at lvl 4 elif len(tier) == 1 and tier in 'dqwe': #Ability (dqwe) output = printAbility(abilities, tier, hero) elif tier.lower() == 'trait': output = printAbility(abilities, 'd', hero) else: tier = abilityAliases(tier) output = printSearch(abilities, talents, tier, hero) if len( output ) == 2: #If len is 2, then it's an array with output split in half if message.channel.name == 'rage': await message.channel.send(output[0].upper()) await message.channel.send(output[1].upper()) else: await message.channel.send(output[0]) await message.channel.send(output[1]) else: if message.channel.name == 'rage': output = output.upper() try: await message.channel.send(output) except: if output == '': try: #If no results, it's probably an emoji with : forgotten. Prefer to call with : to avoid loading abilities and talents page await emoji([hero, tier], message.channel) return except: pass if message.channel.name == 'rage': await message.channel.send('ERROR: NO RESULTS') else: await message.channel.send('Error: no results') print('No results') else: if message.channel.name == 'rage': await message.channel.send( "ERROR: EXCEEDED DISCORD'S 2000 CHARACTER LIMIT. BE MORE SPECIFIC" ) else: await message.channel.send( "Error: exceeded Discord's 2000 character limit. Be more specific" ) print('2000 limit')
async def printDraft(drafts,channel,draftList,lastDraftMessageDict,draftNames):#Print state, and the next action to be done if channel.id not in drafts: await channel.send(channel.id+' does not currently have an active draft.') return if not draftList: await channel.send('Pick a map') return #Order and map have been picked now order='mABABabbaaBAbbaab'#map, order. AB bans, ab picks bansA=[] bansB=[] picks='' #whitespaceAmount=32 try: whitespaceAmount=await getWhiteSpaceLength(draftList,draftNames[channel.id][0]) except: whitespaceAmount=await getWhiteSpaceLength(draftList,'') teamA='Team A' teamB='Team B' try: teamA+=' ('+draftNames[channel.id][0]+')' teamB+=' ('+draftNames[channel.id][1]+')' except:pass for i in range(1,len(draftList)): if order[i]=='A': bansA.append(draftList[i]) elif order[i]=='B': bansB.append(draftList[i]) elif order[i]=='a': picks+=draftList[i]+'\n' elif order[i]=='b': picks+=' '*whitespaceAmount+draftList[i]+'\n' output='```Map: '+draftList[0]+'\n\n' output+=teamA+' '*(whitespaceAmount-len(teamA))+teamB+'\n' output+='Bans: '+' '*(whitespaceAmount-6)+'Bans: \n' output+=', '.join(bansA)+' '*(whitespaceAmount-len(', '.join(bansA)))+', '.join(bansB)+'\n'+'-'*(whitespaceAmount+15)+'\n' output+='Picks:'+' '*(whitespaceAmount-6)+'Picks:\n'+picks+'\n' completeDraft=0 if len(draftList)==17: output+='Draft complete' completeDraft=1 else: nextAction=order[len(draftList)] nextTurnIsTeamB=1 if nextAction.lower()=='a': output+='<---------- ' nextTurnIsTeamB=0 if nextAction==nextAction.upper(): nextAction='BAN for team '+nextAction else: nextAction='Pick for team '+nextAction.upper() output+='Next action: '+nextAction try: output+=' ('+draftNames[channel.id][nextTurnIsTeamB]+')' except: pass if nextTurnIsTeamB: output+=' ---------->' if len(draftList)>1: hero=aliases(draftList[-1]).replace('_',' ').replace('The Butcher','Butcher').capitalize() fileName='' fileExtension='.PNG' if hero=='Maiev' else '.png' if len(draftList) in [2,3,4,5,11,12]:#Numbers are the bans if hero in banEmojis.keys(): output=banEmojis[hero]+'\n'+output else: if channel in lastDraftMessageDict: try:await lastDraftMessageDict[channel].delete() except:pass lastDraftMessageDict[channel]=await channel.send(output+'```',file=discord.File('Emojis/'+hero+' sad'+fileExtension)) return else: if channel in lastDraftMessageDict: try:await lastDraftMessageDict[channel].delete() except:pass lastDraftMessageDict[channel]=await channel.send(output+'```',file=discord.File('Emojis/'+hero+' happy'+fileExtension)) await addCompleteReactions(completeDraft,lastDraftMessageDict[channel]) return if channel in lastDraftMessageDict: try:await lastDraftMessageDict[channel].delete() except:pass lastDraftMessageDict[channel]=await channel.send(output+'```') await addCompleteReactions(completeDraft,lastDraftMessageDict[channel])
async def draft(drafts,channel,member,text,lastDraftMessageDict,draftNames,printDraftBool=True): try: draftList=drafts[channel.id] except: drafts[channel.id]=[] draftList=drafts[channel.id] if len(text)==2: if text[1] in ['help','info']: output='''MOCK DRAFTING GUIDE [Draft] will show the current state of the draft. [Flip] will toss a coin that can be used to randomly select who will go for first pick or Map choice after writing your head or tail preference in chat. [Draft/<Map>] will set the Map at the beginning of the draft. [Draft/<Hero>] will pick or ban a Hero based on the in-game drafting order. [Draft/<Command>] will let you use a Command listed below. Commands: - "Help" will show this guide. - "Reset" will reset the draft. - "Undo" will revert the previous input.''' await channel.send(output) return if await mapAliases(text[1]) in await getMaps() and len(draftList) in [0,17]: drafts[channel.id]=[] draftList=drafts[channel.id] if channel in lastDraftMessageDict:del lastDraftMessageDict[channel] battleground=await mapAliases(text[1]) draftList.append(await mapString(battleground)) await channel.send('New draft started!') await mapImage(channel,battleground) draftNames[channel.id]=[] if printDraftBool:await printDraft(drafts,channel,draftList,lastDraftMessageDict,draftNames) return if len(text)==1: #[draft] with no second part. To call status await printDraft(drafts,channel,draftList,lastDraftMessageDict,draftNames) return text=text[1] if text.count(','): for i in text.split(','): await draft(drafts,channel,member,['d',i],lastDraftMessageDict,draftNames,False) await channel.send('Draft filled! Type [d] to view') return if text in ['new','start','n','s','reset','r']: drafts[channel.id]=[] if channel in lastDraftMessageDict:del lastDraftMessageDict[channel] await channel.send('New draft started! Choose map') draftNames[channel.id]=[] return if text in ['undo','u']: await channel.send('Undid '+draftList.pop()) elif len(draftList)<17: if len(draftList)==1: draftNames[channel.id]=[member.nick or member.name] elif len(draftList)==2: draftNames[channel.id].append(member.nick or member.name) if simplifyName(aliases(text)) in draftList: await channel.send(simplifyName(aliases(text))+' has already been picked/banned. Choose another!') return else: if len(draftList)==0:#Map name doesn't need check try: battleground=await mapAliases(text) except: await channel.send('`Unrecognized battleground!`') return draftList.append(await mapString(battleground)) await mapImage(channel,battleground) else: hero=aliases(text) if hero in getHeroes(): draftList.append(simplifyName(hero)) else: await channel.send('Invalid hero!') return if printDraftBool:await printDraft(drafts,channel,draftList,lastDraftMessageDict,draftNames)
async def draft(drafts, channel, text): try: draftList = drafts[channel.id] except: drafts[channel.id] = [] draftList = drafts[channel.id] if len(text) == 2: if text[1] in ['help', 'info']: output = '''MOCK DRAFTING GUIDE [Draft] will show the current state of the draft. [Flip] will toss a coin that can be used to randomly select who will go for first pick or Map choice after writing your head or tail preference in chat. [Draft/<Map>] will set the Map at the beginning of the draft. [Draft/<Hero>] will pick or ban a Hero based on the in-game drafting order. [Draft/<Command>] will let you use a Command listed below. Commands: - "Help" will show this guide. - "Reset" will reset the draft. - "Undo" will revert the previous input.''' await channel.send(output) return if await mapAliases(text[1] ) in await getMaps() and len(draftList) in [0, 17]: battleground = await mapAliases(text[1]) draftList.append(await mapString(battleground)) await channel.send(file=discord.File('Maps/' + battleground + '.jpg')) await printDraft(drafts, channel, draftList) return if len(text) == 1: #[draft] with no second part. To call status await printDraft(drafts, channel, draftList) return text = text[1] if text in ['new', 'start', 'n', 's', 'reset', 'r']: drafts[channel.id] = [] await channel.send('New draft started! Choose map') return if text in ['undo', 'u']: await channel.send('Undid ' + draftList.pop()) elif len(draftList) < 17: if simplifyName(aliases(text)) in draftList: await channel.send( simplifyName(aliases(text)) + ' has already been picked/banned. Choose another!') else: if len(draftList) == 0: #Map name doesn't need check try: battleground = await mapAliases(text) except: await channel.send('`Unrecognized battleground!`') return draftList.append(await mapString(battleground)) await channel.send(file=discord.File('Maps/' + battleground + '.jpg')) else: hero = aliases(text) if hero in getHeroes(): draftList.append(simplifyName(hero)) else: await channel.send('Invalid hero!') await printDraft(drafts, channel, draftList)
async def printDraft(drafts, channel, draftList): #Print state, and the next action to be done if channel.id not in drafts: await channel.send(channel.id + ' does not currently have an active draft.') return if not draftList: await channel.send('Pick a map') return #Order and map have been picked now order = 'mABABabbaaBAbbaab' #map, order. AB bans, ab picks bansA = [] bansB = [] picks = '' whitespaceAmount = 32 for i in range(1, len(draftList)): if order[i] == 'A': bansA.append(draftList[i]) elif order[i] == 'B': bansB.append(draftList[i]) elif order[i] == 'a': picks += draftList[i] + '\n' elif order[i] == 'b': picks += ' ' * whitespaceAmount + draftList[i] + '\n' output = '```Map: ' + draftList[0] + '\n\n' output += 'Team A' + ' ' * (whitespaceAmount - 6) + 'Team B\n' output += 'Bans: ' + ' ' * (whitespaceAmount - 6) + 'Bans: \n' output += ', '.join( bansA) + ' ' * (whitespaceAmount - len(', '.join(bansA))) + ', '.join( bansB) + '\n' + '-' * (whitespaceAmount + 15) + '\n' output += 'Picks:' + ' ' * (whitespaceAmount - 6) + 'Picks:\n' + picks + '\n' if len(draftList) == 17: output += 'Draft complete' else: nextAction = order[len(draftList)] nextTurnIsTeamB = 1 if nextAction.lower() == 'a': output += '<---------- ' nextTurnIsTeamB = 0 if nextAction == nextAction.upper(): nextAction = 'BAN for team ' + nextAction else: nextAction = 'Pick for team ' + nextAction.upper() output += 'Next action: ' + nextAction if nextTurnIsTeamB: output += ' ---------->' if len(draftList) > 1: hero = aliases(draftList[-1]).replace('_', ' ').replace( 'The Butcher', 'Butcher').capitalize() fileName = '' fileExtension = '.PNG' if hero == 'Maiev' else '.png' if len(draftList) in [2, 3, 4, 5, 11, 12]: #Numbers are the bans if hero in banEmojis.keys(): output = banEmojis[hero] + '\n' + output else: await channel.send(output + '```', file=discord.File('Emojis/' + hero + ' sad' + fileExtension)) return else: await channel.send(output + '```', file=discord.File('Emojis/' + hero + ' happy' + fileExtension)) return await channel.send(output + '```')