def destructionEmbed(member): return Embed( description= f"тЭЧ {member.mention} Your lab has exploded ЁЯТе due to overload, you lost everything." )
async def info(self, ctx): """ send an embed containing info in format Server_id Owner Channels text | voice Total: Members online | idle | dnd | streaming | offline Total: """ status = {} for member in ctx.guild.members: status[member.status.name] = status.get(member.status.name, 0) + 1 online = core.utils.get(self.bot.emojis, name="status_online") idle = core.utils.get(self.bot.emojis, name="status_idle") dnd = core.utils.get(self.bot.emojis, name="status_dnd") streaming = core.utils.get(self.bot.emojis, name="status_streaming") offline = core.utils.get(self.bot.emojis, name="status_offline") text = core.utils.get(self.bot.emojis, name="text_channel") voice = core.utils.get(self.bot.emojis, name="voice_channel") embed = Embed( title=f"{ctx.guild.name}", description= f"{ctx.guild.description if ctx.guild.description else ''}", color=Color.from_rgb(0, 0, 0)) embed.add_field(name="ID", value=(f"{ctx.guild.id}")) embed.add_field(name="Owner", value=(f"{ctx.guild.owner}")) embed.add_field( name="Channels", value=("{text} {text_count} " + "{voice} {voice_count}").format( text=text, text_count=len(ctx.guild.text_channels), voice=voice, voice_count=len(ctx.guild.voice_channels)) + f"\n**Total:** {len(ctx.guild.channels)}", inline=False) embed.add_field( name="Members", value=("{online} {online_count} " + "{idle} {idle_count} " + "{dnd} {dnd_count} " + "{streaming} {streaming_count} " + "{offline} {offline_count}").format( online=online, online_count=status.get("online", 0), idle=idle, idle_count=status.get("idle", 0), dnd=dnd, dnd_count=status.get("dnd", 0), streaming=streaming, streaming_count=status.get("streaming", 0), offline=offline, offline_count=status.get("offline", 0)) + f"\n**Total:** {len(ctx.guild.members)}", inline=False) await ctx.send(embed=embed)
elif l in [ "| **Name** | **Usage** | **Description** | **Aliases** |", "|:-:|:-:|:-:|:-:|" ]: pass elif l.startswith("|") and l.endswith("|"): cmd = list( map(lambda x: x.replace('`', ""), l.strip("|").split("|"))) helpvals[lastheader].append("< " + cmd[1] + " >\n[ AKA " + cmd[3].ljust(15) + " ]( " + cmd[2] + " )") else: helpvals[lastheader].append('> ' + l.replace('`', '')) helpembed = Embed(colour=0x9542f4) desc = "```markdown" first = True for key, value in helpvals.items(): if first: helpembed.title = key helpembed.description = '\n'.join( map(lambda x: x.lstrip(">").strip(), value) ) + '\n\nTo display another page, do `cow help {page number}`. For more help, take a look at [the Readme](https://github.com/UnsignedByte/discow/blob/master/README.md) on our [github repository](https://github.com/UnsignedByte/discow)!' first = False else: stoadd = "\n\n# " + key + '\n\n' + '\n'.join(value) if len(desc) + len(stoadd) >= 1000: helpembed.add_field(name='\a', value=desc + '```')
async def anime(self, args, mobj): """ Does a AniList search to find requested Anime If there are multiple options, will ask you which one to choose. You will have 10 seconds to respond. Will not return any adult series. """ args = " ".join(args) result = await self.ani_get_options(args, mobj, 'ANIME') if result: anime = self.anilist.getAnimeDetailsById(result) else: anime = self.anilist.getAnimeDetails(args) if not anime: await self.error(mobj.channel, "Could not find anything") return if not anime: await self.error(mobj.channel, "Could not find anything") return embed = Embed( title=anime['title_english'] if anime['title_english'] else anime['title_romaji'] if anime['title_romaji'] else anime['title_japanese'], colour=Color(0x7289da), url=f"https://anilist.co/anime/{anime['id']}/{anime['title_romaji']}" .replace(" ", "%20")) embed.set_image(url=anime['img']) embed.add_field(name="Episode Count", value=str(anime['total_episodes'])) embed.add_field(name="Type", value=anime['type']) embed.add_field(name="Status", value=anime['airing_status']) embed.add_field( name="Dates", value= f'{anime["start_date"]} through {anime["end_date"] if anime["end_date"] != "None-None-None" else "present"}' if anime["start_date"] != anime["end_date"] else f'{anime["start_date"]}') if anime["synonyms"]: embed.add_field(name="Synonyms", value=", ".join(anime["synonyms"])) if anime["description"] is None: anime["description"] = "Could not pull synopsis" anime["description"] = re.sub( r'\n\s*\n', '\n\n', unescape(anime["description"]).replace("<br>", "\n")) if len(anime["description"]) > 1000: if "\n" in anime["description"][:965]: anime["description"] = anime[ "description"][:anime["description"][:965].rfind("\n")] else: anime["description"] = anime["description"][:965] anime["description"] += "\nIncomplete synopsis due to length." embed.add_field(name="Synopsis", value=anime["description"]) try: await self.embed(mobj.channel, embed) except BaseException: await self.error( mobj.channel, "Something when trying to format the object. Here is a link to the anime: " + "https://myanimelist.net/anime/{0.id}/{0.title}".format( anime).replace(" ", "%20"))
async def status(self, ctx): #既に存在する関数名だったらERROR出るのでもし今後コマンドを追加するならコマンド名と同じ関数名にして下さい。 f""" ステータスの表示。 今後アイテム追加した場合に備えてページ分けを自動でさせてます。 f""" try: # ERRORが起きるか起きないか。起きたらexceptに飛ばされる # sqlite_listの中からデータベースに接続したというオブジェクトを取得 _, conn, cur = [sql for sql in self.bot.sqlite_list if ctx.author.id == sql[0]][0] user = ctx.author user_id = ctx.author.id user_name = ctx.author.nick if ctx.author.nick else ctx.author.name # ユーザーの総経験値を取得 player_exp = await database.get_player_exp(ctx, user_id, conn, cur) # 戦闘チャンネルの確認 await cur.execute("select distinct channel_id FROM in_battle WHERE user_id=?", (user_id,)) in_battle = await cur.fetchone() battle_str = f"{self.bot.get_channel(in_battle[0]).guild.name}の{self.bot.get_channel(in_battle[0]).mention}" if in_battle and self.bot.get_channel(in_battle[0]) else "現在休戦中or認識出来ないチャンネル" # アイテムを所持してるかの確認。アイテムはitem_idで登録してるので名前をall_dataファイルのitem_lists変数から引っ張ってきます。 await cur.execute("select distinct item_id,count FROM item WHERE user_id=? ORDER BY item_id;", (user_id,)) i_list = ''.join(f'{item_lists[i[0]]} : {i[1]}個\n' for i in await cur.fetchall()) # 今後アイテムが増えた場合に25個のデータ(重複なし)でページ分け msgs = list(filter(lambda a: a != "", ["\n".join(i_list.split("\n")[i:i + 25]) for i in range(0, len(i_list), 25)] if i_list != "" else ["無し"])) # 現在のユーザのランキングlistで返しindexで順位を取得する方法にしています。 await cur.execute("select distinct user_id FROM player ORDER BY exp DESC;") user_rank = [r[0] for r in await cur.fetchall()] # 経験値をmath.sqrt(平方根の計算)を使用し求めます。整数を返すためにint()を使用しています。 player_level = int(math.sqrt(player_exp)) embeds = [] embed = Embed() embed.add_field(name="Lv", value=str(player_level)) embed.add_field(name="HP", value=str(player_level*5+50)) embed.add_field(name="ATK", value=str(int(player_level*5+50))) embed.add_field(name="EXP", value=str(player_exp)) # レベル+1の必要経験値数(2乗)-現在の経験値数で計算しています。 embed.add_field(name="次のLvまで", value=str((player_level+1)**2-player_exp)+"exp") embed.add_field(name="戦闘状況:", value=battle_str) embed.add_field(name="順位:", value=f"{user_rank.index(user_id) + 1}位") # ユーザーのアイコン表示 embed.set_thumbnail(url=user.avatar_url_as()) embed.set_author(name=f"{user_name}のステータス:") embeds.append(embed) [embeds.append(Embed(description=f"```{i if i else 'アイテムを所持していません。'}```").set_thumbnail(url=user.avatar_url_as()).set_author(name=f"{user_name}のステータス:")) for i in msgs] msg = await ctx.send(content=f"```diff\n1ページ/{len(embeds)}ページ目を表示中\n見たいページを発言してください。\n30秒経ったら処理は止まります。\n0と発言したら強制的に処理は止まります。```", embed=embeds[0]) while True: # 処理が終わる(return)まで無限ループ try: # ERRORが起きるか起きないか。起きたらexceptに飛ばされる msg_react = await self.bot.wait_for('message', check=lambda m: m.author == ctx.author and m.content.isdigit() and 0 <= int(m.content) <= len(embeds), timeout=30) # await self.bot.wait_for('message')で返ってくるのは文字列型 if msg_react.content == "0": # このcontentの中にはゼロ幅スペースが入っています。Noneでもいいのですが編集者はこっちの方が分かりやすいからこうしています。 return await msg.edit(content="") await msg.edit(content=f"```diff\n{int(msg_react.content)}ページ/{len(embeds)}ページ目を表示中\n見たいページを発言してください。\n30秒経ったら処理は止まります。\n0と発言したら強制的に処理は止まります。```", embed=embeds[int(msg_react.content)-1]) except asyncio.TimeoutError: # wait_forの時間制限を超過した場合 # このcontentの中にはゼロ幅スペースが入っています。Noneでもいいのですが編集者はこっちの方が分かりやすいからこうしています。 return await msg.edit(content="", embed=Embed(title=f"時間切れです...")) except (NotFound, asyncio.TimeoutError, Forbidden): # 編集した際に文字が見つからなかった, wait_forの時間制限を超過した場合, メッセージに接続できなかった return except: # 上のERROR以外のERROR出た場合はtracebackで表示するようにしています。 上手くコマンドが反応しない場合はコンソールを見てね! return print("エラー情報\n" + traceback.format_exc())
async def superstarify( self, ctx: Context, member: Member, duration: Expiry, *, reason: str = '', ) -> None: """ Temporarily force a random superstar name (like Taylor Swift) to be the user's nickname. A unit of time should be appended to the duration. Units (∗case-sensitive): \u2003`y` - years \u2003`m` - months∗ \u2003`w` - weeks \u2003`d` - days \u2003`h` - hours \u2003`M` - minutes∗ \u2003`s` - seconds Alternatively, an ISO 8601 timestamp can be provided for the duration. An optional reason can be provided, which would be added to a message stating their old nickname and linking to the nickname policy. """ if await _utils.get_active_infraction(ctx, member, "superstar"): return # Post the infraction to the API old_nick = member.display_name infraction_reason = f'Old nickname: {old_nick}. {reason}' infraction = await _utils.post_infraction(ctx, member, "superstar", infraction_reason, duration, active=True) id_ = infraction["id"] forced_nick = self.get_nick(id_, member.id) expiry_str = format_infraction(infraction["expires_at"]) # Apply the infraction async def action() -> None: log.debug(f"Changing nickname of {member} to {forced_nick}.") self.mod_log.ignore(constants.Event.member_update, member.id) await member.edit(nick=forced_nick, reason=reason) old_nick = escape_markdown(old_nick) forced_nick = escape_markdown(forced_nick) nickname_info = textwrap.dedent(f""" Old nickname: `{old_nick}` New nickname: `{forced_nick}` """).strip() user_message = ( f"Your previous nickname, **{old_nick}**, " f"was so bad that we have decided to change it. " f"Your new nickname will be **{forced_nick}**.\n\n" "{reason}" f"You will be unable to change your nickname until **{expiry_str}**. " "If you're confused by this, please read our " f"[official nickname policy]({NICKNAME_POLICY_URL})." ).format successful = await self.apply_infraction( ctx, infraction, member, action(), user_reason=user_message(reason=f'**Additional details:** {reason}\n\n' if reason else ''), additional_info=nickname_info ) # Send an embed with to the invoking context if superstar was successful. if successful: log.trace(f"Sending superstar #{id_} embed.") embed = Embed( title="Superstarified!", colour=constants.Colours.soft_orange, description=user_message(reason='') ) await ctx.send(embed=embed)
async def draw(command, msg, user, channel, *args, **kwargs): full_msg = kwargs['full_msg'] char_num = 7 client = kwargs['client'] unicode_reactions = ["1⃣", "2⃣", "3⃣", "4⃣", "5⃣", "6⃣", "7⃣"] player1 = user if len(msg.split(' ')) > 2: raise Exception( bold("Draw") + ": Too many arguments. " + await help_lizard('', '', '', '')) # No mention or too many, Raise exception elif not full_msg.mentions or len(full_msg.mentions) > 1: raise Exception( bold("Draw") + ": You must mention exactly one user to draw against.") player2 = full_msg.mentions[0] if player1 == player2: raise Exception( bold("Draw") + ": You are not allowed to draw against yourself.") # Start with randomselect basis to get characters try: game = msg.split(' ')[1].lower() except: # No game to be found so default to sfv game = 'sfv' chars, games = get_randomselect_data(game) if not chars: raise Exception( bold("Draw") + ": Invalid game: {0}. Valid games are: {1}".format( bold(game), bold(', '.join(games)))) if len(chars) < char_num: # If we have a game with an amount of characters less than the number of cards drawn, it will never create a list raise Exception( bold("Draw") + ": Invalid game: {0}. The game selected has too few characters to function with this command." .format(bold(game))) # Initial accept embed accept_embed = Embed(title="Card Draw", colour=Colour(0x0fa1dc)) accept_embed.set_footer( text="Do you agree to a draw, {0}?".format(player2.display_name)) try: accept_msg = await channel.send(embed=accept_embed) except: raise Exception( bold("Draw") + ": Error sending embed to chat. Give Lizard-BOT the permission: " + bold("Embed Links")) await accept_msg.add_reaction('❌') await accept_msg.add_reaction('✅') try: # Wait for the reaction from the correct user # lambda function check for the correct reaction and the correct user reaction, user = await client.wait_for( 'reaction_add', timeout=60.0, check=lambda reaction, user: user == player2 and (str(reaction.emoji) == '✅' or str(reaction.emoji) == '❌' ) and reaction.message == accept_msg) if str(reaction.emoji) == '❌': raise Exception() except: await accept_msg.delete() raise Exception(bold("Draw") + ": The draw was not accepted.") # if we got here, draw was accepted # randomly choose player order order = random_choice( [[player1, player2, player1, player2, player2, player1], [player2, player1, player2, player1, player1, player2]]) # declare an Array of 0s to mark all cards as not picked # -1 means a card ban, 1 means a card draw picks = [0] * char_num #create new embed card_embed = Embed(title="Card Draw", colour=Colour(0x0fa1dc)) # Declare list and fill with the amount of random characters # Make it so that it has to be all different characters characters_list = [] while len(characters_list) < char_num: new_char = random_choice(chars) # Only add to the list if it is a new character if not new_char in characters_list: characters_list.append(new_char) # Add characters to ban for i, c in enumerate(characters_list): card_embed.add_field(name="Char {0}".format(i + 1), value=c, inline=True) await accept_msg.delete() try: game_msg = await channel.send(embed=card_embed) except: raise Exception( bold("Draw") + ": Error sending embed to chat. Give Lizard-BOT the permission: " + bold("Embed Links")) # Add reactions for pick/ban purposes for reaction in unicode_reactions: await game_msg.add_reaction(reaction) # Create lists for the picked characters p1_chars = [] p2_chars = [] for it, player in enumerate(order): user_to_check = None msg_to_check = None reaction_read = None reaction_read_emoji = None number = None # first two are bans if it < 2: card_embed.set_footer(text="{0}, select a character to ban.". format(player.display_name)) await game_msg.edit(embed=card_embed) while not (user_to_check == player) or not ( msg_to_check == game_msg ) or reaction_read_emoji not in unicode_reactions: try: reaction_read, user_to_check = await client.wait_for( 'reaction_add', timeout=60.0) msg_to_check = reaction_read.message if not (msg_to_check == game_msg and user_to_check == player): continue reaction_read_emoji = reaction_read.emoji number = unicode_reactions.index(reaction_read_emoji) if picks[number] != 0: # already banned, set as None to make it fail reaction_read_emoji = None card_embed.set_footer( text= "{0}, that character is already banned, please choose another." .format(player.display_name)) await game_msg.edit(embed=card_embed) except Exception as ex: if type(ex).__name__ == "TimeoutError": await game_msg.delete() raise Exception( bold("Draw") + ": {0} failed to ban a character.".format( player.display_name)) else: # As of right now, if something else goes wrong its because a reaction its not expecting was sent, go to the next loop continue # mark character as banned picks[number] = -1 # Strikethrough char on embed card_embed.set_field_at(number, name="Char {0}".format(number + 1), value="~~{0}~~".format( characters_list[number])) else: card_embed.set_footer(text="{0}, select a character to pick.". format(player.display_name)) if it == 4: # Remind them gently they get to pick another character in a row if they are the 2nd player card_embed.set_footer( text="{0}, select another character to pick.".format( player.display_name)) await game_msg.edit(embed=card_embed) while not (user_to_check == player) or not ( msg_to_check == game_msg ) or reaction_read_emoji not in unicode_reactions: try: reaction_read, user_to_check = await client.wait_for( 'reaction_add', timeout=60.0) msg_to_check = reaction_read.message if not (msg_to_check == game_msg and user_to_check == player): continue reaction_read_emoji = reaction_read.emoji number = unicode_reactions.index(reaction_read_emoji) if picks[number] == -1: # already banned, set as None to make it fail reaction_read_emoji = None card_embed.set_footer( text= "{0}, that character is already banned, please choose another." .format(player.display_name)) await game_msg.edit(embed=card_embed) elif picks[number] == 1: # already banned, set as None to make it fail reaction_read_emoji = None card_embed.set_footer( text= "{0}, that character is already chosen, please choose another." .format(player.display_name)) await game_msg.edit(embed=card_embed) except Exception as ex: if type(ex).__name__ == "TimeoutError": await game_msg.delete() raise Exception( bold("Draw") + ": {0} failed to choose a character.".format( player.display_name)) else: # As of right now, if something else goes wrong its because a reaction its not expecting was sent, go to the next loop continue # mark character as picked picks[number] = 1 # edit embed to bold character card_embed.set_field_at(number, name="Char {0}".format(number + 1), value="__" + bold(characters_list[number]) + "__") # assign character chosen to if player == player1: p1_chars.append(characters_list[number]) else: p2_chars.append(characters_list[number]) # create new embed chosen_embed = Embed(title="Final Picks", colour=Colour(0x0fa1dc)) chosen_embed.add_field(name=player1.display_name, value=", ".join(p1_chars)) chosen_embed.add_field(name=player2.display_name, value=", ".join(p2_chars)) await game_msg.delete() await channel.send(embed=chosen_embed) return "Card draw finished"
def write(word, isPic=False): if isPic == False: embed = Embed(description=word) UserObject.embed_send_list.append(embed) else: UserObject.embed_send_list.append(word)
async def hanukkah_festival(self, ctx): """Tells you about the Hanukkah Festivaltime of festival, festival day, etc).""" hanukkah_dates = await self.get_hanukkah_dates() self.hanukkah_dates_split(hanukkah_dates) hanukkah_start_day = int(self.hanukkah_days[0]) hanukkah_start_month = int(self.hanukkah_months[0]) hanukkah_start_year = int(self.hanukkah_years[0]) hanukkah_end_day = int(self.hanukkah_days[8]) hanukkah_end_month = int(self.hanukkah_months[8]) hanukkah_end_year = int(self.hanukkah_years[8]) hanukkah_start = datetime.date(hanukkah_start_year, hanukkah_start_month, hanukkah_start_day) hanukkah_end = datetime.date(hanukkah_end_year, hanukkah_end_month, hanukkah_end_day) today = datetime.date.today() # today = datetime.date(2019, 12, 24) (for testing) day = str(today.day) month = str(today.month) year = str(today.year) embed = Embed() embed.title = 'Hanukkah' embed.colour = Colours.blue if day in self.hanukkah_days and month in self.hanukkah_months and year in self.hanukkah_years: if int(day) == hanukkah_start_day: now = datetime.datetime.utcnow() now = str(now) hours = int(now[11:13]) + 4 # using only hours hanukkah_start_hour = 18 if hours < hanukkah_start_hour: embed.description = ( f"Hanukkah hasnt started yet, " f"it will start in about {hanukkah_start_hour-hours} hour/s." ) return await ctx.send(embed=embed) elif hours > hanukkah_start_hour: embed.description = ( f'It is the starting day of Hanukkah ! ' f'Its been {hours-hanukkah_start_hour} hours hanukkah started !' ) return await ctx.send(embed=embed) festival_day = self.hanukkah_days.index(day) number_suffixes = ['st', 'nd', 'rd', 'th'] suffix = '' if int(festival_day) == 1: suffix = number_suffixes[0] if int(festival_day) == 2: suffix = number_suffixes[1] if int(festival_day) == 3: suffix = number_suffixes[2] if int(festival_day) > 3: suffix = number_suffixes[3] message = '' for _ in range(1, festival_day + 1): message += ':menorah:' embed.description = f'It is the {festival_day}{suffix} day of Hanukkah ! \n {message}' await ctx.send(embed=embed) else: if today < hanukkah_start: festival_starting_month = hanukkah_start.strftime('%B') embed.description = ( f"Hanukkah has not started yet. " f"Hanukkah will start at sundown on {hanukkah_start_day}th " f"of {festival_starting_month}.") else: festival_end_month = hanukkah_end.strftime('%B') embed.description = ( f"Looks like you missed Hanukkah !" f"Hanukkah ended on {hanukkah_end_day}th of {festival_end_month}." ) await ctx.send(embed=embed)
async def _item(self, ctx, user_id, channel_id, item_name, mentions, conn, cur, bot): # アイテム関連の関数。 try: # ERRORが起きるか起きないか。起きたらexceptに飛ばされる if not item_name: # item_nameが空だった場合 # アイテムを所持してるかの確認。アイテムはitem_idで登録してるので名前をall_dataファイルのitem_lists変数から引っ張ってきます。 await cur.execute( "select distinct item_id,count FROM item WHERE user_id=? ORDER BY item_id;", (user_id, )) i_list = ''.join(f'{item_lists[i[0]]} : {i[1]}個\n' for i in await cur.fetchall()) msgs = list( filter(lambda a: a != "", [ "\n".join(i_list.split("\n")[i:i + 25]) for i in range(0, len(i_list), 25) ])) # 今後アイテムが増えた場合に25個のデータ(重複なし)でページ分け embeds = [ Embed(description=f"```{i if i else 'アイテムを所持していません。'}```"). set_thumbnail(url=ctx.author.avatar_url_as()).set_author( name=f"{ctx.author}のステータス:") for i in msgs ] msg = await ctx.send( content= f"```diff\n1ページ/{len(embeds)}ページ目を表示中\n見たいページを発言してください。\n30秒経ったら処理は止まります。\n0と発言したら強制的に処理は止まります。```", embed=embeds[0]) while True: # 処理が終わる(return)まで無限ループ try: # ERRORが起きるか起きないか。起きたらexceptに飛ばされる msg_react = await bot.wait_for( 'message', check=lambda m: m.author == ctx.author and m. content.isdigit() and 0 <= int(m.content) <= len( embeds), timeout=30) # await self.bot.wait_for('message')で返ってくるのは文字列型 if msg_react.content == "0": # このcontentの中にはゼロ幅スペースが入っています。Noneでもいいのですが編集者はこっちの方が分かりやすいからこうしています。 return await msg.edit(content="") await msg.edit( content= f"```diff\n{int(msg_react.content)}ページ/{len(embeds)}ページ目を表示中\n見たいページを発言してください。\n30秒経ったら処理は止まります。\n0と発言したら強制的に処理は止まります。```", embed=embeds[int(msg_react.content) - 1]) except asyncio.TimeoutError: # wait_forの時間制限を超過した場合 # このcontentの中にはゼロ幅スペースが入っています。Noneでもいいのですが編集者はこっちの方が分かりやすいからこうしています。 return await msg.edit(content="", embed=Embed(title=f"時間切れです...")) if item_name in ["e", "elixir", "エリクサー" ]: # item_nameが["e", "elixir", "エリクサー"]の中のどれかだったら return await ctx.send(await elixir(user_id, channel_id, conn, cur)) elif item_name in [ "f", "fire", "ファイアボールの書" ]: # item_nameが["f", "fire", "ファイアボールの書"]の中のどれかだったら return await Database().fireball(ctx, user_id, channel_id, conn, cur, bot) elif item_name in ["p", "pray", "祈りの書" ]: # item_nameが["p", "pray", "祈りの書"]の中のどれかだったら return await ctx.send(await pray(ctx, user_id, channel_id, mentions, conn, cur, bot)) else: # item_nameでアイテムが存在してなかった場合 return await ctx.send( embed=Embed(title=f"!?", description="そのアイテムは存在しません。")) except (NotFound, asyncio.TimeoutError, Forbidden ): # 編集した際に文字が見つからなかった, wait_forの時間制限を超過した場合, メッセージに接続できなかった return except: # 上のERROR以外のERROR出た場合はtracebackで表示するようにしています。 上手くコマンドが反応しない場合はコンソールを見てね! return print("エラー情報\n" + traceback.format_exc())
def _get_error_embed(self, title: str, body: str) -> Embed: """Return an embed that contains the exception.""" return Embed(title=title, colour=Colours.soft_red, description=body)
async def maps(self, ctx, searches="", rotation_maps=True): """ Lists all maps in rotation when no searches are provided Searches for maps when searches are given """ await ctx.defer() with open("utils/maps.json") as file: maps = load(file) map_str = list() args = list(map(lambda x: x.strip(), filter(None, searches.lower().split(",")))) if not rotation_maps: #Merg with open("utils/all_maps.json") as file: all_maps = load(file) maps = {**maps, **all_maps} list_maps = None if not searches: list_maps = list(maps.items()) else: list_maps = [] for search in args: for k, v in maps.items(): if search in k.lower() or search in str(v): if [k, v] not in list_maps: #Only adds new elements so no dupes list_maps.append([k, v]) amount = len(list_maps) #Amount of maps found if not list_maps: #No results return await error_embed(ctx,"No maps found. Did you forget to separate maps with commas (blackout, pagodas III)?") if len(list_maps) == 1: #Image for single search result map_id = list_maps[0][1] map_name = list_maps[0][0] if os.path.exists(f"assets/map_screenshots/{map_id}.jpg"): file = File(f"assets/map_screenshots/{map_id}.jpg", filename=f"{map_id}.png") embed = Embed(title="Maps Found:", description=f"[{map_name}](https://www.brawl.com/games/ctf/maps/{map_id}) ({map_id})", color=Colour.dark_purple()) embed.set_image(url=f"attachment://{map_id}.png") response = await ctx.send("Fetching maps...") await response.edit(content="Done!") await ctx.channel.send(embed=embed, file=file) else: #Handling single search results without an image embed = Embed(title="Maps Found:", description=f"[{map_name}](https://www.brawl.com/games/ctf/maps/{map_id}) ({map_id})", color=Colour.dark_purple()) embed.set_footer(text="This map has no image yet :(") response = await ctx.send("Fetching maps...") await response.edit(content="Done!") await ctx.channel.send(embed=embed) return for (map_name, map_id) in list_maps: map_str.append(f"[{map_name}](https://www.brawl.com/games/ctf/maps/{map_id}) ({map_id})") if len(list_maps)>5: #Sort maps by name but only for >5 results otherwise match string gets scuffed map_str = sorted(map_str) if len(list_maps) <= 5 and len(list_maps) != 0: # Shows map ids only if there are 3 results map_str.append(f"\n*For match server:*\n`{' '.join(str(item[1]) for item in list_maps)}`") await create_list_pages(self.bot, ctx, f"Maps Found ({amount}):", map_str, "No Maps were found", random_item=True)
class VerificationCog(Cog, name="Verification"): def __init__(self, bot: Bot): self.bot = bot @commands.command() @private_only async def verify(self, ctx: Context, *, password: str): correct_password: str = await Settings.get(str, "verification_password") if correct_password is None: raise CommandError(translations.verification_disabled) if password != correct_password: raise CommandError(translations.password_incorrect) guild: Guild = self.bot.guilds[0] member: Member = guild.get_member(ctx.author.id) delay: int = await Settings.get(int, "verification_delay", -1) if delay != -1 and (datetime.utcnow() - member.joined_at).total_seconds() < delay: raise CommandError(translations.password_incorrect) add: List[Role] = [] remove: List[Role] = [] fail = False for vrole in await db_thread( db.all, VerificationRole): # type: VerificationRole role: Optional[Role] = guild.get_role(vrole.role_id) if role is None: continue if vrole.reverse: if role in member.roles: remove.append(role) else: fail = True elif not vrole.reverse and role not in member.roles: add.append(role) if not add and not remove: raise CommandError(translations.already_verified) if fail: raise CommandError( translations.verification_reverse_role_not_assigned) await member.add_roles(*add) await member.remove_roles(*remove) embed = Embed(title=translations.verification, description=translations.verified, colour=Colours.Verification) await ctx.send(embed=embed) @commands.group(aliases=["vf"]) @Permission.manage_verification.check @guild_only() async def verification(self, ctx: Context): """ configure verify command """ if ctx.subcommand_passed is not None: if ctx.invoked_subcommand is None: raise UserInputError return password: str = await Settings.get(str, "verification_password") normal: List[Role] = [] reverse: List[Role] = [] for vrole in await db_thread( db.all, VerificationRole): # type: VerificationRole role: Optional[Role] = ctx.guild.get_role(vrole.role_id) if role is None: await db_thread(db.delete, vrole) else: [normal, reverse][vrole.reverse].append(role) embed = Embed(title=translations.verification, colour=Colours.error) if password is None or not normal + reverse: embed.add_field(name=translations.status, value=translations.verification_disabled, inline=False) await ctx.send(embed=embed) return embed.colour = Colours.Verification embed.add_field(name=translations.status, value=translations.verification_enabled, inline=False) embed.add_field(name=translations.password, value=f"`{password}`", inline=False) delay: int = await Settings.get(int, "verification_delay", -1) val = translations.f_x_seconds( delay) if delay != -1 else translations.disabled embed.add_field(name=translations.delay, value=val, inline=False) if normal: embed.add_field( name=translations.roles_normal, value="\n".join(f":small_orange_diamond: {role.mention}" for role in normal), ) if reverse: embed.add_field( name=translations.roles_reverse, value="\n".join(f":small_blue_diamond: {role.mention}" for role in reverse), ) await ctx.send(embed=embed) @verification.command(name="add", aliases=["a", "+"]) async def verification_add(self, ctx: Context, role: Role, reverse: bool = False): """ add verification role if `reverse` is set to `true`, the role is not added but removed during verification. the `verify` command will fail if the user does not have the role. """ if role >= ctx.me.top_role: raise CommandError( translations.f_role_not_set_too_high(role, ctx.me.top_role)) if role.managed: raise CommandError(translations.f_role_not_set_managed_role(role)) if await db_thread(db.get, VerificationRole, role.id) is not None: raise CommandError(translations.verification_role_already_set) await db_thread(VerificationRole.create, role.id, reverse) embed = Embed( title=translations.verification, description=translations.verification_role_added, colour=Colours.Verification, ) await ctx.send(embed=embed) if reverse: await send_to_changelog( ctx.guild, translations.f_log_verification_role_added_reverse( role.name, role.id)) else: await send_to_changelog( ctx.guild, translations.f_log_verification_role_added(role.name, role.id)) @verification.command(name="remove", aliases=["r", "-"]) async def verification_remove(self, ctx: Context, *, role: Role): """ remove verification role """ if (row := await db_thread(db.get, VerificationRole, role.id)) is None: raise CommandError(translations.verification_role_not_set) await db_thread(db.delete, row) embed = Embed( title=translations.verification, description=translations.verification_role_removed, colour=Colours.Verification, ) await ctx.send(embed=embed) await send_to_changelog( ctx.guild, translations.f_log_verification_role_removed(role.name, role.id))
def redEmbed(descr): return Embed(description=descr, colour=discord.Colour.from_rgb(255, 25, 25))
async def main(client): with db: top_members_limit = ClubUser.top_members_limit() pin_reactions_by_members = [ pin_reaction for pin_reaction in ClubPinReaction.listing() if pin_reaction.user.is_member ] log.info( f'Found {len(pin_reactions_by_members)} pin reactions by people who are currently members' ) for pin_reaction in pin_reactions_by_members: member = await client.juniorguru_guild.fetch_member( pin_reaction.user.id) if member.dm_channel: channel = member.dm_channel else: channel = await member.create_dm() log.info( f"Checking DM if already pinned for {member.display_name} #{member.id}" ) if await is_pinned(pin_reaction.message.url, channel): log.info(f"Already pinned for {member.display_name} #{member.id}") continue log.info( f"Not pinned for {member.display_name} #{member.id}, sending a message to DM" ) if DISCORD_MUTATIONS_ENABLED: content = ( '📌 VidÃm Å¡pendlÃk! Ukládám ti pÅ™ÃspÄ›vek sem, do soukromé zprávy. ' f'Když bude mÃt ~{top_members_limit} Å¡pendlÃků, pÅ™ipnu jej v původnÃm kanálu pro vÅ¡echny.' ) embed_description = [ f"{pin_reaction.message.author.mention} v {pin_reaction.message.channel_mention}:", f"> {textwrap.shorten(pin_reaction.message.content, 500, placeholder='…')}", f"[Hop na pÅ™ÃspÄ›vek]({pin_reaction.message.url})", "", ] await channel.send( content=content, embed=Embed(description="\n".join(embed_description))) else: log.warning( "Skipping Discord mutations, DISCORD_MUTATIONS_ENABLED not set" ) log.info( f"Going through messages pinned by reactions, minimum is {top_members_limit} pin reactions" ) with db: messages = ClubMessage.pinned_by_reactions_listing(top_members_limit) log.info(f'Found {len(messages)} messages') for message in messages: log.info( f"Message {message.url} {'PINNED' if message.is_pinned else 'NOT PINNED'}" ) if not message.is_pinned: log.info(f"Pinning {message.url}") channel = await client.fetch_channel(message.channel_id) discord_message = await channel.fetch_message(message.id) await discord_message.pin( reason= f"The message has {message.pin_reactions_count} pin reactions, minimum is {top_members_limit}" )
def response_embed(self, response, success=True): embed = Embed(description=response, color=0x00ff00 if success else 0xff0000) embed.set_author(name='UoM Esports Bot', icon_url=self.user.avatar_url) return embed
def embed(self): return Embed(title="Error", description=self.msg, color=Color.red())
async def on_ready(self): # output information about the bot's login log('Logged in as {0}, {0.id}'.format(self.user)) # command prefix self.command_prefix = self.config.get('general', 'command_prefix') # read guild variable ids from the config file and intialise them as global variables self.guild = self.get_guild(int(self.config.get('general', 'guild'))) # bot name await self.guild.me.edit(nick=self.config.get('general', 'name')) # channels self.bot_channel = self.guild.get_channel( int(self.config.get('channels', 'bot'))) self.admin_channel = self.guild.get_channel( int(self.config.get('channels', 'admin'))) self.stream_channel = self.guild.get_channel( int(self.config.get('channels', 'stream'))) self.streaming = None # roles self.admin_role = find( lambda role: role.id == int(self.config.get('roles', 'admin')), self.guild.roles) self.member_role = find( lambda role: role.id == int(self.config.get('roles', 'member')), self.guild.roles) self.guest_role = find( lambda role: role.id == int(self.config.get('roles', 'guest')), self.guild.roles) self.first_strike_role = find( lambda role: role.id == int( self.config.get('roles', 'first_strike')), self.guild.roles) self.second_strike_role = find( lambda role: role.id == int( self.config.get('roles', 'second_strike')), self.guild.roles) with open('roles.txt', 'w') as f: for role in self.guild.roles: f.write('{0.name} {0.id}\n'.format(role)) # produce the list of commands self.commands = {} for att in dir(self): attr = getattr(self, att, None) if hasattr(attr, 'bot_command'): self.commands[att] = { 'cmd': attr, 'admin_only': attr.admin_only, 'embed': self.cmd_embed(attr) } # maintain the bots presence asyncio.ensure_future(self.maintain_presence()) # check the unbans asyncio.ensure_future(self.check_unbans()) # generate the help embeds self.help_embed = Embed(title='Commands', color=self.member_role.colour) self.help_embed.set_author(name='UoM Esports Bot', icon_url=self.user.avatar_url) for category in ['General', 'Games', 'Roles']: self.help_embed.add_field( name=category, value='\n'.join([ '{}{}'.format(self.command_prefix, command) for command in self.commands if not self.commands[command]['admin_only'] and self.commands[command]['cmd'].category == category ]), ) self.help_embed.set_footer( text='Type "{}help command" to get its usage.'.format( self.command_prefix)) self.admin_embed = Embed(title='Admin Commands', color=self.admin_role.colour) self.admin_embed.set_author(name='UoM Esports Bot', icon_url=self.user.avatar_url) for category in ['General', 'Games', 'Roles']: self.admin_embed.add_field( name=category, value='\n'.join([ '{0}{1}{2}{0}'.format( '**' if self.commands[command]['admin_only'] else '', self.command_prefix, command) for command in self.commands if self.commands[command]['cmd'].category == category ])) self.admin_embed.set_footer( text= 'Type "{}help command" to get its usage. Admin-only commands have bold formattng.' .format(self.command_prefix)) # generate the game roles self.games = [] for sid in self.config.get('roles', 'games').split(): try: role = find(lambda role: role.id == int(sid), self.guild.roles) # check if role exists if role: self.games.append(role) else: # role doesn't exist log('Couldn\'t find role with ID {}'.format(sid)) except Exception as ex: log('Unhandled {} while reading in role ID {}: {}'.format( ex.__class__.__name__, sid, ex)) # write out working game roles to the config file self.config.set('roles', 'games', ' '.join([str(role.id) for role in self.games])) self.write_config() # ready to go! log('------') self.ready.set()
def help_embed() -> Embed: return Embed(title="MiniMaid Help", description=HELP_MESSAGE, colour=Colour.blue())
async def _clean_messages( self, amount: int, ctx: Context, channels: Iterable[TextChannel], bots_only: bool = False, user: User = None, regex: Optional[str] = None, until_message: Optional[Message] = None, ) -> None: """A helper function that does the actual message cleaning.""" def predicate_bots_only(message: Message) -> bool: """Return True if the message was sent by a bot.""" return message.author.bot def predicate_specific_user(message: Message) -> bool: """Return True if the message was sent by the user provided in the _clean_messages call.""" return message.author == user def predicate_regex(message: Message) -> bool: """Check if the regex provided in _clean_messages matches the message content or any embed attributes.""" content = [message.content] # Add the content for all embed attributes for embed in message.embeds: content.append(embed.title) content.append(embed.description) content.append(embed.footer.text) content.append(embed.author.name) for field in embed.fields: content.append(field.name) content.append(field.value) # Get rid of empty attributes and turn it into a string content = [attr for attr in content if attr] content = "\n".join(content) # Now let's see if there's a regex match if not content: return False else: return bool(re.search(regex.lower(), content.lower())) # Is this an acceptable amount of messages to clean? if amount > CleanMessages.message_limit: embed = Embed( color=Colour(Colours.soft_red), title=random.choice(NEGATIVE_REPLIES), description=f"You cannot clean more than {CleanMessages.message_limit} messages." ) await ctx.send(embed=embed) return # Are we already performing a clean? if self.cleaning: embed = Embed( color=Colour(Colours.soft_red), title=random.choice(NEGATIVE_REPLIES), description="Please wait for the currently ongoing clean operation to complete." ) await ctx.send(embed=embed) return # Set up the correct predicate if bots_only: predicate = predicate_bots_only # Delete messages from bots elif user: predicate = predicate_specific_user # Delete messages from specific user elif regex: predicate = predicate_regex # Delete messages that match regex else: predicate = None # Delete all messages # Default to using the invoking context's channel if not channels: channels = [ctx.channel] # Delete the invocation first self.mod_log.ignore(Event.message_delete, ctx.message.id) await ctx.message.delete() messages = [] message_ids = [] self.cleaning = True # Find the IDs of the messages to delete. IDs are needed in order to ignore mod log events. for channel in channels: async for message in channel.history(limit=amount): # If at any point the cancel command is invoked, we should stop. if not self.cleaning: return # If we are looking for specific message. if until_message: # we could use ID's here however in case if the message we are looking for gets deleted, # we won't have a way to figure that out thus checking for datetime should be more reliable if message.created_at < until_message.created_at: # means we have found the message until which we were supposed to be deleting. break # Since we will be using `delete_messages` method of a TextChannel and we need message objects to # use it as well as to send logs we will start appending messages here instead adding them from # purge. messages.append(message) # If the message passes predicate, let's save it. if predicate is None or predicate(message): message_ids.append(message.id) self.cleaning = False # Now let's delete the actual messages with purge. self.mod_log.ignore(Event.message_delete, *message_ids) for channel in channels: if until_message: for i in range(0, len(messages), 100): # while purge automatically handles the amount of messages # delete_messages only allows for up to 100 messages at once # thus we need to paginate the amount to always be <= 100 await channel.delete_messages(messages[i:i + 100]) else: messages += await channel.purge(limit=amount, check=predicate) # Reverse the list to restore chronological order if messages: messages = reversed(messages) log_url = await self.mod_log.upload_log(messages, ctx.author.id) else: # Can't build an embed, nothing to clean! embed = Embed( color=Colour(Colours.soft_red), description="No matching messages could be found." ) await ctx.send(embed=embed, delete_after=10) return # Build the embed and send it target_channels = ", ".join(channel.mention for channel in channels) message = ( f"**{len(message_ids)}** messages deleted in {target_channels} by " f"{ctx.author.mention}\n\n" f"A log of the deleted messages can be found [here]({log_url})." ) await self.mod_log.send_log_message( icon_url=Icons.message_bulk_delete, colour=Colour(Colours.soft_red), title="Bulk message delete", text=message, channel_id=Channels.mod_log, )
async def _inspire(ctx: Context): embed = Embed() embed.set_image( url=requests.get("https://inspirobot.me/api?generate=true").text) return await ctx.send(embed=embed)
if user.priv & Privileges.Disallowed: return await ctx.send('This user is banned/restricted!') m = 0 if '-m' in args: m = int(args[args.index('-m') + 1]) if '-rx' in args: rx = Mods.RELAX elif '-ap' in args: rx = Mods.AUTOPILOT else: rx = Mods.NOMOD mode = lbModes(m, rx) stats = user.stats[mode.value] embed = Embed(title='') embed.set_author( name= f'{mode!r} profile for {user.full_name} - {stats.pp}pp (#{stats.rank} // {user.country_iso.upper()}#{stats.country_rank})', url=f'https://{glob.config.domain}/u/{user.id}', icon_url=f'https://countryflags.io/{user.country_iso}/flat/64.png') embed.set_thumbnail(url=f'https://a.{glob.config.domain}/{user.id}') # TODO: finish embed lol return await ctx.send(embed=embed) def setup(bot) -> None: bot.add_cog(asahiBot(bot))
async def ln(self, args, mobj): try: """ Does a AniList search to find requested Light Novel. If there are multiple options, will ask you which one to choose. You will have 10 seconds to respond. Will not return any adult series. """ args = " ".join(args) result = await self.ani_get_options(args, mobj, 'LN') if result: manga = self.anilist.getMangaDetailsById(result) else: manga = self.anilist.getMangaDetails(args) if not manga: await self.error(mobj.channel, "Could not find anything") return embed = Embed( title=manga['title_english'] if manga['title_english'] else manga['title_romaji'] if manga['title_romaji'] else manga['title_japanese'], colour=Color(0x7289da), url= f"https://anilist.co/manga/{manga['id']}/{manga['title_romaji']}" .replace(" ", "%20")) # embed.set_author(name=author.display_name, icon_url=avatar) embed.set_image(url=manga['img']) embed.add_field( name="Length", value= f'{manga["total_chapters"] if manga["total_chapters"] else 0} Chapters, {manga["total_volumes"] if manga["total_volumes"] else 0} Volumes' ) embed.add_field(name="Type", value=manga["type"]) embed.add_field(name="Status", value=manga["airing_status"]) embed.add_field( name="Dates", value= f'{manga["start_date"]} through {manga["end_date"] if manga["end_date"] != "None-None-None" else "present"}' if manga["start_date"] != manga["end_date"] else f'{manga["start_date"]}') if manga["synonyms"]: embed.add_field(name="Synonyms", value=", ".join(manga["synonyms"])) if manga["description"] is None: manga["description"] = "Could not pull synopsis" manga["description"] = re.sub( r'\n\s*\n', '\n\n', unescape(manga["description"]).replace("<br>", "\n")) if len(manga["description"]) > 1000: if "\n" in manga["description"][:965]: manga["description"] = manga[ "description"][:manga["description"][:965].rfind("\n")] else: manga["description"] = manga["description"][:965] manga["description"] += "\nIncomplete synopsis due to length." embed.add_field(name="Synopsis", value=manga["description"]) try: await self.embed(mobj.channel, embed) except BaseException: await self.error( mobj.channel, "Something when trying to format the object. Here is a link to the manga: " + "https://myanimelist.net/manga/{0.id}/{0.title}".format( manga).replace(" ", "%20")) except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] print(exc_type, fname, exc_tb.tb_lineno)
async def action(**kwargs): event_type = kwargs['event_type'] config = kwargs['config'] client = kwargs['client'] if event_type == 'member.unban': # Grab configuration values admin_server_id = config.getint('banpool', 'admin_server_id') admin_chan_name = config.get('banpool', 'admin_chan') admin_server = discord.utils.get(client.guilds, id=admin_server_id) admin_chan = discord.utils.get(admin_server.channels, name=admin_chan_name) user = kwargs['user'] guild = kwargs['guild'] try: result = banpool_manager.is_user_banned(user.id) # User is in banpool, so we need to add an exception if result[1]: logger.debug("member_unban event was caught for banpool ID: {}".format(user.id)) banpool_manager.add_user_to_exceptions(user.id, guild.id) unban_embed = Embed(title="User Exception Added", color=Color.orange()) unban_embed.add_field(name="User Name", value=user.name + "#" + str(user.discriminator), inline=False) unban_embed.add_field(name="Server ID", value=guild.id, inline=True) unban_embed.add_field(name="User ID", value=user.id, inline=True) unban_embed.set_footer(icon_url=guild.icon_url, text=guild.name) await admin_chan.send(embed=unban_embed) # check if the server has an announce channel set, if so, announce the ban announce_chan_id = banpool_config.get_announce_chan(guild.id) if announce_chan_id: announce_chan = discord.utils.get(guild.channels, id=announce_chan_id) announce_embed = Embed(title="User Exception Added", color=Color.orange()) announce_embed.add_field(name="User Name", value=user.name + "#" + str(user.discriminator), inline=True) announce_embed.add_field(name="User Profile", value=f"<@{user.id}>", inline=False) announce_embed.add_field(name="User ID", value=user.id, inline=False) await announce_chan.send(embed=announce_embed) except: logger.error(traceback.format_exc()) if event_type == 'member.join': # Grab configuration values admin_server_id = config.getint('banpool', 'admin_server_id') admin_chan_name = config.get('banpool', 'admin_chan') admin_server = discord.utils.get(client.guilds, id=admin_server_id) admin_chan = discord.utils.get(admin_server.channels, name=admin_chan_name) member = kwargs['member'] guild = member.guild try: result = banpool_manager.is_user_banned(member.id) # The member is banpooled and we might need to ban them if result[1]: # check if the guild is subscribed to any banpool the user is in banpool_list = [p for p in result[0]] is_subscribed = False for pool in banpool_list: check_subscription = banpool_config.is_guild_subscribed(guild.id, pool) if check_subscription: is_subscribed = True target_pool = pool if is_subscribed: banpool_name = target_pool reason = result[0][target_pool].reason logger.debug('member_join was caught for banpool ID: {}'.format(member.id)) user_id = member.id user_name = member.name user_discriminator = member.discriminator server_id = member.guild.id is_exception = banpool_manager.is_user_in_exceptions(user_id, server_id) bot_perms = admin_chan.permissions_for(member.guild.me) if not is_exception and bot_perms.ban_members: logger.debug('member joined is in the banpool and has no exceptions: {}'.format(member.id)) banpool_manager.set_last_knowns(user_id, user_name, user_discriminator) ban_embed = Embed(title="User Banned on Join", color=Color.green()) ban_embed.add_field(name="User Name", value=user_name + "#" + str(user_discriminator), inline=False) ban_embed.add_field(name="Server ID", value=guild.id, inline=True) ban_embed.add_field(name="User ID", value=user_id, inline=True) ban_embed.add_field(name="Banpool Name", value=banpool_name, inline=False) ban_embed.add_field(name="Ban Reason", value=reason, inline=False) ban_embed.set_footer(icon_url=guild.icon_url, text=guild.name) await admin_chan.send(embed=ban_embed) # check if the server has an announce channel set, if so, announce the ban announce_chan_id = banpool_config.get_announce_chan(guild.id) if announce_chan_id: announce_chan = discord.utils.get(guild.channels, id=announce_chan_id) announce_embed = Embed(title="User Banned on Join", color=Color.green()) announce_embed.add_field(name="User Name", value=member.name + "#" + str(member.discriminator), inline=True) announce_embed.add_field(name="Nickname", value=member.nick, inline=True) announce_embed.add_field(name="User Profile", value=f"<@{member.id}>", inline=False) announce_embed.add_field(name="User ID", value=user_id, inline=False) announce_embed.set_footer(icon_url=guild.icon_url, text="See Admin Mains for more details") await announce_chan.send(embed=announce_embed) await guild.ban(member, reason="Banpool Bot [{}] - {}".format(banpool_name, reason)) except: logger.error(traceback.format_exc())
async def ranking(self, ctx): #既に存在する関数名だったらERROR出るのでもし今後コマンドを追加するならコマンド名と同じ関数名にして下さい。 f""" 各種ランキングの表示 各種100位まで表示するようにしております。 10位ごとに勝手にページが分けられます。 f""" try: # ERRORが起きるか起きないか。起きたらexceptに飛ばされる bot = self.bot r_dict = {'0⃣': "プレイヤーランキング", '1⃣': "BOTランキング", '2⃣': "鯖ランキング"} # sqlite_listの中からデータベースに接続したというオブジェクトを取得 _, conn, cur = [sql for sql in self.bot.sqlite_list if ctx.author.id == sql[0]][0] msg = await ctx.send(embed=Embed(description="\n".join([f"{r[0]}:`{r[1]}`" for r in list(r_dict.items())]) + "\n見たい番号を発言してください。").set_author(name="Ranking一覧:")) msg_react = await self.bot.wait_for('message', check=lambda message: message.author == ctx.author and message.content.isdigit() and 0 <= int(message.content) <= len(list(r_dict.keys())) - 1, timeout=10) # await self.bot.wait_for('message')で返ってくるのは文字列型 if msg_react.content == "0": # ユーザーはisbotの中身を0で登録してるのでそこで判断して全データを取得させます。 await cur.execute("select distinct user_id, exp FROM player WHERE isbot =0 ORDER BY exp DESC;") players_rank = "\n".join(["{0}位:[`{1}`] (Lv{2})".format(k, bot.get_user(member[0]), int(math.sqrt(member[1]))) for member, k in zip(await cur.fetchall(), range(1, 101))]) # データ10個ごとにページ分け ranking_msgs = ["\n".join(players_rank.split("\n")[i:i + 10]) for i in range(0, 100, 10)] author = "世界Top100プレイヤー" elif msg_react.content == "1": # BOTはisbotの中身を1で登録してるのでそこで判断して全データを取得させます。 await cur.execute("select distinct user_id, exp FROM player WHERE isbot=1 ORDER BY exp DESC;") players_rank = "\n".join(["{0}位:[`{1}`] (Lv{2})".format(k, bot.get_user(member[0]), int(math.sqrt(member[1]))) for member, k in zip(await cur.fetchall(), range(1, 101))]) # データ10個ごとにページ分け ranking_msgs = ["\n".join(players_rank.split("\n")[i:i + 10]) for i in range(0, 100, 10)] author = "世界Top100ボット" else: server_id = [] # チャンネルのレベル(昇順)にリストを取得します # if not [cc for cc in server_id if c[0] in cc] => 既に鯖がリストに入ってる場合は無視するための処理です # bot.get_guild(c[0]) => その鯖をBOTが取得できるかの処理です。取得できなかった場合はその鯖の情報は無視されます。 await cur.execute('select distinct server_id, boss_level FROM channel_status ORDER BY boss_level DESC;') [server_id.append(c) for c in await cur.fetchall() if not [cc for cc in server_id if c[0] in cc] and bot.get_guild(c[0])] players_rank = "".join(["{0}位:[`{1}`] (Lv{2})\n".format(k, bot.get_guild(c[0]), c[1]) for c, k in zip(server_id, range(1, 101))]) # データ10個ごとにページ分け ranking_msgs = ["\n".join(players_rank.split("\n")[i:i + 10]) for i in range(0, 100, 10)] author = "世界Top100サーバー" if not list(filter(lambda a: a != '', ranking_msgs)): return await ctx.send(embed=Embed(description="まだデータはないようだ...")) embeds = [] for embed in list(filter(lambda a: a != '', ranking_msgs)): embeds.append(Embed(description=embed).set_author(name=author)) await msg.edit(content=f"```diff\n1ページ/{len(embeds)}ページ目を表示中\n見たいページを発言してください。\n30秒経ったら処理は止まります。\n0と発言したら強制的に処理は止まります。```", embed=embeds[0]) while True: # 処理が終わる(return)まで無限ループ try: # ERRORが起きるか起きないか。起きたらexceptに飛ばされる msg_react = await self.bot.wait_for('message', check=lambda m: m.author == ctx.author and m.content.isdigit() and 0 <= int(m.content) <= len(embeds), timeout=30) # await self.bot.wait_for('message')で返ってくるのは文字列型 if msg_react.content == "0": # このcontentの中にはゼロ幅スペースが入っています。Noneでもいいのですが編集者はこっちの方が分かりやすいからこうしています。 return await msg.edit(content="") await msg.edit(content=f"```diff\n{int(msg_react.content)}ページ/{len(embeds)}ページ目を表示中\n見たいページを発言してください。\n30秒経ったら処理は止まります。\n0と発言したら強制的に処理は止まります。```", embed=embeds[int(msg_react.content)-1]) except asyncio.TimeoutError: # wait_forの時間制限を超過した場合 # このcontentの中にはゼロ幅スペースが入っています。Noneでもいいのですが編集者はこっちの方が分かりやすいからこうしています。 return await msg.edit(content="", embed=Embed(title=f"時間切れです...")) except (NotFound, asyncio.TimeoutError, Forbidden): # 編集した際に文字が見つからなかった, wait_forの時間制限を超過した場合, メッセージに接続できなかった return except: # 上のERROR以外のERROR出た場合はtracebackで表示するようにしています。 上手くコマンドが反応しない場合はコンソールを見てね! return print("エラー情報\n" + traceback.format_exc())
async def server(self, ctx: Context) -> None: """ Returns information about the guild the command was run in. Information included: - A brief server description - Server icon - Date server was created (and how long ago that was) - Human member count - Bot count - How many members are online/offline - Current server owner - Boost information """ # Save guild to variable instead of using `ctx.message.guild` each time guild: Guild = ctx.message.guild # Calculate when the guild was created and how long ago that was and present it in a human-friendly format now: datetime = datetime.utcnow() delta: relativedelta = abs(relativedelta(now, guild.created_at)) humanized: str = humanize_delta(delta) created_at: str = guild.created_at.strftime('%d %B %Y') created_ago: str = f'{humanized} ago' # Get guild's icon icon: str = guild.icon_url # Get information about the current members of the guild humans: int = len( [x for x in filter(lambda member: not member.bot, guild.members)]) bots: int = guild.member_count - humans total: int = humans + bots invite: Invite = await self.bot.fetch_invite('discord.gg/RqPtwNxd8h') online: int = invite.approximate_presence_count offline: int = invite.approximate_member_count - invite.approximate_presence_count # Get owner information owner: str = guild.owner.mention # Get server boost information number_of_boosts: int = guild.premium_subscription_count boost_level: int = guild.premium_tier # Declare embed with all fields added embed = Embed( title='Server information', description='SMETCH is a community that helps those in need!', colour=0x00d166).add_field( name='Server was created on:', value=f'{created_at}\n{created_ago}', inline=False ).add_field( name='Member count:', value=f'👥 {humans} humans\n🤖 {bots} bots\nTotal: {total}\ \n<:online:832185731845062716> {online} <:offline:832185762618671164> {offline}', inline=False).add_field( name='Current owner:', value=owner, inline=False ).add_field( name='Current boosts:', value=f'{number_of_boosts} boosts at Level {boost_level}', inline=True).set_thumbnail(url=icon) await ctx.send(embed=embed) return
async def pep_command(self, ctx: Context, pep_number: str): """ Fetches information about a PEP and sends it to the channel. """ if pep_number.isdigit(): pep_number = int(pep_number) else: return await ctx.invoke(self.bot.get_command("help"), "pep") # Newer PEPs are written in RST instead of txt if pep_number > 542: pep_url = f"{self.base_github_pep_url}{pep_number:04}.rst" else: pep_url = f"{self.base_github_pep_url}{pep_number:04}.txt" # Attempt to fetch the PEP log.trace(f"Requesting PEP {pep_number} with {pep_url}") response = await self.bot.http_session.get(pep_url) if response.status == 200: log.trace("PEP found") pep_content = await response.text() # Taken from https://github.com/python/peps/blob/master/pep0/pep.py#L179 pep_header = HeaderParser().parse(StringIO(pep_content)) # Assemble the embed pep_embed = Embed( title=f"**PEP {pep_number} - {pep_header['Title']}**", description=f"[Link]({self.base_pep_url}{pep_number:04})", ) pep_embed.set_thumbnail( url="https://www.python.org/static/opengraph-icon-200x200.png") # Add the interesting information if "Status" in pep_header: pep_embed.add_field(name="Status", value=pep_header["Status"]) if "Python-Version" in pep_header: pep_embed.add_field(name="Python-Version", value=pep_header["Python-Version"]) if "Created" in pep_header: pep_embed.add_field(name="Created", value=pep_header["Created"]) if "Type" in pep_header: pep_embed.add_field(name="Type", value=pep_header["Type"]) elif response.status == 404: log.trace("PEP was not found") not_found = f"PEP {pep_number} does not exist." pep_embed = Embed(title="PEP not found", description=not_found) pep_embed.colour = Colour.red() else: log.trace( f"The user requested PEP {pep_number}, but the response had an unexpected status code: " f"{response.status}.\n{response.text}") error_message = "Unexpected HTTP error during PEP search. Please let us know." pep_embed = Embed(title="Unexpected error", description=error_message) pep_embed.colour = Colour.red() await ctx.message.channel.send(embed=pep_embed)
async def on_message(message): # if message.guild.id != 202845295158099980: return # Testing guild # if message.author.id != 174406433603846145: return # Testing stuff, stop spamming # check if it's even a user if message.author.bot: return #TEMPORARY if message.guild and message.guild.id == 442952794480050177: if message.channel.id == 693792405882929173: # verification try: await message.delete() except: pass if message.content.lower() == 'i agree to the rules': r = discord.utils.get(message.guild.roles, id=693790666249207808) try: await message.author.add_roles(r) except: pass is_mod = await moderator_check_no_ctx(message.author, message.guild, bot) ck = 'censor_list' was_deleted = False if not is_mod: if message.guild and message.guild.id in bot.from_serversetup and bot.from_serversetup[message.guild.id][ck]: if any(w.lower() in bot.from_serversetup[message.guild.id][ck] for w in message.content.lower().split()): await message.delete() was_deleted = True if any(c in message.content.lower() for c in bot.from_serversetup[message.guild.id][ck]) and not was_deleted: await message.delete() was_deleted = True arl = 0 # get anti raid level if message.guild and message.guild.id in bot.anti_raid: arl = bot.anti_raid[message.guild.id]['anti_raid_level'] if arl > 1: # check ping count during raid levels 2 and 3 mention_count = sum(not m.bot and m.id != message.author.id for m in message.mentions) if mention_count > bot.anti_raid[message.guild.id]['max_allowed_mentions']: return await dutils.punish_based_on_arl(arl, message, bot, mentions=True) # it was a dm if not message.guild and message.author.id != bot.config['CLIENT_ID']: arl = -1 # print(f'DM LOG: {str(message.author)} (id: {message.author.id}) sent me this: {message.content}') if not bot.is_ready(): return await message.channel.send("Bot is still starting up, hold on a few seconds.") is_setup = await dutils.dm_log_try_setup(bot) if is_setup: await dutils.dm_log(bot, message) pfx = str(get_pre(bot, message)) if message.content in [f'<@!{bot.config["CLIENT_ID"]}>', f'<@{bot.config["CLIENT_ID"]}>']: return await message.channel.send( embed=(Embed(title='My prefix here is', description=pfx).set_footer(text='You can change it with ' f'{pfx}prefix'))) # is_prefix = message.content.startswith(pfx) or message.content.split(' ')[0] in [f'<@!{bot.config["CLIENT_ID"]}>', # f'<@{bot.config["CLIENT_ID"]}>'] # Check if it's actually a cmd or custom cmd possible_cmd = "" is_actually_cmd = False ctype = -1 # 1 possible_cmd | 2 mutli word | 3 same as 0 but inh | 4 same as 1 but inh if message.content.startswith(f'<@{bot.config["CLIENT_ID"]}>'): pfx_len = len(f'<@{bot.config["CLIENT_ID"]}>') + 1 elif message.content.startswith(f'<@!{bot.config["CLIENT_ID"]}>'): pfx_len = len(f'<@!{bot.config["CLIENT_ID"]}>') + 1 elif message.content.startswith(pfx): pfx_len = len(pfx) else: pfx_len = -1 if pfx_len > 0: possible_cmd = message.content[pfx_len:].split(' ')[0] if possible_cmd in bot.all_commands: is_actually_cmd = True if not is_actually_cmd: if message.guild and message.guild.id in bot.all_cmds: if possible_cmd in bot.all_cmds[message.guild.id]['cmds_name_list']: ctype = 1 elif message.content[pfx_len:] in bot.all_cmds[message.guild.id]['cmds_name_list']: ctype = 2 elif possible_cmd in bot.all_cmds[message.guild.id]['inh_cmds_name_list']: ctype = 3 elif message.content[pfx_len:] in bot.all_cmds[message.guild.id]['inh_cmds_name_list']: ctype = 4 # if it was a command if (is_actually_cmd or ctype > 0) or arl > 1: # catch messages here for anti spam on arl > 1 regardless of cmd if arl in [0, 1]: # If not checking for message spamming and user is blacklisted return if message.author.id in bot.banlist: return if arl in [0, 1]: # user can unblacklist themselves here if (message.author.id in bot.blacklist) and ('unblacklistme' in message.content): if possible_cmd and possible_cmd == 'unblacklistme': if not bot.is_ready(): return await message.channel.send("Bot is still starting up, hold on a few seconds.") if was_deleted: return return await bot.process_commands(message) if arl in [0, 1]: # the journey for the blacklisted end shere if message.author.id in bot.blacklist: return bucket = bot.spam_control[arl].get_bucket(message) current = message.created_at.replace(tzinfo=datetime.timezone.utc).timestamp() retry_after = bucket.update_rate_limit(current) author_id = message.author.id # spamming has started (but ignore moderators though) if retry_after and not is_mod: bot._auto_spam_count[author_id] += 1 d_max = 4 # max number of times they can spam again after bucket triggers if arl > 1: d_max = 2 if bot._auto_spam_count[author_id] >= d_max: # SPAMMER DETECTED HERE! if arl > 1: return await dutils.punish_based_on_arl(arl, message, bot) if possible_cmd != 'unblacklistme' and arl in [0, 1]: del bot._auto_spam_count[author_id] # await self.log_spammer(ctx, message, retry_after, autoblock=True) out = f'[{retry_after} | {message.content}]({message.jump_url})' # print(out) gid = 0 if message.guild: gid = message.guild.id await dutils.blacklist_from_bot(bot, message.author, out, gid, ch_to_reply_at=message.channel, arl=arl) else: out2 = f"{str(message.author)} {datetime.datetime.utcnow().strftime('%c')}" \ f" source: {message.jump_url}" out = f'[{author_id} | {retry_after} |' \ f' {message.content}]({message.jump_url})' if message.author.id not in bot.banlist: await dutils.ban_from_bot(bot, message.author, out2, message.guild.id, message.channel) else: out = f'almost SPAMMER: {author_id} | {retry_after} | {message.content} | {message.jump_url}' bot.logger.info(out) if bot._auto_spam_count[author_id] == d_max - 1: return else: bot._auto_spam_count.pop(author_id, None) arl1_ret = ("The server has set it's raid protection to level 1.\n" f"{message.author.mention} stop using/spamming bot commands " f"for now or else you will get banned from the bot.") sup = None kk = 'disabled_onlyEnabled_cmds_and_chs' if message.guild and message.guild.id in bot.from_serversetup and bot.from_serversetup[message.guild.id][kk]: sup = bot.from_serversetup[message.guild.id][kk] if not is_mod and (is_actually_cmd or ctype > 0) and arl > 1: return # we don't want non mods triggering commands during a raid if was_deleted: return if is_actually_cmd: if arl == 1 and not is_mod: # well, during a lvl 1 raid, we can warn them return await message.channel.send(arl1_ret) if sup and possible_cmd in sup and not is_mod: if message.channel.id in sup[possible_cmd]['dis']: return await message.channel.send("❌ This command is disabled in the following channels:\n" f"{', '.join((message.guild.get_channel(c)).mention for c in sup[possible_cmd]['dis'])}") if sup[possible_cmd]['only_e'] and message.channel.id not in sup[possible_cmd]['only_e']: return await message.channel.send("❌ This command is enabled only in the following channels:\n" f"{', '.join((message.guild.get_channel(c)).mention for c in sup[possible_cmd]['only_e'])}") if not bot.is_ready(): return await message.channel.send("Bot is still starting up, hold on a few seconds.") return await bot.process_commands(message) if ctype != -1: if not bot.is_ready(): return await message.channel.send("Bot is still starting up, hold on a few seconds.") if arl == 1 and not is_mod: return await message.channel.send(arl1_ret) pos_c = '"custom cmds"' if sup and pos_c in sup: if message.channel.id in sup[pos_c]['dis'] and not is_mod: return await message.channel.send("❌ Custom commands are disabled in the following channels:\n" f"{', '.join((message.guild.get_channel(c)).mention for c in sup[pos_c]['dis'])}") if sup[pos_c]['only_e'] and message.channel.id not in sup[pos_c]['only_e']: return await message.channel.send("❌ Custom commands are enabled only in the following channels:\n" f"{', '.join((message.guild.get_channel(c)).mention for c in sup[pos_c]['only_e'])}") if ctype == 1: c = bot.all_cmds[message.guild.id]['cmds'][possible_cmd] elif ctype == 2: c = bot.all_cmds[message.guild.id]['cmds'][message.content[pfx_len:]] elif ctype == 3: for cc in bot.all_cmds[message.guild.id]['inh_cmd_list']: if possible_cmd in cc: c = cc[possible_cmd] elif ctype == 4: for cc in bot.all_cmds[message.guild.id]['inh_cmd_list']: if message.content[pfx_len:] in cc: c = cc[message.content[pfx_len:]] if bool(c['raw']): return await message.channel.send(c['content']) if bool(c['image']): em = Embed(color=int(f'0x{c["color"][-6:]}', 16)) em.set_image(url=c['content']) else: em = Embed(color=int(f'0x{c["color"][-6:]}', 16), description=c['content']) pic = str(c['content']).find('http') if pic > -1: urls = re.findall(r'https?:[/.\w\s-]*\.(?:jpg|gif|png|jpeg)', str(c['content'])) if len(urls) > 0: em.set_image(url=urls[0]) return await message.channel.send(embed=em)
def search_talents_and_feats(self, class_name, query): # Check if cache is populated for this class if not self.class_list[class_name].get("feats", None): self.refresh_class_details(class_name) talents = list( filter( lambda x: str(query).lower() in x.get("name", "").lower(), self.class_list[class_name]["feats"], )) if len(talents) == 1 or query.lower() in list( map(lambda x: x["name"].lower(), talents)): # Only a single talent found, so return all details about it talent = (talents[0] if len(talents) == 1 else list( filter(lambda x: x["name"].lower() == str(query).lower(), talents))[0]) res = Embed( title= f"{talent['name']} -- Level {talent['level']} {class_name.capitalize()} {talent['talentType'].capitalize()}", color=ClassColors(class_name.upper()).value, ) res.add_field(name="Cast Type", value=talent["castTime"], inline=True) res.add_field(name="Duration", value=talent["duration"], inline=True) res.add_field( name="Description", value=html2text(talent["description"]).strip(), inline=False, ) res.add_field( name="Requirements", value="\n".join(talent["requirements"]) if talent["requirements"] else "None", inline=False, ) res.add_field(name="Prerequisite", value=talent["requiredFeat"], inline=False) elif len(talents) >= 1: # User is searching based on a query, so return a list of talents res = Embed(title=f'Features Matching "{query}":', color=Color.dark_gold()) talent_map = { feat_name: [] for feat_name in list( map(lambda x: x["talentType"].capitalize(), talents)) } for talent in list( map( lambda x: { "name": x["name"], "type": x["talentType"].capitalize() }, talents, )): talent_map[talent["type"]].append(talent["name"]) for type, names in talent_map.items(): res.add_field(name=type, value="\n".join(names), inline=False) else: res = Embed( title= f'Feature/ talent not found for class {class_name.capitalize()}: "{query}"', color=Color.red(), ) return res
def noStorageEmbed(member): return Embed(description=f"{member.mention} {no_storage_warning}")