async def cog_before_invoke(self, ctx): # We don't need to ensure extra for the following commands: if ctx.command.name in ("playingin","autodeleteafter","disableplay"): return # General checks for all music player commands - with specifics filtered per command # If Youtube ratelimits - you can disable music globally so only owners can use it player = self.bot.wavelink.get_player(ctx.guild.id) delay = self.settings.getServerStat(ctx.guild, "MusicDeleteDelay", 20) if self.settings.getGlobalStat("DisableMusic",False) and not Utils.is_owner(ctx): # Music is off - and we're not an owner - disconnect if connected, then send the bad news :( self.dict_pop(ctx) if player.is_connected: await player.destroy() await Message.EmbedText(title="♫ Music player is currently disabled!",color=ctx.author,delete_after=delay).send(ctx) raise commands.CommandError("Music Cog: Music disabled.") # Music is enabled - let's make sure we have the right role if not await self._check_role(ctx): raise commands.CommandError("Music Cog: Missing DJ roles.") # If we're just using the join command - we don't need extra checks - they're done in the command itself if ctx.command.name == "join": return # We've got the role - let's join the author's channel if we're playing/shuffling and not connected if ctx.command.name in ("play","shuffle") and not player.is_connected and ctx.author.voice: await player.connect(ctx.author.voice.channel.id) # Let's ensure the bot is connected to voice if not player.is_connected: await Message.EmbedText(title="♫ Not connected to a voice channel!",color=ctx.author,delete_after=delay).send(ctx) raise commands.CommandError("Music Cog: Not connected to a voice channel.") # Let's make sure the caller is connected to voice and the same channel as the bot - or a bot-admin if Utils.is_bot_admin(ctx): return # We good - have enough perms to override whatever if not ctx.author.voice or not ctx.author.voice.channel.id == int(player.channel_id): await Message.EmbedText(title="♫ You have to be in the same voice channel as me to use that!",color=ctx.author,delete_after=delay).send(ctx) raise commands.CommandError("Music Cog: Author not connected to the bot's voice channel.")
async def message(self, message): # Check the message and see if we should allow it - always yes. word_list = self.settings.getServerStat(message.guild, "FilteredWords") if not len(word_list): # No filter return { "Ignore" : False, "Delete" : False } # Check for admin/bot-admin ctx = await self.bot.get_context(message) if Utils.is_bot_admin(ctx): return { "Ignore" : False, "Delete" : False } f = ProfanitiesFilter(word_list, replacements=self.replacements) f.ignore_case = True f.inside_words = True new_msg = f.clean(message.content) if not new_msg == message.content: # Something changed new_msg = "Halo *{}*\nBerdasarkan perhitungan ku, ini adalah versi terbaru dari pesan tersebut:\n".format(DisplayName.name(message.author)) + new_msg em = discord.Embed(color = 0XFF8C00, description = new_msg) em.set_footer(text = "{}#{}".format(ctx.author.name, ctx.author.discriminator), icon_url = "{}".format(ctx.author.avatar_url)) await message.channel.send(new_msg) return { "Ignore" : False, "Delete" : True } return { "Ignore" : False, "Delete" : False }
def _has_privs(self, ctx, l_role="RequiredLinkRole"): if not Utils.is_bot_admin(ctx): required_role = self.settings.getServerStat(ctx.guild, l_role, "") if required_role == "" or not ctx.guild.get_role( int(required_role)) in ctx.author.roles: return False return True
async def message(self, message): # Check for discord invite links and remove them if found - per server settings if not self.dregex.search(message.content): return None # No invite in the passed message - nothing to do # Got an invite - let's see if we care if not self.settings.getServerStat(message.guild,"RemoveInviteLinks",False): return None # We don't care # We *do* care, let's see if the author is admin/bot-admin as they'd have power to post invites ctx = await self.bot.get_context(message) if Utils.is_bot_admin(ctx): return None # We are immune! # At this point - we need to delete the message return { 'Ignore' : True, 'Delete' : True}
async def _check_role(self, ctx): if Utils.is_bot_admin(ctx): return True promoArray = self.settings.getServerStat(ctx.guild, "DJArray", []) delay = self.settings.getServerStat(ctx.guild, "MusicDeleteDelay", 20) if not len(promoArray): await Message.EmbedText(title="♫ There are no DJ roles set yet. Use `{}adddj [role]` to add some.".format(ctx.prefix),color=ctx.author,delete_after=delay).send(ctx) return None for role in promoArray: if ctx.guild.get_role(int(role["ID"])) in ctx.author.roles: return True await Message.EmbedText(title="♫ You need a DJ role to do that!",color=ctx.author,delete_after=delay).send(ctx) return False
async def skip(self, ctx): """Adds your vote to skip the current song. 50% or more of the non-bot users need to vote to skip a song. Original requestors and admins can skip without voting.""" delay = self.settings.getServerStat(ctx.guild, "MusicDeleteDelay", 20) player = self.bot.wavelink.get_player(ctx.guild.id) if not player.is_connected: return await Message.EmbedText(title="♫ Not connected to a voice channel!",color=ctx.author,delete_after=delay).send(ctx) if not player.is_playing: return await Message.EmbedText(title="♫ Not playing anything!",color=ctx.author,delete_after=delay).send(ctx) # Check for added by first, then check admin data = self.data.get(str(ctx.guild.id)) if Utils.is_bot_admin(ctx): self.skip_pop(ctx) return await Message.EmbedText(title="♫ Admin override activated - skipping!",color=ctx.author,delete_after=delay).send(ctx) if data.info.get("added_by",None) == ctx.author: self.skip_pop(ctx) return await Message.EmbedText(title="♫ Requestor chose to skip - skipping!",color=ctx.author,delete_after=delay).send(ctx) # At this point, we're not admin, and not the requestor, let's make sure we're in the same vc if not ctx.author.voice or not ctx.author.voice.channel.id == int(player.channel_id): return await Message.EmbedText(title="♫ You have to be in the same voice channel as me to use that!",color=ctx.author,delete_after=delay).send(ctx) # Do the checking here to validate we can use this and etc. skips = self.skips.get(str(ctx.guild.id),[]) # Relsolve the skips new_skips = [] channel = ctx.guild.get_channel(int(player.channel_id)) if not channel: return await Message.EmbedText(title="♫ Something went wrong!",description="That voice channel doesn't seem to exist anymore...",color=ctx.author,delete_after=delay).send(ctx) for x in skips: member = ctx.guild.get_member(x) if not member or member.bot: continue if not member in channel.members: continue # Got a valid user who's in the skip list and the voice channel new_skips.append(x) # Check if we're not already in the skip list if not ctx.author.id in new_skips: new_skips.append(ctx.author.id) # Let's get the number of valid skippers skippers = [x for x in channel.members if not x.bot] needed_skips = math.ceil(len(skippers)/2) if len(new_skips) >= needed_skips: # Got it! self.skip_pop(ctx) return await Message.EmbedText(title="♫ Skip threshold met ({}/{}) - skipping!".format(len(new_skips),needed_skips),color=ctx.author,delete_after=delay).send(ctx) # Update the skips self.skips[str(ctx.guild.id)] = new_skips await Message.EmbedText(title="♫ Skip threshold not met - {}/{} skip votes entered - need {} more!".format(len(new_skips),needed_skips,needed_skips-len(new_skips)),color=ctx.author,delete_after=delay).send(ctx)
async def message(self, message): # Periksa invite link dan hapus jika ditemukan, lakukan pengecekan tiap server settings if not self.dregex.search(message.content): return None # Jika tidak ada invite pada pesan dari member abaikan saja, return None # Acinonyx mendapatkan invite link dari pesan member, cek apakah Acinonyx harus menghapusnya? if not self.settings.getServerStat(message.guild, "RemoveInviteLinks", False): return None # Nilai False berarti abaikan saja, return None # Acinonyx *memiliki* izin untuk menghapus invite link # cek dulu, apakah pesan itu dari admin server yang memiliki izin untuk melakukan post invite link? ctx = await self.bot.get_context(message) if Utils.is_bot_admin(ctx): return None # Kalau pesan itu dari admin abaikan saja, return None # Disini Acinonyx mendapat invite link tapi bukan dari admin server yang tidak memiliki izin untuk post invite link # hapus saja pesannya return {'Ignore': True, 'Delete': True}
async def gif(self, ctx, *, gif=None): """Search for some giphy!""" if not Utils.is_bot_admin(ctx): gif_array = self.settings.getServerStat(ctx.guild, "GifArray", []) if not any(x for x in gif_array for y in ctx.author.roles if str(x["ID"]) == str(y.id)): return await ctx.send( "You do not have sufficient privileges to access this command." ) if not self.canDisplay(ctx.guild): return if not gif == None: gif = re.sub(r'([^\s\w]|_)+', '', gif) my_gif = None if gif == None: # Random try: my_gif = self.giphy.random_gif() except Exception: my_gif = None else: try: my_gif = random.choice( list(self.giphy.search(phrase=gif, limit=20))) except Exception: my_gif = None if my_gif == None: return await ctx.send("I couldn't get a working link!") try: gif_url = my_gif["original"]["url"].split("?")[0] except: gif_url = None if not gif_url: return await ctx.send("I couldn't get a working link!") try: title = my_gif["raw_data"]["title"] except: title = "Gif for \"{}\"".format(gif) await Message.Embed(title=title, image=gif_url, url=gif_url, color=ctx.author).send(ctx)
async def message(self, message): # Check the message and see if we should allow it. current_ignore = self.settings.getServerStat(message.guild, "IgnoreDeath") if current_ignore: return { 'Ignore' : False, 'Delete' : False } ignore = delete = False hunger = int(self.settings.getServerStat(message.guild, "Hunger")) hungerLock = self.settings.getServerStat(message.guild, "HungerLock") isKill = self.settings.getServerStat(message.guild, "Killed") # Get any commands in the message context = await self.bot.get_context(message) if (isKill or hunger >= 100 and hungerLock): ignore = not context.command or not context.command.name in [ "iskill", "resurrect", "hunger", "feed" ] # Check if admin and override if Utils.is_bot_admin(context): ignore = delete = False return { 'Ignore' : ignore, 'Delete' : delete}
async def autodeleteafter(self, ctx, seconds = None): """Lists or sets the current delay before auto-deleting music related messages (max of 300 seconds). Set to an integer less than 10 to disable auto-deletion. Requires bot-admin or admin to set.""" if not Utils.is_bot_admin(ctx): seconds = None delay = self.settings.getServerStat(ctx.guild, "MusicDeleteDelay", 20) if seconds == None: # List the delay if delay == None: return await Message.EmbedText(title="♫ Music related messages are not auto-deleted!",color=ctx.author).send(ctx) else: return await Message.EmbedText(title="♫ Music related messages are auto-deleted after {} second{}!".format(delay, "" if delay == 1 else "s"),color=ctx.author,delete_after=delay).send(ctx) # Attempting to set it try: real = int(seconds) except: return await Message.EmbedText(title="♫ Seconds must be an integer!",color=ctx.author,delete_after=delay).send(ctx) if real < 10: self.settings.setServerStat(ctx.guild, "MusicDeleteDelay", None) return await Message.EmbedText(title="♫ Music related messages will not be auto-deleted!",color=ctx.author).send(ctx) real = 300 if real > 300 else real self.settings.setServerStat(ctx.guild, "MusicDeleteDelay", real) return await Message.EmbedText(title="♫ Music related messages will be auto-deleted after {} second{}!".format(real, "" if real == 1 else "s"),color=ctx.author,delete_after=real).send(ctx)
async def unqueue(self, ctx): """Removes all songs you've added from the queue (does not include the currently playing song). Admins remove all songs from the queue.""" delay = self.settings.getServerStat(ctx.guild, "MusicDeleteDelay", 20) player = self.bot.wavelink.get_player(ctx.guild.id) if not player.is_connected: return await Message.EmbedText(title="♫ I am not connected to a voice channel!",color=ctx.author,delete_after=delay).send(ctx) queue = self.queue.get(str(ctx.guild.id),[]) if not len(queue): # No songs in queue return await Message.EmbedText(title="♫ No songs in queue!", description="If you want to bypass a currently playing song, use `{}skip` instead.".format(ctx.prefix),color=ctx.author,delete_after=delay).send(ctx) removed = 0 new_queue = [] for song in queue: if song.info.get("added_by",None) == ctx.author or Utils.is_bot_admin(ctx): removed += 1 else: new_queue.append(song) self.queue[str(ctx.guild.id)] = new_queue if removed > 0: return await Message.EmbedText(title="♫ Removed {} song{} from queue!".format(removed,"" if removed == 1 else "s"),color=ctx.author,delete_after=delay).send(ctx) await Message.EmbedText(title="♫ You can only remove songs you requested!", description="Only an admin can remove all queued songs!",color=ctx.author,delete_after=delay).send(ctx)
async def unplay(self, ctx, *, song_number = None): """Removes the passed song number from the queue. You must be the requestor, or an admin to remove it. Does not include the currently playing song.""" delay = self.settings.getServerStat(ctx.guild, "MusicDeleteDelay", 20) player = self.bot.wavelink.get_player(ctx.guild.id) if not player.is_connected: return await Message.EmbedText(title="♫ I am not connected to a voice channel!",color=ctx.author,delete_after=delay).send(ctx) queue = self.queue.get(str(ctx.guild.id),[]) if not len(queue): # No songs in queue return await Message.EmbedText(title="♫ No songs in queue!", description="If you want to bypass a currently playing song, use `{}skip` instead.".format(ctx.prefix),color=ctx.author,delete_after=delay).send(ctx) try: song_number = int(song_number)-1 except: return await Message.EmbedText(title="♫ Not a valid song number!",color=ctx.author,delete_after=delay).send(ctx) if song_number < 0 or song_number > len(queue): return await Message.EmbedText(title="♫ Out of bounds! Song number must be between 2 and {}.".format(len(queue)),color=ctx.author,delete_after=delay).send(ctx) # Get the song at the index song = queue[song_number] if song.info.get("added_by",None) == ctx.author or Utils.is_bot_admin(ctx): queue.pop(song_number) return await Message.EmbedText(title="♫ Removed {} at position {}!".format(song.title,song_number+1),color=ctx.author,delete_after=delay).send(ctx) await Message.EmbedText(title="♫ You can only remove songs you requested!", description="Only {} or an admin can remove that song!".format(song["added_by"].mention),color=ctx.author,delete_after=delay).send(ctx)
async def message(self, message): # Check the message and see if we should allow it - always yes. word_list = self.settings.getServerStat(message.guild, "FilteredWords") if not len(word_list): # No filter return {"Ignore": False, "Delete": False} # Check for admin/bot-admin ctx = await self.bot.get_context(message) if Utils.is_bot_admin(ctx): return {"Ignore": False, "Delete": False} f = ProfanitiesFilter(word_list, replacements=self.replacements) f.ignore_case = True f.inside_words = True new_msg = f.clean(message.content) if not new_msg == message.content: # Something changed new_msg = "Hey *{}*, based on my calculations, here's a cleaner version of that messsage:\n\n".format( DisplayName.name(message.author)) + new_msg await message.channel.send(new_msg) return {"Ignore": False, "Delete": True} return {"Ignore": False, "Delete": False}
async def kick_ban(self, ctx, members_and_reason=None, command_name="kick"): # Helper method to handle the lifting for kick and ban if not await Utils.is_bot_admin_reply(ctx): return if not members_and_reason: return await ctx.send( 'Usage: `{}{} [space delimited member mention] [reason]`'. format(ctx.prefix, command_name)) # Force a mention - we don't want any ambiguity args = members_and_reason.split() # Get our list of targets targets = [] reason = "" for index, item in enumerate(args): if self.mention_re.search(item): # Check if it's a mention # Resolve the member member = ctx.guild.get_member(int(re.sub(r'\W+', '', item))) # If we have an invalid mention - bail - no ambiguity if member is None: return await ctx.send("Invalid mention passed!") # We should have a valid member - let's make sure it's not: # 1. The bot, 2. The command caller, 3. Another bot-admin/admin if member.id == self.bot.user.id: return await ctx.send( "I don't think I want to {} myself...".format( command_name)) if member.id == ctx.author.id: return await ctx.send( "I don't think you really want to {} yourself...". format(command_name)) if Utils.is_bot_admin(ctx, member): return await ctx.send( "You cannot {} other admins!".format(command_name)) targets.append(member) else: # Not a mention - must be the reason, dump the rest of the items into a string # separated by a space reason = " ".join(args[index:]) break if not len(targets): return await ctx.send("No valid members passed!") if len(targets) > 5: return await ctx.send( "You can only {} up to 5 members at once!".format(command_name) ) if not len(reason): return await ctx.send("Reason is required!") # We should have a list of targets, and the reason - let's list them for confirmation # then generate a 4-digit confirmation code that the original requestor needs to confirm # in order to follow through confirmation_code = "".join( [str(random.randint(0, 9)) for x in range(4)]) msg = "**To {} the following member{}:**\n\n{}\n\n**With reason:**\n\n\"{}\"\n\n**Please type:**\n\n`{}`".format( command_name, "" if len(targets) == 1 else "s", "\n".join([x.name + "#" + x.discriminator for x in targets]), reason, confirmation_code) confirmation_message = await Message.EmbedText( title="{} Confirmation".format(command_name.capitalize()), description=msg, color=ctx.author).send(ctx) def check_confirmation(message): return message.channel == ctx.channel and ctx.author == message.author # Just making sure it's the same user/channel try: confirmation_user = await self.bot.wait_for( 'message', timeout=60, check=check_confirmation) except: confirmation_user = "" # Delete the confirmation message await confirmation_message.delete() # Verify the confirmation if not confirmation_user.content == confirmation_code: return await ctx.send("{} cancelled!".format( command_name.capitalize())) # We got the authorization! message = await Message.EmbedText(title="{}ing...".format( "Bann" if command_name == "ban" else "Kick"), color=ctx.author).send(ctx) canned = [] cant = [] command = ctx.guild.ban if command_name == "ban" else ctx.guild.kick for target in targets: try: await command(target, reason="{}#{}: {}".format( ctx.author.name, ctx.author.discriminator, reason)) canned.append(target) except: cant.append(target) msg = "" if len(canned): msg += "**I was ABLE to {}:**\n\n{}\n\n".format( command_name, "\n".join([x.name + "#" + x.discriminator for x in canned])) if len(cant): msg += "**I was UNABLE to {}:**\n\n{}\n\n".format( command_name, "\n".join([x.name + "#" + x.discriminator for x in cant])) await Message.EmbedText(title="{} Results".format( command_name.capitalize()), description=msg).edit(ctx, message)
async def on_reaction_add(self, reaction, member): # Catch reactions and see if they match our list if not type(member) is discord.Member: # Not in a server return # Check if the reaction is added by the bot if member.id == self.bot.user.id: return r = self.settings.getServerStat(member.guild, "QuoteReaction") r_channel = self.settings.getServerStat(member.guild, "QuoteChannel") r_admin = self.settings.getServerStat(member.guild, "QuoteAdminOnly") if r == None or r_channel == None: # Not setup return # Check reactions if not str(reaction.emoji) == r: # Our reaction isn't in there return em = None for reac in reaction.message.reactions: if str(reac) == str(r): em = reac if not em: # Broken for no reason? return ctx = await self.bot.get_context(reaction.message) if em.count > 1: # Our reaction is already here if not r_admin: # We're not worried about admin stuffs # and someone already quoted return # Check for admin/bot-admin if not Utils.is_bot_admin(ctx, member=member): # We ARE worried about admin - and we're not admin... skip return # Iterate through those that reacted and see if any are admin r_users = await reaction.users().flatten() for r_user in r_users: if r_user == member: continue if Utils.is_bot_admin(ctx, member=r_user): # An admin already quoted - skip return else: # This is the first reaction # Check for admin/bot-admin if r_admin and not Utils.is_bot_admin(ctx, member=member): return r_channel = member.guild.get_channel(int(r_channel)) if r_channel == None: # Not a valid channel return if not len(reaction.message.content) and not len( reaction.message.attachments): # Only quote actual text or attachments - no embeds return # Initialize our message msg = reaction.message.content if len(reaction.message.content) else "" if len(reaction.message.attachments): # We have some attachments to work through attach_text = "" for a in reaction.message.attachments: # Add each attachment by name as a link to its own url attach_text += "[{}]({}), ".format(a.filename, a.url) # Remove the last ", " attach_text = attach_text[:-2] msg += "\n\n" + attach_text # Build an embed! e = { "author": reaction.message.author, "pm_after": -1, # Don't pm quotes "description": msg + "\n\nSent by {} in {} | {} | {} UTC".format( reaction.message.author.mention, reaction.message.channel.mention, "[Link](https://discordapp.com/channels/{}/{}/{})".format( reaction.message.guild.id, reaction.message.channel.id, reaction.message.id), reaction.message.created_at.strftime("%I:%M %p")), "color": reaction.message.author, "footer": "Quoted by {}#{}".format(member.name, member.discriminator) } await Message.EmbedText(**e).send(r_channel)
async def temp(self, ctx, member=None, role=None, *, cooldown=None): """Gives the passed member the temporary role for the passed amount of time - needs quotes around member and role (bot-admin only).""" if not await Utils.is_bot_admin_reply(ctx): return if member == None or role == None: msg = 'Usage: `{}temp "[member]" "[role]" [cooldown]`'.format( ctx.prefix) return await ctx.send(msg) # Get member and role member_from_name = DisplayName.memberForName(member, ctx.guild) role_from_name = DisplayName.roleForName(role, ctx.guild) if not member_from_name and not role_from_name: msg = "I couldn't find either the role or member..." return await ctx.send(msg) if not member_from_name: msg = 'I couldn\'t find *{}*...'.format(member) return await ctx.send(Utils.suppressed(ctx, msg)) # Don't allow us to temp admins or bot admins if Utils.is_bot_admin(ctx, member_from_name): return await ctx.send( "You can't apply temp roles to other admins or bot-admins.") if not role_from_name: msg = 'I couldn\'t find *{}*...'.format(role) return await ctx.send(Utils.suppressed(ctx, msg)) # Make sure our role is in the list promoArray = self.settings.getServerStat(ctx.guild, "TempRoleList") if not role_from_name.id in [int(x["ID"]) for x in promoArray]: # No dice return await ctx.send("That role is not in the temp role list!") if cooldown == None: return await ctx.send( "You must specify a time greater than 0 seconds.") if not cooldown == None: # Get the end time end_time = None try: # Get current time - and end time currentTime = int(time.time()) cal = parsedatetime.Calendar() time_struct, parse_status = cal.parse(cooldown) start = datetime(*time_struct[:6]) end = time.mktime(start.timetuple()) # Get the time from now to end time end_time = end - currentTime except: pass if end_time == None: # We didn't get a time return await ctx.send("That time value is invalid.") # Set the cooldown cooldown = end_time if cooldown < 1: return await ctx.send( "You must specify a time greater than 0 seconds.") message = await ctx.send("Applying...") # Here we have a member, role, and end time - apply them! user_roles = self.settings.getUserStat(member_from_name, ctx.guild, "TempRoles") # Check and see if we're overriding a current time found = False temp_role = {} for r in user_roles: if int(r["ID"]) == role_from_name.id: # Already have it - update the cooldown r["Cooldown"] = cooldown + int( time.time()) if cooldown != None else cooldown r["AddedBy"] = ctx.author.id temp_role = r found = True break if not found: # Add it anew temp_role["ID"] = role_from_name.id temp_role["Cooldown"] = cooldown + int( time.time()) if cooldown != None else cooldown temp_role["AddedBy"] = ctx.author.id user_roles.append(temp_role) self.settings.setUserStat(member_from_name, ctx.guild, "TempRoles", user_roles) if not role_from_name in member_from_name.roles: self.settings.role.add_roles(member_from_name, [role_from_name]) if not cooldown == None: # We have a cooldown msg = "*{}* has been given **{}** for *{}*.".format( DisplayName.name(member_from_name), role_from_name.name, ReadableTime.getReadableTimeBetween(0, cooldown)) pm = "You have been given **{}** in *{}* for *{}*".format( role_from_name.name, ctx.guild.name, ReadableTime.getReadableTimeBetween(0, cooldown)) self.bot.loop.create_task( self.check_temp_roles(member_from_name, temp_role)) else: msg = "*{}* has been given **{}** *until further notice*.".format( DisplayName.name(member_from_name), role_from_name.name) pm = "You have been given **{}** in *{} until further notice*.".format( role_from_name.name, ctx.guild.name) # Announce it await message.edit(content=Utils.suppressed(ctx, msg)) # Check if we pm if self.settings.getServerStat(ctx.guild, "TempRolePM"): try: await member_from_name.send(pm) except: pass
async def message(self, message): # Check the message and see if we should allow it - always yes. # This module doesn't need to cancel messages. # Check if our server supports it table = self.settings.getServerStat(message.guild, "TableFlipMute") if not table: return {'Ignore': False, 'Delete': False} # Check for admin status ctx = await self.bot.get_context(message) isAdmin = Utils.is_bot_admin(ctx) # Check if the message contains the flip chars conts = message.content face = table = False table_list = ['┻', '╙', '╨', '╜', 'ǝʃqɐʇ', '┺'] front_list = ['('] back_list = [')', ')'] if any(ext in conts for ext in front_list) and any(ext in conts for ext in back_list): face = True if any(ext in conts for ext in table_list): table = True if face and table: # Contains all characters # Table flip - add time currentTime = int(time.time()) cooldownFinal = currentTime + 60 alreadyMuted = self.settings.getUserStat(message.author, message.guild, "Muted") if not isAdmin: # Check if we're muted already previousCooldown = self.settings.getUserStat( message.author, message.guild, "Cooldown") if not previousCooldown: if alreadyMuted: # We're perma-muted - ignore return {'Ignore': False, 'Delete': False} previousCooldown = 0 if int(previousCooldown) > currentTime: # Already cooling down - add to it. cooldownFinal = previousCooldown + 60 coolText = ReadableTime.getReadableTimeBetween( currentTime, cooldownFinal) res = '┬─┬ ノ( ゜-゜ノ) *{}*, I understand that you\'re frustrated, but we still don\'t flip tables here. Why don\'t you cool down for *{}* instead.'.format( DisplayName.name(message.author), coolText) else: # Not cooling down - start it coolText = ReadableTime.getReadableTimeBetween( currentTime, cooldownFinal) res = '┬─┬ ノ( ゜-゜ノ) *{}*, we don\'t flip tables here. You should cool down for *{}*'.format( DisplayName.name(message.author), coolText) # Do the actual muting await self.mute._mute(message.author, message.guild, cooldownFinal) await message.channel.send(res) return {'Ignore': True, 'Delete': True} return {'Ignore': False, 'Delete': False}
async def kick_ban(self, ctx, members_and_reason=None, command_name="kick"): # Helper method to handle the lifting for kick and ban if not await Utils.is_bot_admin_reply(ctx): return # isOwner = self.settings.isOwner(ctx.author) # if isOwner == False: # return if not members_and_reason: em = discord.Embed( color=0XFF8C00, description="> **Panduan {} member**\n" "> `{}{} [mention member, spasi dibutuhkan jika lebih dari 1 orang] [alasan]`" .format(command_name, ctx.prefix, command_name)) em.set_author( name=f"{command_name}", url="https://acinonyxesports.com", icon_url= "https://cdn.discordapp.com/attachments/518118753226063887/725569194304733435/photo.jpg" ) em.set_footer( text= "Saat mengetik command, tanda [] tidak usah digunakan\n{}#{}". format(ctx.author.name, ctx.author.discriminator), icon_url="{}".format(ctx.author.avatar_url)) return await ctx.send(embed=em) # Force a mention - we don't want any ambiguity args = members_and_reason.split() # Get our list of targets targets = [] reason = "" for index, item in enumerate(args): if self.mention_re.search(item): # Check if it's a mention # Resolve the member member = ctx.guild.get_member(int(re.sub(r'\W+', '', item))) # If we have an invalid mention - bail - no ambiguity msg = "┐( ̄ヘ ̄;)┌\nInvalid mention" em = discord.Embed(color=0XFF8C00, description=msg) em.set_footer(text="{}#{}".format(ctx.author.name, ctx.author.discriminator), icon_url="{}".format(ctx.author.avatar_url)) if member is None: return await ctx.send(embed=em) # We should have a valid member - let's make sure it's not: # 1. The bot, 2. The command caller, 3. Another bot-admin/admin msg = "╥﹏╥ Noooooo\nAku gak mau keluar dari sini!!" em = discord.Embed(color=0XFF8C00, description=msg) em.set_footer(text="{}#{}".format(ctx.author.name, ctx.author.discriminator), icon_url="{}".format(ctx.author.avatar_url)) if member.id == self.bot.user.id: return await ctx.send(embed=em) msg = "( ̄ー ̄;)ゞ\nKok nge{} diri sendiri...?".format( command_name) em = discord.Embed(color=0XFF8C00, description=msg) em.set_footer(text="{}#{}".format(ctx.author.name, ctx.author.discriminator), icon_url="{}".format(ctx.author.avatar_url)) if member.id == ctx.author.id: return await ctx.send(embed=em) msg = "┐( ̄ヘ ̄;)┌\nKamu tidak dapat melakukan {} pada admin lain!".format( command_name) em = discord.Embed(color=0XFF8C00, description=msg) em.set_footer(text="{}#{}".format(ctx.author.name, ctx.author.discriminator), icon_url="{}".format(ctx.author.avatar_url)) if Utils.is_bot_admin(ctx, member): return await ctx.send(embed=em) targets.append(member) else: # Not a mention - must be the reason, dump the rest of the items into a string # separated by a space reason = " ".join(args[index:]) break msg = "┐( ̄ヘ ̄;)┌\nAku tidak dapat menemukan member yang kamu cari" em = discord.Embed(color=0XFF8C00, description=msg) em.set_footer(text="{}#{}".format(ctx.author.name, ctx.author.discriminator), icon_url="{}".format(ctx.author.avatar_url)) if not len(targets): return await ctx.send(embed=em) msg = "┐( ̄ヘ ̄;)┌\nKamu hanya dapat menggunakan {} sampai dengan 5 member dalam 1 command!".format( command_name) em = discord.Embed(color=0XFF8C00, description=msg) em.set_footer(text="{}#{}".format(ctx.author.name, ctx.author.discriminator), icon_url="{}".format(ctx.author.avatar_url)) if len(targets) > 5: return await ctx.send(embed=em) msg = "┐( ̄ヘ ̄;)┌\nAlasan {} dibutuhkan".format(command_name) em = discord.Embed(color=0XFF8C00, description=msg) em.set_footer(text="{}#{}".format(ctx.author.name, ctx.author.discriminator), icon_url="{}".format(ctx.author.avatar_url)) if not len(reason): return await ctx.send(embed=em) # We should have a list of targets, and the reason - let's list them for confirmation # then generate a 4-digit confirmation code that the original requestor needs to confirm # in order to follow through confirmation_code = "".join( [str(random.randint(0, 9)) for x in range(4)]) msg = "**Untuk {} member berikut{}:**\n{}\n\n**Dengan alasan:**\n\"{}\"\n\n**Silahkan ketik:**\n`{}`".format( command_name, "" if len(targets) == 1 else "", "\n".join([x.name + "#" + x.discriminator for x in targets]), reason, confirmation_code) confirmation_message = await Message.EmbedText( title="Konfirmasi {} member".format(command_name.capitalize()), description=msg, color=0XFF8C00).send(ctx) def check_confirmation(message): return message.channel == ctx.channel and ctx.author == message.author # Just making sure it's the same user/channel try: confirmation_user = await self.bot.wait_for( 'message', timeout=60, check=check_confirmation) except: confirmation_user = "" # Delete the confirmation message await confirmation_message.delete() # Verify the confirmation msg = "┐( ̄ヘ ̄;)┌\nKode verifikasi salah.\n{} member dibatalkan!".format( command_name.capitalize()) em = discord.Embed(color=0XFF8C00, description=msg) em.set_footer(text="{}#{}".format(ctx.author.name, ctx.author.discriminator), icon_url="{}".format(ctx.author.avatar_url)) if not confirmation_user.content == confirmation_code: return await ctx.send(embed=em) # We got the authorization! message = await Message.EmbedText(title="{}ing...".format( "Bann" if command_name == "ban" else "Kick"), color=0XFF8C00).send(ctx) canned = [] cant = [] command = ctx.guild.ban if command_name == "ban" else ctx.guild.kick for target in targets: try: await command(target, reason="{}#{}: {}".format( ctx.author.name, ctx.author.discriminator, reason)) canned.append(target) except: cant.append(target) msg = "" if len(canned): msg += "**Aku berhasil {} member berikut:**\n{}\n\n".format( command_name, "\n".join([x.name + "#" + x.discriminator for x in canned])) if len(cant): msg += "**Aku tidak dapat {} member berikut:**\n{}\n\n".format( command_name, "\n".join([x.name + "#" + x.discriminator for x in cant])) await Message.EmbedText(color=0XFF8C00, title="Hasil {}".format( command_name.capitalize()), description=msg).edit(ctx, message)
async def message(self, message): # Check the message and see if we should allow it - always yes. # This module doesn't need to cancel messages. ignore = False delete = False res = None # Check if user is muted isMute = self.settings.getUserStat(message.author, message.guild, "Muted") # Check for admin status ctx = await self.bot.get_context(message) isAdmin = Utils.is_bot_admin(ctx) if isMute: ignore = True delete = True checkTime = self.settings.getUserStat(message.author, message.guild, "Cooldown") if checkTime: checkTime = int(checkTime) currentTime = int(time.time()) # Build our PM if checkTime: # We have a cooldown checkRead = ReadableTime.getReadableTimeBetween( currentTime, checkTime) res = 'You are currently **Muted**. You need to wait *{}* before sending messages in *{}*.'.format( checkRead, self.suppressed(message.guild, message.guild.name)) else: # No cooldown - muted indefinitely res = 'You are still **Muted** in *{}* and cannot send messages until you are **Unmuted**.'.format( self.suppressed(message.guild, message.guild.name)) if checkTime and currentTime >= checkTime: # We have passed the check time ignore = False delete = False res = None self.settings.setUserStat(message.author, message.guild, "Cooldown", None) self.settings.setUserStat(message.author, message.guild, "Muted", False) ignoreList = self.settings.getServerStat(message.guild, "IgnoredUsers") if ignoreList: for user in ignoreList: if not isAdmin and str(message.author.id) == str(user["ID"]): # Found our user - ignored ignore = True adminLock = self.settings.getServerStat(message.guild, "AdminLock") if not isAdmin and adminLock: ignore = True if isAdmin: ignore = False delete = False # Get Owner and OwnerLock ownerLock = self.settings.getGlobalStat("OwnerLock", False) owner = self.settings.isOwner(message.author) # Check if owner exists - and we're in OwnerLock if (not owner) and ownerLock: # Not the owner - ignore ignore = True if not isAdmin and res: # We have a response - PM it await message.author.send(res) return {'Ignore': ignore, 'Delete': delete}
async def message(self, message): # Check the message and see if we should allow it - always yes. # This module doesn't need to cancel messages. # Check if our server supports it table = self.settings.getServerStat(message.guild, "TableFlipMute") if not table: return {'Ignore': False, 'Delete': False} # Check for admin status ctx = await self.bot.get_context(message) isAdmin = Utils.is_bot_admin(ctx) # Check if the message contains the flip chars conts = message.content face = table = False table_list = ['┻', '╙', '╨', '╜', 'ǝʃqɐʇ', '┺'] front_list = ['('] back_list = [')', ')'] if any(ext in conts for ext in front_list) and any(ext in conts for ext in back_list): face = True if any(ext in conts for ext in table_list): table = True if face and table: # Contains all characters # Table flip - add time currentTime = int(time.time()) cooldownFinal = currentTime + 60 alreadyMuted = self.settings.getUserStat(message.author, message.guild, "Muted") if not isAdmin: # Check if we're muted already previousCooldown = self.settings.getUserStat( message.author, message.guild, "Cooldown") if not previousCooldown: if alreadyMuted: # We're perma-muted - ignore return {'Ignore': False, 'Delete': False} previousCooldown = 0 if int(previousCooldown) > currentTime: # Already cooling down - add to it. cooldownFinal = previousCooldown + 60 coolText = ReadableTime.getReadableTimeBetween( currentTime, cooldownFinal) res = '> ┬─┬ ノ( ゜-゜ノ)\n> *{}*, Aku mengerti jika kamu sedang frustasi.\n> Tapi kami tidak melempar meja di server ini\nKenapa kamu tidak menenangkan diri dulu untuk *{}*.'.format( DisplayName.name(message.author), coolText) em = discord.Embed(color=0XFF8C00, description=res) else: # Not cooling down - start it coolText = ReadableTime.getReadableTimeBetween( currentTime, cooldownFinal) res = '> ┬─┬ ノ( ゜-゜ノ)\n> *{}*, kita tidak menggunakan table flip disini.\n> Aku akan membuat kamu cooldown selama *{}*'.format( DisplayName.name(message.author), coolText) em = discord.Embed(color=0XFF8C00, description=res) # Do the actual muting await self.mute._mute(message.author, message.guild, cooldownFinal) await message.channel.send(embed=em) return {'Ignore': True, 'Delete': True} return {'Ignore': False, 'Delete': False}