async def invoke(message, arg_stack, botuser): embed = Embed(title=message.guild.name, description=transget('command.server.embed.desc', botuser.user_pref_lang), color=botcommon.key_color_info) embed.set_thumbnail(url=message.guild.icon_url) created = message.guild.created_at.date() embed.add_field(name=transget( 'command.server.embed.field.creation_date.title', botuser.user_pref_lang), value=f"{created.day}.{created.month}.{created.year}") embed.add_field(name=transget('command.server.embed.field.owner.title', botuser.user_pref_lang), value="<@" + str(message.guild.owner_id) + ">") onlinecount = sum(m.status != Status.offline for m in message.guild.members) embed.add_field(name=transget('command.server.embed.field.members.title', botuser.user_pref_lang).format( member_count=message.guild.member_count), value=transget('command.server.embed.field.members.value', botuser.user_pref_lang).format( member_count=onlinecount)) footertext = "Requested by " + str(message.author.name) + "#" \ + str(message.author.discriminator) + " (" \ + str(message.author.id) + ")" embed.set_footer(text=footertext) await message.channel.send(embed=embed)
async def name(message, arg_stack, botuser, channel_obj): if channel_obj['editcount'] >= 2: await message.channel.send( transget("command.voice.edits_used_up", botuser.user_pref_lang)) return False if len(arg_stack) <= 2: await message.channel.send( transget("command.voice.name.missing_name_argument", botuser.user_pref_lang)) return False new_name = " ".join(arg_stack[2:]) new_name = re.sub('[^A-Za-z1-9\\s\\-]', '', new_name) new_name = (new_name[:20]) if len(new_name) > 20 else new_name tc = client.get_channel(channel_obj['textchannel']) vc = client.get_channel(channel_obj['voicechannel']) await tc.edit(name=new_name) await vc.edit(name=new_name) channel_obj['editcount'] += 1 channel_obj['renamed'] = True await message.channel.send( transget("command.voice.name.renamed", botuser.user_pref_lang).format(new_name=new_name)) await message.channel.send( transget("command.voice.edits_notice", botuser.user_pref_lang).format( current_edits=str(channel_obj['editcount']), remaining_edits=str(2 - channel_obj['editcount'])))
async def invoke(message, arg_stack, botuser): if len(arg_stack) < 3: return False else: try: warned_member = await message.guild.fetch_member(arg_stack[1]) except Exception: warned_member = None if warned_member is None: await message.channel.send( transget('command.warn.error.user_not_found', botuser.user_pref_lang)) return False new_warn = UserWarnings(reason=" ".join(arg_stack[2:]), issuer=message.author.id, warned_user=warned_member.id) sqlsession.add(new_warn) sqlsession.commit() warned_botuser = get_user_or_create(warned_member.id) await message.channel.send() try: # REVIEW: This standard translation needs more information in it. await warned_member.send( transget('command.warn.notification.warned', warned_botuser.user_pref_lang)) except Forbidden: await message.channel.send( transget('command.warn.notification.warned.public', warned_botuser.user_pref_lang).format( mention=warned_member.mention)) return True
async def kick(message, arg_stack, botuser, channel_obj): if channel_obj['type'] != "private": await message.channel.send( transget('command.voice.kick.channel_not_private', botuser.user_pref_lang)) return False kick_member = await botcommon.get_member_by_id_or_ping(arg_stack[2]) if kick_member is None: await message.channel.send( transget('command.voice.kick.user_not_found', botuser.user_pref_lang)) return False if kick_member.id == message.author.id: await message.channel.send( transget('command.voice.kick.self_not_permitted', botuser.user_pref_lang)) return False role = botcommon.main_guild.get_role(channel_obj['role']) if role is None: await message.channel.send( transget('command.voice.kick.rolecheck_failed', botuser.user_pref_lang)) return False await kick_member.remove_roles(role) await kick_member.move_to(channel=None) return True
async def toggle(message, arg_stack, botuser, channel_obj): if channel_obj['editcount'] >= 2: await message.channel.send( transget("command.voice.edits_used_up", botuser.user_pref_lang)) return False if channel_obj['type'] == "public": channel_obj['editcount'] += 1 role = botcommon.main_guild.get_role(channel_obj['role']) overwrites = voicecommon.get_private_overwrites(role) vc = client.get_channel(channel_obj['voicechannel']) tc = message.channel await vc.edit(overwrites=overwrites['vc']) await tc.edit(overwrites=overwrites['tc']) await role.edit(name="vc-prv-" + message.author.display_name) if channel_obj['renamed'] is False: await vc.edit(name="Private by " + message.author.display_name) await tc.edit(name="Private by " + message.author.display_name) channel_obj['type'] = "private" await message.channel.send( transget("command.voice.toggle.to_private.success", botuser.user_pref_lang)) await message.channel.send( transget("command.voice.edits_notice", botuser.user_pref_lang).format( current_edits=str(channel_obj['editcount']), remaining_edits=str(2 - channel_obj['editcount']))) return True else: channel_obj['editcount'] += 1 role = botcommon.main_guild.get_role(channel_obj['role']) overwrites = voicecommon.get_public_overwrites(role) vc = client.get_channel(channel_obj['voicechannel']) tc = message.channel await role.edit(name="vc-pub-" + message.author.display_name) if channel_obj['renamed'] is False: await vc.edit(name="Public by " + message.author.display_name, overwrites=overwrites['vc']) await tc.edit(name="Public by " + message.author.display_name, overwrites=overwrites['tc']) else: await vc.edit(overwrites=overwrites['vc']) await tc.edit(overwrites=overwrites['tc']) channel_obj['type'] = "public" await message.channel.send( transget("command.voice.toggle.to_public.success", botuser.user_pref_lang)) await message.channel.send( transget("command.voice.edits_notice", botuser.user_pref_lang).format( current_edits=str(channel_obj['editcount']), remaining_edits=str(2 - channel_obj['editcount']))) return True return False
async def invoke(message, arg_stack, botuser): if len(arg_stack) != 3: return False channel = await botcommon.get_channel_by_id_or_ping(arg_stack[2]) if channel is None: return False channelid = channel.id channelkey = None if arg_stack[1] == "admin": channelkey = botcommon.key_bot_adminchannel elif arg_stack[1] == "log": channelkey = botcommon.key_bot_logchannel elif arg_stack[1] == "apply": channelkey = botcommon.key_bot_applychannel elif arg_stack[1] == "applydest": channelkey = botcommon.key_bot_applydestchannel elif arg_stack[1] == "voice_newpublic": channelkey = botcommon.key_bot_newpublicvoicechannel elif arg_stack[1] == "voice_newprivate": channelkey = botcommon.key_bot_newprivatevoicechannel else: await message.channel.send( transget('command.chanset.info.unknown_channelkey', botuser.user_pref_lang)) channelkey = 'bot_' + arg_stack[1] + '_channel' dbcommon.set_bot_setting(channelkey, channelid) await _log_action(message, arg_stack, botuser, channelkey, channelid) return True
async def _do_general_help(message, arg_stack, botuser): shortprefix = dbcommon.get_bot_setting(botcommon.key_bot_prefix, "$") helpmsg = transget( 'command.help.general_help.header', botuser.user_pref_lang).format( shortprefix=shortprefix) + "\n```md\n" for command in botcommon.registered_bot_commands: cmdimport = importlib.import_module( '.' + command, 'src.dcbot.commands') cmdmeta = cmdimport.CMD_METADATA if botuser.user_permission_level >= cmdmeta['required_permlevel']: helpmsg += "<" + command + "> " + transget( 'command.' + command + '.meta.description', botuser.user_pref_lang) + "\n" helpmsg += "```" await message.channel.send(helpmsg) return True
async def trytolog(message, arg_stack, botuser, embed): logchannel_id = dbcommon.get_bot_setting(key_bot_logchannel, 0) try: logchannel = await client.fetch_channel(logchannel_id) except Exception: await message.channel.send( transget('dcbot.log.error.channel', botuser.user_pref_lang)) await message.channel.send(embed=embed) return else: if logchannel is None: await message.channel.send( transget('dcbot.log.error.channel', botuser.user_pref_lang)) await message.channel.send(embed=embed) return else: await logchannel.send(embed=embed) return
async def transfer(message, arg_stack, botuser, channel_obj): transfer_member = await botcommon.get_member_by_id_or_ping(arg_stack[2]) if transfer_member is None: await message.channel.send( transget('command.voice.transfer.user_not_found', botuser.user_pref_lang)) return False if transfer_member.id == message.author.id: await message.channel.send( transget('command.voice.transfer.self_not_permitted', botuser.user_pref_lang)) return False channel_obj['owner'] = transfer_member.id previous_owner = message.author.mention new_owner = transfer_member.mention await message.channel.send( transget('command.voice.transfer.successful').format( previous_mention=previous_owner, new_mention=new_owner))
async def invoke(message, arg_stack, botuser): if len(arg_stack) != 3: await message.channel.send( transget("command.faq.err.wrongsyntax", botuser.user_pref_lang)) return False question = arg_stack[1] answer = arg_stack[2] embed = Embed(title=question, description=answer, color=botcommon.key_color_info) await message.channel.send(embed=embed) await message.delete()
async def on_ready(): if not botcommon.is_initial_start: print("Bot reconnected to discord after connection loss") return botcommon.is_initial_start = False # Setting the first guild (which is the only guild per definition) to a # commonly accessible variable print("Initializing the bot...") print(f"Setting main guild to {str(client.guilds[0])}") botcommon.main_guild = client.guilds[0] # Place all commands in a register used for the help command print("Getting all enabled commands...") for importer, modname, ispkg in pkgutil.iter_modules(commands.__path__): if not str(modname).startswith('_'): botcommon.registered_bot_commands.append(modname) # Place all message processors in a register to call everyone of them # on every message ever sent print("Getting all enabled message processors...") for importer, modname, ispkg in pkgutil.iter_modules( messageprocessors.__path__): if not str(modname).startswith('_'): botcommon.registered_message_processors.append(modname) print("Starting Hypixel API...") botcommon.hypixel_api = hypixelv2.SkyblockAPI( os.getenv('DD_HYPIXEL_API_KEY', '')) botcommon.hypixel_api.start() print("Starting Challenge Event scheduler...") botcommon.challenge_scheduler = botcommon.ChallengeScheduler() botcommon.challenge_scheduler.start() print("Load previously tracked challenge events") botcommon.challenge_scheduler.load_all_tracked() print("Initializing Signal Handler, Press CTRL+C once (!) to shut down " + "the bot at any time!") signal.signal(signal.SIGINT, signal_handler) # Log the ready-state of the bot in the console. message = transget("dcbot.readymessage").format(client=client.user) print(message)
async def send_init_help(channel_obj, botuser): shortprefix = dbcommon.get_bot_setting(botcommon.key_bot_prefix, "$") tc = client.get_channel(channel_obj['textchannel']) embed = Embed(title=transget("event.voice.inithelp.embed.title", botuser.user_pref_lang), description=transget( "event.voice.inithelp.embed.description", botuser.user_pref_lang), color=botcommon.key_color_info) embed.add_field( name='`' + shortprefix + transget("command.voice.help.toggle.syntax", botuser.user_pref_lang) + '`', value=transget("command.voice.help.toggle.description", botuser.user_pref_lang)) embed.add_field( name='`' + shortprefix + transget("command.voice.help.name.syntax", botuser.user_pref_lang) + '`', value=transget("command.voice.help.name.description", botuser.user_pref_lang)) embed.add_field(name='`' + shortprefix + transget( "command.voice.help.transfer.syntax", botuser.user_pref_lang) + '`', value=transget("command.voice.help.transfer.description", botuser.user_pref_lang)) embed.add_field( name='`' + shortprefix + transget("command.voice.help.invite.syntax", botuser.user_pref_lang) + '`', value=transget("command.voice.help.invite.description", botuser.user_pref_lang)) embed.add_field( name='`' + shortprefix + transget("command.voice.help.kick.syntax", botuser.user_pref_lang) + '`', value=transget("command.voice.help.kick.description", botuser.user_pref_lang)) embed.add_field( name='`' + shortprefix + transget("command.voice.help.close.syntax", botuser.user_pref_lang) + '`', value=transget("command.voice.help.close.description", botuser.user_pref_lang)) embed.add_field(name=transget("event.voice.inithelp.embed.more_info.title", botuser.user_pref_lang), value=transget( "event.voice.inithelp.embed.more_info.value", botuser.user_pref_lang)) await tc.send(embed=embed)
async def invoke(message, arg_stack, botuser): remove_messages = [message] metadata = {'discord_id': message.author.id} if len(arg_stack) == 2 and arg_stack[1] == "on" and \ botuser.user_permission_level >= botcommon.key_permlevel_moderator: # TODO: Check if apply command actually can be enabled! # Key bot_gapplydest_channel must be properly set and available! dbcommon.set_bot_setting("bot_gapply_enabled", "true") # TODO: Log the changing apply state return await _success_and_delete(remove_messages) if len(arg_stack) == 2 and arg_stack[1] == "off" and \ botuser.user_permission_level >= botcommon.key_permlevel_moderator: dbcommon.set_bot_setting("bot_gapply_enabled", "false") # TODO: Log the changing apply state return await _success_and_delete(remove_messages) if dbcommon.get_bot_setting("bot_gapply_enabled", default="false") == "false": remove_messages.append(await message.channel.send( transget('command.apply.err.disabled', botuser.user_pref_lang))) return await _error_and_delete(remove_messages) # Check if command contains no argument (stack size 1) # This means no player name was provided if len(arg_stack) == 1: remove_messages.append(await message.channel.send( transget('command.apply.err.noname', botuser.user_pref_lang))) return await _error_and_delete(remove_messages) # Check if command contains only one argument (stack size 2) # This means no profile name was provided if len(arg_stack) == 2: remove_messages.append(await message.channel.send( transget('command.apply.err.noprofile', botuser.user_pref_lang))) return await _error_and_delete(remove_messages) # Get the player from the Hypixel API hypixelplayer = hypixel.getplayer_by_name(arg_stack[1]) player_uuid = hypixelplayer['player']['uuid'] metadata['mc_username'] = arg_stack[1] metadata['mc_uuid'] = player_uuid # Get a personal applicant message, if provided in command private_message = None if len(arg_stack) > 2: private_message = " ".join(arg_stack[3:]) metadata['private_message'] = private_message # Check if the player actually exists if hypixelplayer['player'] is None: remove_messages.append(await message.channel.send( transget('command.apply.err.playernotfound', botuser.user_pref_lang).format(playername=arg_stack[1]))) return await _error_and_delete(remove_messages) # Build the Socialtag for the applying discord user actual_dc_tag = message.author.name + "#" + message.author.discriminator # Check if the player has linked a discord profile if ('socialMedia' not in hypixelplayer['player']) or \ ('DISCORD' not in hypixelplayer['player']['socialMedia']['links']): remove_messages.append(await message.channel.send( transget( 'command.apply.err.playernotlinked', botuser.user_pref_lang).format(actual_dc_tag=actual_dc_tag))) return await _error_and_delete(remove_messages) # Get the Socialtag the player provided in the Hypixel API api_dc_tag = hypixelplayer['player']['socialMedia']['links']['DISCORD'] # Check if the player has linked actually his own discord profile if api_dc_tag != actual_dc_tag: remove_messages.append(await message.channel.send( transget('command.apply.err.playerwronglinked', botuser.user_pref_lang).format( api_dc_tag=api_dc_tag, actual_dc_tag=actual_dc_tag))) return await _error_and_delete(remove_messages) # Check if provided Profile name actually exists profile_uuid = None for profile in \ hypixelplayer['player']['stats']['SkyBlock']['profiles'].values(): if profile['cute_name'].lower() == arg_stack[2].lower(): profile_uuid = profile['profile_id'] if profile_uuid is None: remove_messages.append(await message.channel.send( transget('command.apply.err.profilenotfound', botuser.user_pref_lang).format(profile=arg_stack[2]))) return await _error_and_delete(remove_messages) metadata['profile_name'] = arg_stack[2] metadata['profile_uuid'] = profile_uuid # Gather profile stats to show if current requirements are met profile_data = None try: profile_data = _get_profile_data(metadata) except Exception: profile_data = None if profile_data is not None: metadata['pdata_err'] = False metadata['slayer_xp'] = profile_data['data']['slayer_xp'] metadata['skill_avg'] = profile_data['data']['average_level'] metadata['alchemy_lvl'] = \ profile_data['data']['levels']['alchemy']['level'] metadata['fairy_souls'] = \ profile_data['data']['fairy_souls']['collected'] else: metadata['pdata_err'] = True # Check for HGG Entries try: hgg_check = hgg.check_hgg_by_uuid(player_uuid) except Exception: hgg_check = "Error" if hgg_check == "Error": metadata['hgg_report_count'] = "Error" elif hgg_check['found'] is False: metadata['hgg_report_count'] = 0 else: metadata['hgg_report_count'] = len(hgg_check['user']['reports']) embed = _create_embed(metadata) if await _send_application(embed) is False: remove_messages.append(await message.channel.send( transget('command.apply.err.sendfailure', botuser.user_pref_lang).format(playername=arg_stack[1]))) return await _error_and_delete(remove_messages) return await _success_and_delete(remove_messages)
async def invoke(message, arg_stack, botuser): embed = Embed( title=transget( 'command.info.embed.title', botuser.user_pref_lang).format( bot_title=transget( 'bot.title', botuser.user_pref_lang)), description=transget( 'command.info.embed.desc', botuser.user_pref_lang), color=0xdfdfdf) embed.set_thumbnail( url=str(client.user.avatar_url)) embed.add_field( name=transget( 'dcbot.features.title', botuser.user_pref_lang), value=transget( 'dcbot.features.features', botuser.user_pref_lang), inline=False) embed.add_field( name=transget( 'command.info.embed.field.author.title', botuser.user_pref_lang), value="<@285720078031388673>", inline=True) embed.add_field( name=transget( 'dcbot.contributor.title', botuser.user_pref_lang), value=transget( 'dcbot.contributor.contributors', botuser.user_pref_lang), inline=True) versiontag = os.popen('git describe --tags --abbrev=0').read().rstrip('\n') versioncommit = os.popen('git rev-parse --short HEAD').read().rstrip('\n') versionstring = str(versiontag) + " (" + str(versioncommit) + ")" embed.add_field( name=transget( 'command.info.embed.field.version.title', botuser.user_pref_lang), value=versionstring, inline=True) embed.add_field( name=transget( 'command.info.embed.field.upstream.title', botuser.user_pref_lang), value=transget( 'command.info.embed.field.upstream.value', botuser.user_pref_lang), inline=False) embed.add_field( name=transget( 'command.info.embed.field.prefix.title', botuser.user_pref_lang), value=transget( 'command.info.embed.field.prefix.value', botuser.user_pref_lang).format( longprefix="<@" + str(client.user.id) + ">", shortprefix=dbcommon.get_bot_setting( botcommon.key_bot_prefix, '$' ) ), inline=True) embed.add_field( name=transget( 'command.info.embed.field.bugreports.title', botuser.user_pref_lang), value=transget( 'command.info.embed.field.bugreports.value', botuser.user_pref_lang), inline=False) footertext = "Requested by " + str(message.author.name) + "#" \ + str(message.author.discriminator) + " (" \ + str(message.author.id) + ")" embed.set_footer(text=footertext) await message.channel.send(embed=embed)
async def on_message_init_mode(message, cmd_arg_stack, init_stage): if not is_command(message.content): return if init_stage == 0: if cmd_arg_stack[0] == "init": newuser = BotUser( user_discord_id=message.author.id, user_pref_lang=botcommon.default_user_preferred_language, user_permission_level=botcommon.key_permlevel_owner) sqlsession.add(newuser) sqlsession.commit() from src.dcbot.commands import chanset await chanset.invoke( message, ['chanset', 'admin', '<#' + str(message.channel.id) + '>'], newuser) dbcommon.set_bot_setting(botcommon.key_bot_mainserver, message.guild.id) dbcommon.set_bot_setting(botcommon.key_bot_init_stage, 1) await message.channel.send( transget('init.stage0.successful', newuser.user_pref_lang)) await message.channel.send( transget('init.stage1.intro', newuser.user_pref_lang)) elif init_stage == 1: currentuser = dbcommon.get_user_or_create(message.author.id) if cmd_arg_stack[0] == "init": await message.channel.send( transget('init.stage1.intro', currentuser.user_pref_lang)) elif cmd_arg_stack[0] == "setprefix": from src.dcbot.commands import setprefix if await setprefix.invoke(message, cmd_arg_stack, currentuser): dbcommon.set_bot_setting(botcommon.key_bot_init_stage, 2) await message.channel.send( transget('init.stage1.successful', currentuser.user_pref_lang)) await message.channel.send( transget('init.stage2.intro', currentuser.user_pref_lang)) elif init_stage == 2: currentuser = dbcommon.get_user_or_create(message.author.id) if cmd_arg_stack[0] == "init": await message.channel.send( transget('init.stage2.intro', currentuser.user_pref_lang)) elif cmd_arg_stack[0] == "chanset": from src.dcbot.commands import chanset if await chanset.invoke(message, cmd_arg_stack, currentuser): dbcommon.set_bot_setting(botcommon.key_bot_init_stage, 3) await message.channel.send( transget('init.stage2.successful', currentuser.user_pref_lang)) await message.channel.send( transget('init.stage3.intro', currentuser.user_pref_lang)) elif init_stage == 3: currentuser = dbcommon.get_user_or_create(message.author.id) if cmd_arg_stack[0] == "init": await message.channel.send( transget('init.stage3.intro', currentuser.user_pref_lang)) if cmd_arg_stack[0] == "addcmdchan": from src.dcbot.commands import addcmdchan if await addcmdchan.invoke(message, cmd_arg_stack, currentuser): dbcommon.set_bot_setting(botcommon.key_bot_init_stage, 4) await message.channel.send( transget('init.stage3.successful', currentuser.user_pref_lang)) await message.channel.send( transget('init.completed', currentuser.user_pref_lang)) elif init_stage == 4: pass