diff --git a/bot/__pycache__/commandmod.cpython-38.pyc b/bot/__pycache__/commandmod.cpython-38.pyc new file mode 100644 index 0000000..23003c0 Binary files /dev/null and b/bot/__pycache__/commandmod.cpython-38.pyc differ diff --git a/bot/__pycache__/commandmodserver.cpython-38.pyc b/bot/__pycache__/commandmodserver.cpython-38.pyc new file mode 100644 index 0000000..4a9f239 Binary files /dev/null and b/bot/__pycache__/commandmodserver.cpython-38.pyc differ diff --git a/bot/__pycache__/commandowner.cpython-38.pyc b/bot/__pycache__/commandowner.cpython-38.pyc new file mode 100644 index 0000000..928e2ff Binary files /dev/null and b/bot/__pycache__/commandowner.cpython-38.pyc differ diff --git a/bot/__pycache__/commandpoll.cpython-38.pyc b/bot/__pycache__/commandpoll.cpython-38.pyc new file mode 100644 index 0000000..16744fc Binary files /dev/null and b/bot/__pycache__/commandpoll.cpython-38.pyc differ diff --git a/bot/__pycache__/commanduser.cpython-38.pyc b/bot/__pycache__/commanduser.cpython-38.pyc new file mode 100644 index 0000000..82799ff Binary files /dev/null and b/bot/__pycache__/commanduser.cpython-38.pyc differ diff --git a/bot/__pycache__/counter.cpython-38.pyc b/bot/__pycache__/counter.cpython-38.pyc new file mode 100644 index 0000000..ca8d786 Binary files /dev/null and b/bot/__pycache__/counter.cpython-38.pyc differ diff --git a/bot/__pycache__/decorators.cpython-38.pyc b/bot/__pycache__/decorators.cpython-38.pyc new file mode 100644 index 0000000..1402f94 Binary files /dev/null and b/bot/__pycache__/decorators.cpython-38.pyc differ diff --git a/bot/__pycache__/helpfunc.cpython-38.pyc b/bot/__pycache__/helpfunc.cpython-38.pyc new file mode 100644 index 0000000..c5e1c9b Binary files /dev/null and b/bot/__pycache__/helpfunc.cpython-38.pyc differ diff --git a/bot/__pycache__/inspiro.cpython-38.pyc b/bot/__pycache__/inspiro.cpython-38.pyc new file mode 100644 index 0000000..9c17173 Binary files /dev/null and b/bot/__pycache__/inspiro.cpython-38.pyc differ diff --git a/bot/__pycache__/jsonhandel.cpython-38.pyc b/bot/__pycache__/jsonhandel.cpython-38.pyc new file mode 100644 index 0000000..4eb8d6f Binary files /dev/null and b/bot/__pycache__/jsonhandel.cpython-38.pyc differ diff --git a/bot/__pycache__/poll.cpython-38.pyc b/bot/__pycache__/poll.cpython-38.pyc new file mode 100644 index 0000000..00ced7f Binary files /dev/null and b/bot/__pycache__/poll.cpython-38.pyc differ diff --git a/bot/__pycache__/textban.cpython-38.pyc b/bot/__pycache__/textban.cpython-38.pyc new file mode 100644 index 0000000..490aecc Binary files /dev/null and b/bot/__pycache__/textban.cpython-38.pyc differ diff --git a/bot/__pycache__/xpfunk.cpython-38.pyc b/bot/__pycache__/xpfunk.cpython-38.pyc new file mode 100644 index 0000000..65f8e1f Binary files /dev/null and b/bot/__pycache__/xpfunk.cpython-38.pyc differ diff --git a/bot/commandmod.py b/bot/commandmod.py index ed2837c..35c4da8 100644 --- a/bot/commandmod.py +++ b/bot/commandmod.py @@ -1,7 +1,7 @@ import discord from discord.utils import get from discord.ext import commands -from .decorators import isBotMod +from .decorators import isBotModCommand, isBotMod class Commandmod(commands.Cog, name='Bot Mod Commands'): """You need privilage level 1 to use these commands.""" @@ -12,41 +12,27 @@ def __init__(self, bot, helpf, jh, xpf): self.jh = jh self.xpf = xpf - #Adds channel to blacklist - @commands.command(name='addvoiceblacklist', brief='Adds a voice channel to the blacklist.', description='You need privilege level 1 to use this command. You can add a voice channel to the blacklist. The users in blacklisted channels will not get voice XP. As an input you need the channel id, which you can get by rigth clicking on the channel.') - @isBotMod() - async def addblacklist(self, ctx, channelID): - guilde = self.bot.get_guild(self.jh.getFromConfig("guilde")) - channels = self.helpf.getVoiceChannelsFrom(self.jh.getFromConfig("guilde")) - #Test if channel is in Server - if str(channelID) in [str(channel.id) for channel in channels]: - #Try to write in Blacklist - if self.jh.writeToBalcklist(channelID): - channelName = str(self.bot.get_channel(int(channelID))) - message = f"Added {channelName} with id {channelID} to Blacklist. This Voice channel will not be logged." - else: - message = "Channel is already in Blacklist." - else: - message = f"Channel is not in the server {str(guilde)}" - await self.helpf.log(f"{message} from user {ctx.author}",2) - await ctx.send(message) - #Removes channels from blacklist - @commands.command(name='removevoiceblacklist', brief='Removes a voice channel to the blacklist.', description='You need privilege level 1 to use this command. You can remove a voice channel from the blacklist. The users in this channel will get voice XP. As an input you need the channel id, which you can get by rigth clicking on the channel.') - @isBotMod() - async def removeblacklist(self, ctx, channelID): - #Try to remove from Blacklist - if self.jh.removeFromBalcklist(channelID): - channelName = str(self.bot.get_channel(int(channelID))) - message = f"Removed {channelName} with id {channelID} from Blacklist. This Voice channel will be logged." - else: - message = "Channel does not exist or is not in Blacklist" - await self.helpf.log(f"{message} from user {ctx.author}",2) - await ctx.send(message) + """ + ###################################################################### + + Text Whitlist commands and function + + ###################################################################### + """ + + @commands.command(name='textwl') + @isBotModCommand() + async def textwlCommandInterpretor(self, ctx, *inputs): + if inputs[0] == "add": + await self.addtextwhitelist(ctx, inputs[1]) + + elif inputs[0] == "rm": + await self.removetextwhitelist(ctx, inputs[1]) #Adds text channel to whitelist - @commands.command(name='addtextwhitelist', brief='Adds a text channel to the whitelist.', description='You need privilege level 1 to use this command. You can add a text channel to the whitelist. Users writting in channels from the whitelist will get text XP. As an input you need the channel id, which you can get by rigth clicking on the channel.') - @isBotMod() + #@commands.command(name='addtextwhitelist', brief='Adds a text channel to the whitelist.', description='You need privilege level 1 to use this command. You can add a text channel to the whitelist. Users writting in channels from the whitelist will get text XP. As an input you need the channel id, which you can get by rigth clicking on the channel.') + #@isBotMod() async def addtextwhitelist(self, ctx, channelID): guilde = self.bot.get_guild(self.jh.getFromConfig("guilde")) channels = self.helpf.getTextChannelsFrom(self.jh.getFromConfig("guilde")) @@ -64,8 +50,8 @@ async def addtextwhitelist(self, ctx, channelID): await ctx.send(message) #Removes text channel from whitelist - @commands.command(name='removetextwhitelist', brief='Removes a text channel to the whitelist.', description='You need privilege level 1 to use this command. You can remove text channels from the whitelist. Users writting in channels from the whitelist will get not get text XP. As an input you need the channel id, which you can get by rigth clicking on the channel.') - @isBotMod() + #@commands.command(name='removetextwhitelist', brief='Removes a text channel to the whitelist.', description='You need privilege level 1 to use this command. You can remove text channels from the whitelist. Users writting in channels from the whitelist will get not get text XP. As an input you need the channel id, which you can get by rigth clicking on the channel.') + #@isBotMod() async def removetextwhitelist(self, ctx, channelID): #Try to remove from whitelist if self.jh.removeFromWhitelist(channelID): @@ -76,57 +62,65 @@ async def removetextwhitelist(self, ctx, channelID): await self.helpf.log(f"{message} from user {ctx.author}",2) await ctx.send(message) - @commands.command(name='getuserdata', brief='Gives VoiceXP, TextXP and writen messages back.', description='You need privilege level 1 to use this command. Returns UserName, UserID, VoiceXP, TextXP and writen messages back. As an input you need the user id, which you can get by rigth clicking on the user.') - @isBotMod() - async def getUserData(self, ctx, userID): - if self.jh.isInData(userID): - voice = self.jh.getUserVoice(userID) - text = self.jh.getUserText(userID) - textCount = self.jh.getUserTextCount(userID) - message = f"User: {str(self.bot.get_user(int(userID)))} VoiceXP: {voice} TextXP: {text} TextCount: {textCount}" + """ + ###################################################################### + + Voice Blacklist commands and function + + ###################################################################### + """ + + @commands.command(name='voicebl') + @isBotModCommand() + async def voiceblCommandInterpretor(self, ctx, *inputs): + if inputs[0] == "add": + await self.addblacklist(ctx, inputs[1]) + + elif inputs[0] == "rm": + await self.removeblacklist(ctx, inputs[1]) + + #Adds channel to blacklist + #@commands.command(name='addvoiceblacklist', brief='Adds a voice channel to the blacklist.', description='You need privilege level 1 to use this command. You can add a voice channel to the blacklist. The users in blacklisted channels will not get voice XP. As an input you need the channel id, which you can get by rigth clicking on the channel.') + #@isBotMod() + async def addblacklist(self, ctx, channelID): + guilde = self.bot.get_guild(self.jh.getFromConfig("guilde")) + channels = self.helpf.getVoiceChannelsFrom(self.jh.getFromConfig("guilde")) + #Test if channel is in Server + if str(channelID) in [str(channel.id) for channel in channels]: + #Try to write in Blacklist + if self.jh.writeToBalcklist(channelID): + channelName = str(self.bot.get_channel(int(channelID))) + message = f"Added {channelName} with id {channelID} to Blacklist. This Voice channel will not be logged." + else: + message = "Channel is already in Blacklist." else: - user = self.bot.get_user(int(userID)) - message = f"User was not in data. Created user: {user.mention}" + message = f"Channel is not in the server {str(guilde)}" + await self.helpf.log(f"{message} from user {ctx.author}",2) await ctx.send(message) - @commands.command(name='setvoicexp',brief='Sets the voiceXP of a user.', description='You need privilege level 1 to use this command. Sets the voiceXP to the given amount. As an input you need the userID, which you can get by rigth clicking on the user, and the value of the XP.') - @isBotMod() - async def setVoiceXP(self, ctx, userID, amount): - message = "" - if not self.jh.isInData(userID): - message = f"User was not in data. Created user: {self.bot.get_user(int(userID))}\n" - self.jh.addNewDataEntry(userID) - self.jh.setUserVoice(userID, amount) - message += f"Set user {str(self.bot.get_user(int(userID)))} voiceXP to {amount}." - await self.helpf.log(f"User {ctx.author} set user {str(self.bot.get_user(int(userID)))} voiceXP to {amount}.",2) + #Removes channels from blacklist + #@commands.command(name='removevoiceblacklist', brief='Removes a voice channel to the blacklist.', description='You need privilege level 1 to use this command. You can remove a voice channel from the blacklist. The users in this channel will get voice XP. As an input you need the channel id, which you can get by rigth clicking on the channel.') + #@isBotMod() + async def removeblacklist(self, ctx, channelID): + #Try to remove from Blacklist + if self.jh.removeFromBalcklist(channelID): + channelName = str(self.bot.get_channel(int(channelID))) + message = f"Removed {channelName} with id {channelID} from Blacklist. This Voice channel will be logged." + else: + message = "Channel does not exist or is not in Blacklist" + await self.helpf.log(f"{message} from user {ctx.author}",2) await ctx.send(message) - @commands.command(name='settextxp',brief='Sets the textXP of a user.', description='You need privilege level 1 to use this command. Sets the TextXP to the given amount. As an input you need the userID, which you can get by rigth clicking on the user, and the value of the XP.') - @isBotMod() - async def setTextXP(self, ctx, userID, amount): - message = "" - if not self.jh.isInData(userID): - message = f"User was not in data. Created user: {self.bot.get_user(int(userID))}\n" - self.jh.addNewDataEntry(userID) - self.jh.setUserText(userID, amount) - message += f"Set user {str(self.bot.get_user(int(userID)))} textXP to {amount}." - await self.helpf.log(f"User {ctx.author} set user {str(self.bot.get_user(int(userID)))} textXP to {amount}.",2) - await ctx.send(message) + """ + ###################################################################### - @commands.command(name='settextcount',brief='Sets the textCount of a user.', description='You need privilege level 1 to use this command. Sets the TextCount to the given amount. As an input you need the userID, which you can get by rigth clicking on the user, and the value of the XP.') - @isBotMod() - async def setTextCount(self, ctx, userID, amount): - message = "" - if not self.jh.isInData(userID): - message = f"User was not in data. Created user: {self.bot.get_user(int(userID))}\n" - self.jh.addNewDataEntry(userID) - self.jh.setUserTextCount(userID, amount) - message += f"Set user {str(self.bot.get_user(int(userID)))} TextCount to {amount}." - await self.helpf.log(f"User {ctx.author} set user {str(self.bot.get_user(int(userID)))} textCount to {amount}.",2) - await ctx.send(message) + Normal @commads.command functions - @commands.command(name='printdata', brief='Prints the Data of the Users', description='You need privilege level 1 to use this command. Prints the Username, userID, level, voiceXP, textXP and textCount off all users on the server.') - @isBotMod() + ###################################################################### + """ + + @commands.command(name='dp', brief='Prints the Data of the Users', description='You need privilege level 1 to use this command. Prints the Username, userID, level, voiceXP, textXP and textCount off all users on the server.') + @isBotModCommand() async def printData(self,ctx): guilde = str(self.bot.get_guild(int(self.jh.getFromConfig("guilde")))) message = f"Printing data of server {guilde}:\n" @@ -150,19 +144,7 @@ async def printData(self,ctx): print(f"User {ctx.author} prints all data in {ctx.channel}.") await ctx.send(message) - @commands.command(name='removeuser', brief='Removes user from data.', description='You need privilege level 1 to use this command. Removes the userID from the data und save it. As an input you need the userID, which you can get by rigth clicking on the user.') - @isBotMod() - async def removeuser(self, ctx, userID): - if self.jh.removeUserFromData(userID) == 1: - user = self.bot.get_user(int(userID)) - username = "No User" - if user != None: - username = user.name - message = f"Removed User {username} with ID {userID} from Data." - else: - message = f"User with ID {userID} is not in data." - await self.helpf.log(f"User {ctx.author}: {message}",2) - await ctx.send(message) + def setup(bot, helpf, jh, xpf): bot.add_cog(Commandmod(bot, helpf, jh, xpf)) \ No newline at end of file diff --git a/bot/commandmodserver.py b/bot/commandmodserver.py index a0fd8c6..6abc3fa 100644 --- a/bot/commandmodserver.py +++ b/bot/commandmodserver.py @@ -10,7 +10,7 @@ def hasAnyRole(*items): This on pulls the roles from the conffigured guilde and makes the same check as commands.has_any_role(). """ def predicate(ctx): - return Commandmodserver.helpf.hasOneRole(ctx.author.id, [role for role in items]) + return Commandmodserver.helpf.hasOneRole(ctx.author.id, [*items]) return commands.check(predicate) class Commandmodserver(commands.Cog, name='Server Mod Commands'): @@ -26,49 +26,5 @@ def __init__(self, bot, helpf, tban, counter, jh): self.helpf = helpf Commandmodserver.helpf = helpf - @commands.command(name='textban', brief='Textbans a user.', description='You need to be a \'Administrator\' or \'moderator\' to use this command. Can only be used in a private channel and \'log\'.\nAdds a user to the textban-list. The users text-messages will be deletet upon posting them. You can not change the ban time, only unban with \'+textunban\'.\nTo use this command you need the userID, which you can get be rigth-clicking on the person. Also a time is requiered. The time you input will be in seconds. Also a reason is requiered. The reason must be in \"\", otherwise the command wont work.') - @isDM() - @hasAnyRole("CEO","COO") - async def textban(self, ctx, userID, time, reason): - if not self.tban.hasTextBan(userID): - bantime = 0 - try: - bantime = float(time) - except ValueError: - bantime = -1 - if bantime >= 0.1: - user = self.bot.get_user(int(userID)) - guilde = self.bot.get_guild(int(self.jh.getFromConfig("server"))) - member = guilde.get_member(int(userID)) - if user != None: - logchannel = self.bot.get_channel(int(self.jh.getFromConfig("logchannel"))) - await self.helpf.log(f"User {ctx.author.mention} textbaned {user.mention} for {time} h. Reason:\n{reason}",2) - await logchannel.send(f"{user.mention} was textbaned for {time} h.\n**Reason**: {reason}") - await user.send(content=f"You received a textban for {time} h.\n**Reason**: {reason}") - await self.helpf.sendServerModMessage(f"{member.nick} ({user.name}) was textbaned by {guilde.get_member(int(ctx.author.id)).nick} ({ctx.author.name}) for {time} h.\n**Reason**: {reason}") - await self.tban.addTextBan(userID, int(bantime*3600.0)) - #Textban over - await user.send("Your Textban is over. Pay more attention to your behavior in the future.") - else: - await ctx.send(content="ERROR: User does not exist.", delete_after=3600) - else: - await ctx.send(content="ERROR: time is not valid.", delete_after=3600) - else: - await ctx.send(content="ERROR: User has already a textban.", delete_after=3600) - - - @commands.command(name='textunban', brief='Removes textban from user.', description='You need to be a \'Administrator\' or \'moderator\' to use this command. Can only be used in a private channel and \'log\'.\nThis command will remnove a person from the textban-list and the messages from the person wont be removed anymore.\nTo use this command you need the userID, which you can get be rigth-clicking on the person.') - @isDM() - @hasAnyRole("CEO","COO") - async def textunban(self, ctx, userID): - if not self.tban.hasTextBan(ctx.author.id): - if self.tban.removeTextBan(userID): - logchannel = self.bot.get_channel(int(self.jh.getFromConfig("logchannel"))) - user = self.bot.get_user(int(userID)) - await self.helpf.log(f"User {ctx.author.mention} textunbaned {user.mention}",2) - await logchannel.send(f"User {ctx.author.mention} textunbaned {user.mention}") - else: - await ctx.send(content="ERROR: User has no textban.", delete_after=3600) - def setup(bot, helpf, tban, jh): bot.add_cog(Commandpoll(bot, helpf, tban, jh)) diff --git a/bot/commandowner.py b/bot/commandowner.py index a432161..08b4803 100644 --- a/bot/commandowner.py +++ b/bot/commandowner.py @@ -17,19 +17,19 @@ def __init__(self, bot, helpf, tban, jh, xpf): self.tban = tban @commands.command(name='test', pass_context=True, brief='Testing command for programmer.', description='You need privilege level Owner to use this command. Only the programmer knows what happens here.') - @isBotOwner() + @isBotOwnerCommand() async def test(self, ctx): await ctx.send("Geht") await ctx.message.delete() @commands.command(name="ping") - @isBotOwner() + @isBotOwnerCommand() async def ping(self, ctx): await ctx.send("pong") #Starts to log the users in voice channels @commands.command(name='startlog', brief='Starts to log the users on the configured server.', description='You need privilege level 2 to use this command. Gets the connected users of the configured server und increments every minute their voice XP.') - @isBotOwner() + @isBotOwnerCommand() async def startlog(self, ctx): if self.jh.getFromConfig("log") == "False": self.jh.config["log"] = "True" @@ -47,7 +47,7 @@ async def startlog(self, ctx): await ctx.send(f"Bot is logging. Logging state: True") @commands.command(name='stoplog', brief='Stops to log the users on configured server.', description='You need privilege level 2 to use this command. When the bot logs the connective users on the configured server, this command stops the logging process.') - @isBotOwner() + @isBotOwnerCommand() async def stoplog(self, ctx): if self.jh.getFromConfig("log")=="True": guildeID = int(self.jh.getFromConfig("guilde")) @@ -59,7 +59,7 @@ async def stoplog(self, ctx): await ctx.send(f"Bot is NOT logging. Logging state: False") @commands.command(name='stopbot', brief='Shuts down the bot.', description='You need privilege level 2 to use this command. This command shuts the bot down.') - @isBotOwner() + @isBotOwnerCommand() async def stopbot(self, ctx): self.jh.saveConfig() self.jh.saveData() @@ -70,7 +70,7 @@ async def stopbot(self, ctx): sys.exit() @commands.command(name='sendDPD', brief='Sends data protection declaration to channel') - @isBotOwner() + @isBotOwnerCommand() async def sendDPD(self, ctx): binpath = str(os.path.dirname(__file__))[:-4]+"/bin/" string = "" @@ -87,7 +87,7 @@ async def sendDPD(self, ctx): await message.add_reaction("✅") @commands.command(name='sendGR', brief='Sends message to assing roles') - @isBotOwner() + @isBotOwnerCommand() async def sendGiveRoles(self, ctx): text = "**Choose your interest group**\n```You will be given roles based on your interest that grant you access to optional voice- and textchannels.\nInterest: Rolename:\n🎮 gaming gaming\n📚 study-channel student\n👾 development-technology dev-tech\n🏹 single-exchange single\n🤑 gambling-channel gambling\n⚡ bot-development bot-dev```" guilde = self.bot.get_guild(int(self.jh.getFromConfig("guilde"))) @@ -103,7 +103,7 @@ async def sendGiveRoles(self, ctx): await message.add_reaction(emoji) @commands.command(name='changeBotMessage') - @isBotOwner() + @isBotOwnerCommand() async def changeBotMessage(self, ctx, channelID, messageID, text): message = await self.bot.get_channel(int(channelID)).fetch_message(int(messageID)) if (message.author != self.bot.user): @@ -115,7 +115,7 @@ async def changeBotMessage(self, ctx, channelID, messageID, text): await message.edit(content=str(text)) @commands.command(name='addReaction') - @isBotOwner() + @isBotOwnerCommand() async def addReaction(self, ctx, channelID, messageID, emoji): message = await self.bot.get_channel(int(channelID)).fetch_message(int(messageID)) if (message.author != self.bot.user): diff --git a/bot/commandpoll.py b/bot/commandpoll.py index 1b2f11e..e33c700 100644 --- a/bot/commandpoll.py +++ b/bot/commandpoll.py @@ -6,11 +6,15 @@ def hasAnyRole(*items): """ commands.has_any_role() does not work in DM since a users can't have roles. - This on pulls the roles from the conffigured guilde and makes the same check as commands.has_any_role(). + This on pulls the roles from the configured guilde and makes the same check as commands.has_any_role(). """ - def predicate(ctx): - return Commandpoll.helpf.hasOneRole(ctx.author.id, [role for role in items]) - return commands.check(predicate) + def decorator(func): + def wrapper(*args, **kwargs): + if Commandpoll.helpf.hasOneRole(args[1].author.id, [*items]): + return func(*args, **kwargs) + return passFunc() + return wrapper + return decorator class Commandpoll(commands.Cog, name='Poll Commands'): """These Commands are for creating polls.""" @@ -25,7 +29,42 @@ def __init__(self, bot, helpf, poll, jh): self.jh = jh Commandpoll.helpf = helpf - @commands.command(name='poll_create', brief='Creates a new poll.', description='You need to be a \'member\', \'Administrator\' or \'moderator\' to use this command. Can only be used in private messages.\nThis command creates a new poll with given name. The pollID is the lowest possible number available.\nAs an input you have to specify a name. If you want a name with spaces than set the name in \"\". The name can not be longer than 71 characters.') + @commands.command(name='poll') + async def pollCommandInterpretor(self, ctx, *inputs): + if inputs[0] == "close": + await self.poll_close(ctx, inputs[1]) + + elif inputs[0] == "create": + await self.pollCreate(ctx, inputs[1]) + + elif inputs[0] == "list": + await self.pollsList(ctx) + + elif inputs[0] == "close": + await self.poll_close(ctx, inputs[1]) + + elif inputs[0] == "open": + await self.poll_open(ctx, inputs[1]) + + elif inputs[0] == "publish": + await self.poll_publish(ctx, inputs[1]) + + elif inputs[0] == "rm": + await self.poll_remove(ctx, inputs[1]) + + elif inputs[0] == "show": + await self.pollSend(ctx, inputs[1]) + + elif inputs[0] == "op" and inputs[1] == "add": + await self.optionAdd(ctx, *inputs[2:]) + + elif inputs[0] == "op" and inputs[1] == "rm": + await self.polloptionRemove(ctx, *inputs[2:]) + + else: + await ctx.send("Error") + + #@commands.command(name='poll_create', brief='Creates a new poll.', description='You need to be a \'member\', \'Administrator\' or \'moderator\' to use this command. Can only be used in private messages.\nThis command creates a new poll with given name. The pollID is the lowest possible number available.\nAs an input you have to specify a name. If you want a name with spaces than set the name in \"\". The name can not be longer than 71 characters.') @isDM() @hasAnyRole("CEO","COO","chairman") async def pollCreate(self, ctx, pollName): @@ -43,7 +82,7 @@ async def pollCreate(self, ctx, pollName): message = "ERROR: The optionName is to long." await ctx.send(message) - @commands.command(name='poll', brief='Prints a poll.', description='You need to be a \'member\', \'Administrator\' or \'moderator\' to use this command. Can only be used in private messages.\nThis command shows the poll with the given ID with all its options.\nAs an input you need the poll ID, which you can get with \"+polls\".') + #@commands.command(name='poll', brief='Prints a poll.', description='You need to be a \'member\', \'Administrator\' or \'moderator\' to use this command. Can only be used in private messages.\nThis command shows the poll with the given ID with all its options.\nAs an input you need the poll ID, which you can get with \"+polls\".') @isDM() @hasAnyRole("CEO","COO","chairman") async def pollSend(self, ctx, pollID): @@ -55,7 +94,7 @@ async def pollSend(self, ctx, pollID): message = "ERROR: Poll does not exists. Check +polls for active polls." await ctx.send(message) - @commands.command(name='polloption_add', brief="Adds a poll option to vote for.", description='You need to be a \'member\', \'Administrator\' or \'moderator\' to use this command. Can only be used in private messages. The status of the poll must be \'CLOSED\' to use this command.\nThis command adds a option with name to vote for into the poll with the given ID. You can only add up to 7 options.The number of the option is always the lowest available.\nAs an input you need the poll ID, which you can get with \"+polls\", and the option Name. When you want a option with spaces in it, then set the name in \"\". The name can not be longer than 112 characters.') + #@commands.command(name='polloption_add', brief="Adds a poll option to vote for.", description='You need to be a \'member\', \'Administrator\' or \'moderator\' to use this command. Can only be used in private messages. The status of the poll must be \'CLOSED\' to use this command.\nThis command adds a option with name to vote for into the poll with the given ID. You can only add up to 7 options.The number of the option is always the lowest available.\nAs an input you need the poll ID, which you can get with \"+polls\", and the option Name. When you want a option with spaces in it, then set the name in \"\". The name can not be longer than 112 characters.') @isDM() @hasAnyRole("CEO","COO","chairman") async def optionAdd(self, ctx, pollID, optionName): @@ -72,7 +111,7 @@ async def optionAdd(self, ctx, pollID, optionName): message = "ERROR: Poll does not exists. Check +polls for active polls." await ctx.send(message) - @commands.command(name='polloption_remove', brief='Removes an option from a poll.', description='You need to be a \'member\', \'Administrator\' or \'moderator\' to use this command. Can only be used in private messages. The status of the poll must be \'CLOSED\' to use this command.\nThis command removes a option with the spefified name for the poll with the given ID.\nAs an input you need the poll ID, which you can get with \"+polls\", and the option Name, which you can get with \"+poll pollID\".') + #@commands.command(name='polloption_remove', brief='Removes an option from a poll.', description='You need to be a \'member\', \'Administrator\' or \'moderator\' to use this command. Can only be used in private messages. The status of the poll must be \'CLOSED\' to use this command.\nThis command removes a option with the spefified name for the poll with the given ID.\nAs an input you need the poll ID, which you can get with \"+polls\", and the option Name, which you can get with \"+poll pollID\".') @isDM() @hasAnyRole("CEO","COO","chairman") async def polloptionRemove(self, ctx, pollID, optionName): @@ -86,7 +125,7 @@ async def polloptionRemove(self, ctx, pollID, optionName): message = "ERROR: Poll does not exists. Check +polls for active polls." await ctx.send(message) - @commands.command(name='polls', brief='Gives a brief list of all polls.', description='You need to be a \'member\', \'Administrator\', \'moderator\' or \'friend\' to use this command. Can only be used in private messages or in te spam-channel.\nThis command shows you the header of all stored polls.') + #@commands.command(name='polls', brief='Gives a brief list of all polls.', description='You need to be a \'member\', \'Administrator\', \'moderator\' or \'friend\' to use this command. Can only be used in private messages or in te spam-channel.\nThis command shows you the header of all stored polls.') @isInChannelOrDM("🚮spam") @hasAnyRole("CEO","COO","chairman","associate") async def pollsList(self, ctx): @@ -98,7 +137,7 @@ async def pollsList(self, ctx): message = "No active polls." await ctx.send(message) - @commands.command(name='poll_remove', brief='Removes a poll.', description='You need to be a \'member\', \'Administrator\' or \'moderator\' to use this command. Can only be used in private messages.\nThis command removes a poll completely from the storage. Can only be used if the poll is cloesed. Also it is not possible for users with no PrivilegeLevel to remove a poll while it has options. A message will then be send to an authorized to remove to poll. \nAs an input you need the poll ID, which you can get with \"+polls\".') + #@commands.command(name='poll_remove', brief='Removes a poll.', description='You need to be a \'member\', \'Administrator\' or \'moderator\' to use this command. Can only be used in private messages.\nThis command removes a poll completely from the storage. Can only be used if the poll is cloesed. Also it is not possible for users with no PrivilegeLevel to remove a poll while it has options. A message will then be send to an authorized to remove to poll. \nAs an input you need the poll ID, which you can get with \"+polls\".') @isDM() @hasAnyRole("CEO","COO","chairman") async def poll_remove(self, ctx, pollID): @@ -124,7 +163,7 @@ async def poll_remove(self, ctx, pollID): await ctx.send(message) - @commands.command(name='poll_open', brief='Opens a poll for votes.', description='You need to be a \'member\', \'Administrator\' or \'moderator\' to use this command. Can only be used text-channels other than \'level\', \'info\', \'log\'. The status of the poll must be \'CLOSED\' or \'OPEN\' to use this command.\nThis command will post the poll (as seen in \'+poll\') to the text-channel. If the poll is already \'OPEN\' the previous version will be deleted from the channel and reposted. Also reactions will be added to vote with. You can change your vote as often as you like.This can sometimes break if to many users vote at once without waiting for reactions to be added. \nAs an input you need the poll ID, which you can get with \"+polls\".') + #@commands.command(name='poll_open', brief='Opens a poll for votes.', description='You need to be a \'member\', \'Administrator\' or \'moderator\' to use this command. Can only be used text-channels other than \'level\', \'info\', \'log\'. The status of the poll must be \'CLOSED\' or \'OPEN\' to use this command.\nThis command will post the poll (as seen in \'+poll\') to the text-channel. If the poll is already \'OPEN\' the previous version will be deleted from the channel and reposted. Also reactions will be added to vote with. You can change your vote as often as you like.This can sometimes break if to many users vote at once without waiting for reactions to be added. \nAs an input you need the poll ID, which you can get with \"+polls\".') @isNotInChannelOrDM("📂log","📢info","⏫level") @hasAnyRole("CEO","COO","chairman") async def poll_open(self, ctx, pollID): @@ -148,7 +187,7 @@ async def poll_open(self, ctx, pollID): await self.helpf.log(f"User {ctx.author.mention} opened the poll {pollID} in channel {ctx.channel.name}.",1) await ctx.message.delete() - @commands.command(name='poll_close', brief='Closes a poll.', description='You need to be a \'member\', \'Administrator\' or \'moderator\' to use this command. Can only be used in private channels. The status of the poll must be \'OPEN\' to use this command.\nThis command will close a poll again. Then yo are free to manipulate the poll. \nAs an input you need the poll ID, which you can get with \"+polls\".') + #@commands.command(name='poll_close', brief='Closes a poll.', description='You need to be a \'member\', \'Administrator\' or \'moderator\' to use this command. Can only be used in private channels. The status of the poll must be \'OPEN\' to use this command.\nThis command will close a poll again. Then yo are free to manipulate the poll. \nAs an input you need the poll ID, which you can get with \"+polls\".') @isDM() @hasAnyRole("CEO","COO","chairman") async def poll_close(self, ctx, pollID): @@ -164,7 +203,7 @@ async def poll_close(self, ctx, pollID): else: await ctx.send("ERROR: Can't close Poll") - @commands.command(name='poll_publish', brief='Publish a poll.', description='You need to be a \'member\', \'Administrator\' or \'moderator\' to use this command. Can only be used text-channels other than \'level\', \'info\', \'log\'. The status of the poll must be \'OPEN\' to use this command.\nThis command will post the finished poll to the text channel and will be ordered by the amount of votes. The previously opened poll will be delete. \nAs an input you need the poll ID, which you can get with \"+polls\".') + #@commands.command(name='poll_publish', brief='Publish a poll.', description='You need to be a \'member\', \'Administrator\' or \'moderator\' to use this command. Can only be used text-channels other than \'level\', \'info\', \'log\'. The status of the poll must be \'OPEN\' to use this command.\nThis command will post the finished poll to the text channel and will be ordered by the amount of votes. The previously opened poll will be delete. \nAs an input you need the poll ID, which you can get with \"+polls\".') @isNotInChannelOrDM("📂log","📢info","⏫level") @hasAnyRole("CEO","COO","chairman") async def poll_publish(self, ctx, pollID): diff --git a/bot/commanduser.py b/bot/commanduser.py index 5c6846f..446c476 100644 --- a/bot/commanduser.py +++ b/bot/commanduser.py @@ -5,17 +5,195 @@ from .decorators import * +def hasAnyRole(*items): + """ + Only use for commands, which don't use @commands.command + commands.has_any_role() does not work in DM since a users can't have roles. + This on pulls the roles from the configured guilde and makes the same check as commands.has_any_role(). + """ + def decorator(func): + def wrapper(*args, **kwargs): + if Commanduser.helpf.hasOneRole(args[1].author.id, [*items]): + return func(*args, **kwargs) + return passFunc() + return wrapper + return decorator + class Commanduser(commands.Cog, name='User Commands'): """These Commands are available for all users.""" - def __init__(self, bot, helpf, jh, xpf): + + helpf = None + + def __init__(self, bot, helpf, tban, jh, xpf): super(Commanduser, self).__init__() self.bot = bot self.helpf = helpf self.jh = jh + self.tban = tban self.xpf = xpf - + Commanduser.helpf = helpf + + @commands.command(name='user') + async def userCommandsInterpretor(self, ctx, *inputs): + if inputs[0] == "get": + await self.getUserData(ctx, inputs[1]) + + elif inputs[0] == "rm": + await self.removeuser(ctx, inputs[1]) + + elif inputs[0] == "set" and inputs[1] == "tc": + await self.setTextCount(ctx, inputs[2], inputs[3]) + + elif inputs[0] == "set" and inputs[1] == "text": + await self.setTextXP(ctx, inputs[2], inputs[3]) + + elif inputs[0] == "set" and inputs[1] == "voice": + await self.setVoiceXP(ctx, inputs[2], inputs[3]) + + elif inputs[0] == "tb" and inputs[1] == "add": + await self.textban(ctx, inputs[2], inputs[3], inputs[4]) + + elif inputs[0] == "tb" and inputs[1] == "rm": + await self.textunban(ctx, inputs[2]) + + + + """ + ###################################################################### + + Bot Mod user commands + + ###################################################################### + """ + + #@commands.command(name='getuserdata', brief='Gives VoiceXP, TextXP and writen messages back.', description='You need privilege level 1 to use this command. Returns UserName, UserID, VoiceXP, TextXP and writen messages back. As an input you need the user id, which you can get by rigth clicking on the user.') + @isBotMod() + async def getUserData(self, ctx, userID): + if self.jh.isInData(userID): + voice = self.jh.getUserVoice(userID) + text = self.jh.getUserText(userID) + textCount = self.jh.getUserTextCount(userID) + message = f"User: {str(self.bot.get_user(int(userID)))} VoiceXP: {voice} TextXP: {text} TextCount: {textCount}" + else: + user = self.bot.get_user(int(userID)) + message = f"User was not in data. Created user: {user.mention}" + await ctx.send(message) + + #@commands.command(name='setvoicexp',brief='Sets the voiceXP of a user.', description='You need privilege level 1 to use this command. Sets the voiceXP to the given amount. As an input you need the userID, which you can get by rigth clicking on the user, and the value of the XP.') + @isBotMod() + async def setVoiceXP(self, ctx, userID, amount): + message = "" + if not self.jh.isInData(userID): + message = f"User was not in data. Created user: {self.bot.get_user(int(userID))}\n" + self.jh.addNewDataEntry(userID) + self.jh.setUserVoice(userID, amount) + message += f"Set user {str(self.bot.get_user(int(userID)))} voiceXP to {amount}." + await self.helpf.log(f"User {ctx.author} set user {str(self.bot.get_user(int(userID)))} voiceXP to {amount}.",2) + await ctx.send(message) + + #@commands.command(name='settextxp',brief='Sets the textXP of a user.', description='You need privilege level 1 to use this command. Sets the TextXP to the given amount. As an input you need the userID, which you can get by rigth clicking on the user, and the value of the XP.') + @isBotMod() + async def setTextXP(self, ctx, userID, amount): + message = "" + if not self.jh.isInData(userID): + message = f"User was not in data. Created user: {self.bot.get_user(int(userID))}\n" + self.jh.addNewDataEntry(userID) + self.jh.setUserText(userID, amount) + message += f"Set user {str(self.bot.get_user(int(userID)))} textXP to {amount}." + await self.helpf.log(f"User {ctx.author} set user {str(self.bot.get_user(int(userID)))} textXP to {amount}.",2) + await ctx.send(message) + + #@commands.command(name='settextcount',brief='Sets the textCount of a user.', description='You need privilege level 1 to use this command. Sets the TextCount to the given amount. As an input you need the userID, which you can get by rigth clicking on the user, and the value of the XP.') + @isBotMod() + async def setTextCount(self, ctx, userID, amount): + message = "" + if not self.jh.isInData(userID): + message = f"User was not in data. Created user: {self.bot.get_user(int(userID))}\n" + self.jh.addNewDataEntry(userID) + self.jh.setUserTextCount(userID, amount) + message += f"Set user {str(self.bot.get_user(int(userID)))} TextCount to {amount}." + await self.helpf.log(f"User {ctx.author} set user {str(self.bot.get_user(int(userID)))} textCount to {amount}.",2) + await ctx.send(message) + + #@commands.command(name='removeuser', brief='Removes user from data.', description='You need privilege level 1 to use this command. Removes the userID from the data und save it. As an input you need the userID, which you can get by rigth clicking on the user.') + @isBotMod() + async def removeuser(self, ctx, userID): + if self.jh.removeUserFromData(userID) == 1: + user = self.bot.get_user(int(userID)) + username = "No User" + if user != None: + username = user.name + message = f"Removed User {username} with ID {userID} from Data." + else: + message = f"User with ID {userID} is not in data." + await self.helpf.log(f"User {ctx.author}: {message}",2) + await ctx.send(message) + + + + """ + ###################################################################### + + Guilde Mod user commands + + ###################################################################### + """ + + #@commands.command(name='textban', brief='Textbans a user.', description='You need to be a \'Administrator\' or \'moderator\' to use this command. Can only be used in a private channel and \'log\'.\nAdds a user to the textban-list. The users text-messages will be deletet upon posting them. You can not change the ban time, only unban with \'+textunban\'.\nTo use this command you need the userID, which you can get be rigth-clicking on the person. Also a time is requiered. The time you input will be in seconds. Also a reason is requiered. The reason must be in \"\", otherwise the command wont work.') + @isDM() + @hasAnyRole("CEO","COO") + async def textban(self, ctx, userID, time, reason): + if not self.tban.hasTextBan(userID): + bantime = 0 + try: + bantime = float(time) + except ValueError: + bantime = -1 + if bantime >= 0.1: + user = self.bot.get_user(int(userID)) + guilde = self.bot.get_guild(int(self.jh.getFromConfig("guilde"))) + member = guilde.get_member(int(userID)) + if user != None: + logchannel = self.bot.get_channel(int(self.jh.getFromConfig("logchannel"))) + await self.helpf.log(f"User {ctx.author.mention} textbaned {user.mention} for {time} h. Reason:\n{reason}",2) + await logchannel.send(f"{user.mention} was textbaned for {time} h.\n**Reason**: {reason}") + await user.send(content=f"You received a textban for {time} h.\n**Reason**: {reason}") + await self.helpf.sendServerModMessage(f"{member.nick} ({user.name}) was textbaned by {guilde.get_member(int(ctx.author.id)).nick} ({ctx.author.name}) for {time} h.\n**Reason**: {reason}") + await self.tban.addTextBan(userID, int(bantime*3600.0)) + #Textban over + await user.send("Your Textban is over. Pay more attention to your behavior in the future.") + else: + await ctx.send(content="ERROR: User does not exist.", delete_after=3600) + else: + await ctx.send(content="ERROR: time is not valid.", delete_after=3600) + else: + await ctx.send(content="ERROR: User has already a textban.", delete_after=3600) + + + #@commands.command(name='textunban', brief='Removes textban from user.', description='You need to be a \'Administrator\' or \'moderator\' to use this command. Can only be used in a private channel and \'log\'.\nThis command will remnove a person from the textban-list and the messages from the person wont be removed anymore.\nTo use this command you need the userID, which you can get be rigth-clicking on the person.') + @isDM() + @hasAnyRole("CEO","COO") + async def textunban(self, ctx, userID): + if not self.tban.hasTextBan(ctx.author.id): + if self.tban.removeTextBan(userID): + logchannel = self.bot.get_channel(int(self.jh.getFromConfig("logchannel"))) + user = self.bot.get_user(int(userID)) + await self.helpf.log(f"User {ctx.author.mention} textunbaned {user.mention}",2) + await logchannel.send(f"User {ctx.author.mention} textunbaned {user.mention}") + else: + await ctx.send(content="ERROR: User has no textban.", delete_after=3600) + + + """ + ###################################################################### + + Normal @commads.command functions + + ###################################################################### + """ + @commands.command(name='level', pass_context=True, brief='Returns the level of a player.', description='You need privilege level 0 to use this command. Returns the users level on the configured server. The higher the level, the more roles you will get. Can only be used in the level Channel') - @isInChannel("⏫level") + @isInChannelCommand("⏫level") async def getLevel(self, ctx): userID = ctx.author.id server = self.bot.get_guild(int(self.jh.getFromConfig("guilde"))) @@ -39,7 +217,7 @@ async def getLevel(self, ctx): await ctx.message.delete() @commands.command(name='top',brief='Sends an interactive rank list.', description='You need privilege level 0 to use this command. Sends a list of the top 10 users orderd by XP. By klicking on ⏫, you jump to the first page, on ⬅, you go one page back, on ➡, you go one page further, on ⏰, you order by time, on 💌, you order by messages sent, and on 🌟, you order by XP. Can only be used in the level Channel') - @isInChannel("⏫level") + @isInChannelCommand("⏫level") async def leaderboard(self, ctx): await self.helpf.log(f"+top by {ctx.author}",1) #Notify Mods #Create leaderboard @@ -51,7 +229,7 @@ async def leaderboard(self, ctx): await ctx.message.delete() @commands.command(name='quote', brief='Sends an unique inspirational quote.', description='You need privilege level 0 to use this command. Sends a random quote from inspirobot.me. Can only be used in the Spam Channel.') - @isInChannel("🚮spam") + @isInChannelCommand("🚮spam") async def getPicture(self, ctx): inspiro = Inspiro() url = inspiro.getPictureUrl() @@ -88,6 +266,7 @@ async def reclaimData(self, ctx, voice, text, textCount, code, hash): async def memeResponse(self, ctx): message = "Lieber User,\nder Command nach dem du suchst ist '+ meme'.\nAn die Person, die sich gedacht hat, es sei eine gute Idee das Prefix von Dankmemer Bot soll '+' sein, you suck.\nDer Bot hat gesprochen!" await ctx.send(message) + def setup(bot, helpf, jh, xpf): bot.add_cog(Commandmod(bot, helpf, jh, xpf)) \ No newline at end of file diff --git a/bot/decorators.py b/bot/decorators.py index 389ea69..4af4163 100644 --- a/bot/decorators.py +++ b/bot/decorators.py @@ -5,26 +5,113 @@ from .helpfunc import Helpfunc """ -Following functions are ment to use as decorators +Following functions are ment to use as decorators, when not using @commands.command """ + +def isBotOwner(): + def decorator(func): + def wrapper(*args, **kwargs): + jh = Jsonhandel() + if jh.getPrivilegeLevel(args[1].author.id) >= 2: + return func(*args, **kwargs) + return sendCTX(args[1], "Not permitted") + return wrapper + return decorator + def isBotMod(): + def decorator(func): + def wrapper(*args, **kwargs): + jh = Jsonhandel() + if jh.getPrivilegeLevel(args[1].author.id) >= 1: + return func(*args, **kwargs) + return sendCTX(args[1], "Not permitted") + return wrapper + return decorator + +def isDM(): + def decorator(func): + def wrapper(*args, **kwargs): + if isinstance(args[1].channel, discord.channel.DMChannel): + return func(*args, **kwargs) + return passFunc() + return wrapper + return decorator + +def isInChannel(*items): + def decorator(func): + def wrapper(*args, **kwargs): + dm = isinstance(args[1].channel, discord.channel.DMChannel) + if not dm and (args[1].channel.id in items or args[1].channel.name in items): + return func(*args, **kwargs) + return passFunc() + return wrapper + return decorator + +def isInChannelOrDM(*items): + def decorator(func): + def wrapper(*args, **kwargs): + dm = isinstance(args[1].channel, discord.channel.DMChannel) + if dm or args[1].channel.id in items or args[1].channel.name in items: + return func(*args, **kwargs) + return passFunc() + return wrapper + return decorator + +def isNotInChannel(*items): + def decorator(func): + def wrapper(*args, **kwargs): + dm = isinstance(args[1].channel, discord.channel.DMChannel) + if dm or not (args[1].channel.id in items or args[1].channel.name in items): + return func(*args, **kwargs) + return passFunc() + return wrapper + return decorator + +def isNotInChannelOrDM(*items): + def decorator(func): + def wrapper(*args, **kwargs): + dm = isinstance(args[1].channel, discord.channel.DMChannel) + if not dm or not (args[1].channel.id in items or args[1].channel.name in items): + return func(*args, **kwargs) + return passFunc() + return wrapper + return decorator + + +async def sendCTX(ctx, message): + await ctx.send(message) + +async def passFunc(): + await asyncio.sleep(0) + + + + + + + + +""" +Following functions are ment to use as decorators, when using @commands.command +""" +def isBotModCommand(): def predicate(ctx): jh = Jsonhandel() return jh.getPrivilegeLevel(ctx.author.id) >= 1 return commands.check(predicate) -def isBotOwner(): +def isBotOwnerCommand(): def predicate(ctx): jh = Jsonhandel() return jh.getPrivilegeLevel(ctx.author.id) >= 2 return commands.check(predicate) -def isDM(): +def isDMCommand(): def predicate(ctx): return isinstance(ctx.channel, discord.channel.DMChannel) return commands.check(predicate) -def isInChannel(*items): +def isInChannelCommand(*items): """ Checks if Command is invoked in a channel configured in items. """ @@ -34,7 +121,7 @@ def predicate(ctx): return ctx.channel.id in items or ctx.channel.name in items return commands.check(predicate) -def isInChannelOrDM(*items): +def isInChannelOrDMCommand(*items): """ Checks if Command is invoked in a channel configured in items or a DM. """ @@ -42,17 +129,12 @@ def predicate(ctx): return isinstance(ctx.channel, discord.channel.DMChannel) or ctx.channel.id in items or ctx.channel.name in items return commands.check(predicate) -def isNotInChannel(*items): +def isNotInChannelCommand(*items): def predicate(ctx): return not (ctx.channel.id in items or ctx.channel.name in items) return commands.check(predicate) -def isNotInChannelOrDM(*items): +def isNotInChannelOrDMCommand(*items): def predicate(ctx): return not (isinstance(ctx.channel, discord.channel.DMChannel) or ctx.channel.id in items or ctx.channel.name in items) return commands.check(predicate) - - - - - diff --git a/bot/jsonhandel.py b/bot/jsonhandel.py index 48b18f5..ef4ead1 100644 --- a/bot/jsonhandel.py +++ b/bot/jsonhandel.py @@ -159,7 +159,7 @@ def addTextXP(self, userID, amount): def addReactionXP(self, userID, amount): self.addNewDataEntry(str(userID)) - cooldownTime = self.data[str(userID)]["Cooldown"] + cooldownTime = float(self.data[str(userID)]["Cooldown"]) cooldownCon = 10 t =time.time() deltat = t-cooldownTime diff --git a/main.py b/main.py index f160598..6053d8b 100644 --- a/main.py +++ b/main.py @@ -305,7 +305,7 @@ async def on_error(event, *args, **kwargs): jh.saveConfig() print("Set log to False.") print("Loading Commands...") -bot.add_cog(Commanduser(bot, helpf, jh, xpf)) +bot.add_cog(Commanduser(bot, helpf, tban, jh, xpf)) bot.add_cog(Commandmod(bot, helpf, jh, xpf)) bot.add_cog(Commandowner(bot, helpf, tban, jh, xpf)) bot.add_cog(Commandpoll(bot, helpf, poll, jh))