/ Automatisierung2.0.0.py
Automatisierung2.0.0.py
1 #!/usr/bin/python3.8 2 #import the libraries: 3 import asyncio,discord,random,requests,mctools,time,logging,json 4 from datetime import datetime 5 from bs4 import BeautifulSoup as bs4 6 from datetime import datetime 7 from discord.ext import commands, tasks 8 from discord.utils import get 9 10 format = logging.Formatter('%(name)s @ [%(asctime)s] - %(message)s', datefmt='%m/%d/%Y %I:%M %p') 11 logger = logging.getLogger('The Butler') 12 file = logging.FileHandler(filename='./ERRORS.log',mode='a') 13 file.setFormatter(format) 14 logger.addHandler(file) 15 16 DATAPATH = './data.json' 17 18 #WORKING ON 19 #Theoretically optimizing the throne room loop - Not a pressing issue though 20 21 """ 22 Functions verified to work as expected: 23 getJSONfile 24 writeJSONFile 25 ReactionCheck 26 serverCheck 27 Loops verified to work as expected: 28 StatusChangeLoop 29 """ 30 31 #Bot Token: 32 TOKEN = "" 33 #Guild name: 34 GUILD = "Bot test server" 35 #Rcon setup stuff: 36 #ANYTHING WITH A 2 AFTER IT REFERS TO THE SECONDARY SERVER 37 """ 38 RCONPORT = '25575' 39 PINGPORT='25565' #Same port the server is hosted on 40 RCONPORT2= '25579' 41 PINGPORT2='25578' #Same port the secondary server is hosted on 42 RCONPASS = 'Spghtt' 43 RCONHOST = '192.168.29.39' 44 """ 45 #SQL_DB = 'db.sqlite3' 46 47 #Enable events: 48 intents = discord.Intents.all() 49 #Create a function to do things: 50 prefixes = ['$'] 51 bot = commands.Bot(command_prefix = prefixes, intents = intents) 52 53 #Global variables needed across functions: 54 global ThroneRoomActive, Guild 55 ThroneRoomActive = False 56 RoleHeigherarchy = ["Citizenry","Good Lad","Count","Duke","Regent","Head Regent","King"] 57 RoleHeigherarchy2 = ["Citizenry","Good Lady","Countess","Duchess","Regent","Head Regent","King"] 58 GoodLadCheck = ['Good Lad','Good Lady','Count','Countess','Duke','Duchess','Regent','Head Regent','King'] 59 CountCheck = ['Count','Countess','Duke','Duchess','Regent','Head Regent','King'] 60 DukeCheck =['Duke','Duchess','Regent','Head Regent','King'] 61 RegentCheck = ['Regent','Head Regent','King'] 62 63 #Default responces: 64 #Timeout: 65 TIMEOUTR=['Mate, you timed out','Try typing like lightning next time buckaroo','My grandma can type faster than you and she\'s dead','Type faster...Please...'] 66 BADCOMMANDR=["Bruh, that aint a valid command", "Try that command again buckaroo",'My guy...You failed your one task of entering a valid command',\ 67 'Dont worry, that might not be a valid command but I\'m sure your next one will be', 'If you spent as much time on entering the right command as I do on these messages you might get them correct'] 68 69 def getJSONFile(): 70 with open(DATAPATH,'r') as F: 71 temp = json.load(F) 72 return temp 73 74 def writeJSONFile(new): 75 with open(DATAPATH,'w') as F: 76 F.write(json.dumps(new,indent=2)) 77 78 def opCommand(Command,User,server): 79 textData = '' 80 jsonData = getJSONFile() 81 if server == 'main': 82 rconClient = mctools.mclient.RCONClient(host=jsonData['RCON']['ip'],port=jsonData['RCON']['main']['rconport'],format_method=1,timeout=60) 83 rconClient.authenticate(jsonData['RCON']['password']) 84 textData = rconClient.command(Command) 85 textData = textData.replace('[0m','') 86 rconClient.stop() 87 elif server == 'secondary': 88 rconClient = mctools.mclient.RCONClient(host=jsonData['RCON']['ip'],port=jsonData['RCON']['secondary']['rconport'],format_method=1,timeout=60) 89 rconClient.authenticate(jsonData['RCON']['password']) 90 textData = rconClient.command(Command) 91 textData = textData.replace('[0m','') 92 rconClient.stop() 93 jsonData['RCONLogs'].append({'user':str(User.display_name),'date':str(datetime()),'command':str(Command),'return':str(textData)}) 94 writeJSONFile(jsonData) 95 return textData 96 97 def ReactionCheck(Message,left,right): 98 def check(reaction, user): 99 if reaction.message.id != Message.id or user == bot.user: 100 return False 101 if left and reaction.emoji == "⏪": 102 return True 103 if right and reaction.emoji == "⏩": 104 return True 105 return False 106 return check 107 108 async def serverCheck(ctx): 109 embed = discord.Embed(color=discord.Color.dark_gold(),description='Which server would you like to run it on?') 110 embed.add_field(name='Standard',value='The standard minecraft server') 111 embed.add_field(name='Event',value='Minecraft server that minigames are run on') 112 embed.set_footer(text='[1/2] is what you should put in the chat') 113 message = await ctx.channel.send(embed=embed) 114 try: 115 response = await bot.wait_for("message",check=lambda i: i.author == ctx.message.author,timeout=60) 116 await message.delete() 117 await response.delete() 118 except asyncio.TimeoutError: 119 temp=await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description=random.choice(TIMEOUTR))) 120 await message.delete() 121 await temp.delete(delay=15) 122 return 'FAIL' 123 else: 124 if response.content == '1': 125 return 'main' 126 elif response.content == '2': 127 return 'secondary' 128 else: 129 temp=await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description=random.choice(BADCOMMANDR))) 130 return 'FAIL' 131 132 async def statUpdate(Port,cleared,server,event,message=None): 133 try: 134 ping = mctools.PINGClient(host=jsonData['RCON']['ip'],port=int(Port)) 135 stats = ping.get_stats() 136 ping.stop() 137 except: 138 if server == 'main': 139 embed = discord.Embed(color=discord.Color.dark_gold(),title='Main server') 140 elif server == 'secondary': 141 embed = discord.Embed(color=discord.Color.dark_gold(),title='Minigame server') 142 embed.add_field(name='Server IP',value=('OFFLINE'),inline=False) 143 embed.add_field(name='Status',value='OFFLINE') 144 embed.add_field(name='Minecraft Version',value='OFFLINE') 145 embed.add_field(name='Server TPS',value='OFFLINE',inline=False) 146 embed.add_field(name='Server Uptime',value='OFFLINE',inline=False) 147 embed.add_field(name='Player Stats',value='OFFLINE',inline=False) 148 embed.add_field(name='Players Online',value='OFFLINE',inline=False) 149 embed.add_field(name='Upcoming event',value='\u200b'+event) 150 embed.add_field(name='Next Scheduled Restart',value='OFFLINE',inline=False) 151 message = await importantChannels['serverstats'].send(embed=embed) 152 return 153 serverVersion=stats['version']['name'] 154 maxP=stats['players']['max'] 155 onlineCountP=stats['players']['online'] 156 pList = '' 157 try: 158 for index,i in enumerate(stats['players']['sample']): 159 if index < len(stats['players']['sample'])-1: 160 temp = i[0].replace('\x1b','') 161 temp = temp.replace('[0m','') 162 pList += (temp+', ') 163 else: 164 temp = i[0].replace('\x1b','') 165 temp = temp.replace('[0m','') 166 pList += (temp) 167 except Exception as E: 168 pList='NONE' 169 jsonData=getJSONFile() 170 if server == 'main': 171 rconClient = mctools.mclient.RCONClient(host=jsonData['RCON']['ip'],port=jsonData['RCON']['main']['rconport'],format_method=1,timeout=60) 172 else: 173 rconClient = mctools.mclient.RCONClient(host=jsonData['RCON']['ip'],port=jsonData['RCON']['secondary']['rconport'],format_method=1,timeout=60) 174 rconClient.authenticate(jsonData['RCON']['password']) 175 tpsData = rconClient.command('tps') 176 tpsData = tpsData.replace('[0m','') 177 daysData = rconClient.command('time query day') 178 daysData = daysData.replace('[0m','') 179 rconClient.stop() 180 181 tps = 0 182 for i,char in enumerate(tpsData): 183 if char == '*': 184 tps += int(tpsData[i+1:i+3]) 185 tps = tps/3 186 187 for i,char in enumerate(daysData): 188 if i != len(daysData)-1: 189 if char + daysData[i+1] == 's ': 190 days = daysData[i+2:] 191 break 192 193 #formatting output for the standard server: 194 if server == 'main': 195 embed = discord.Embed(color=discord.Color.dark_gold(),title='Main server') 196 elif server == 'secondary': 197 embed = discord.Embed(color=discord.Color.dark_gold(),title='Minigame server') 198 jsonData = getJSONFile() 199 embed.add_field(name='Server IP',value=(jsonData['RCON']['ip']+':'),inline=False) 200 embed.add_field(name='Status',value='Online') 201 embed.add_field(name='Minecraft Version',value='\u200b'+str(serverVersion),inline=False) 202 embed.add_field(name='Server TPS',value='\u200b'+str(tps),inline=False) 203 embed.add_field(name='Server Uptime',value='\u200b'+(str(days)+' days'),inline=False) 204 embed.add_field(name='Player Stats',value='\u200b'+(str(onlineCountP)+'/'+str(maxP)),inline=False) 205 embed.add_field(name='Players Online',value='\u200b'+pList,inline=False) 206 embed.add_field(name='Upcoming event',value='\u200b'+event) 207 embed.add_field(name='Next Scheduled Restart',value='Wednesday night at midnight',inline=False) 208 209 if cleared: 210 await message.edit(embed=embed) 211 else: 212 message = await importantChannels['serverstats'].send(embed=embed) 213 return message.id 214 215 #Once the bot has fully come online run this function before everything else: 216 @bot.event 217 async def on_ready(): 218 global Guild, importantChannels, CITIZENRY,ThroneRoomActive 219 Guild = get(bot.guilds, name = GUILD) 220 221 for Role in Guild.roles: 222 if Role.name == RoleHeigherarchy[0]: 223 CITIZENRY = Role 224 225 jsonData = getJSONFile() 226 TH = Guild.get_channel(int(jsonData['channels']['throne-room'])) 227 AN = Guild.get_channel(int(jsonData['channels']['announcements'])) 228 AB = Guild.get_channel(int(jsonData['channels']['admin-bots'])) 229 SS = Guild.get_channel(int(jsonData['channels']['stats'])) 230 SR = Guild.get_channel(int(jsonData['channels']['rules'])) 231 importantChannels = dict(throneroom=TH,announcements=AN,adminbots=AB,serverstats=SS,serverrules=SR) 232 233 #Update the loops that run in the background with no user input 234 if jsonData['throne-room']['active'] == 'True': 235 """ThroneRoomLoop.change_interval(seconds = TimeLeft)""" 236 ThroneRoomActive = True 237 ThroneRoomLoop.start(True,jsonData['throne-room']['time-left']) 238 else: 239 ThroneRoomActive = False 240 StatusChangeLoop.start() 241 await UpdateThroneRoomFile() 242 #serverStats.start() 243 244 #Change statuses of the bot: 245 @tasks.loop(hours = 5) 246 async def StatusChangeLoop(): 247 Options = ["I spent way too much time on this","I should get a life","Why do I do all the grunt work?","Pedro for president 2024!",\ 248 "Minecraft","Can I earn money doing this?","Earth is fine, people are dumb",\ 249 "Everyone should be able to do one card trick, tell two jokes, and recite three poems, in case they are ever trapped in an elevator",\ 250 "Bruh","When a bird hits your window have you ever wondered if God is playing angry birds with you?",\ 251 "When I’m on my death bed, I want my final words to be “I left one million dollars in the…",\ 252 "My study period = 15 minutes. My break time = 3 hours","Never make eye contact while eating a banana",\ 253 "C.L.A.S.S- come late and start sleeping","My biggest concern in life is actually how my online friends can be informed of my death!",\ 254 "How do you know what it’s like to be stupid if you’ve never been smart?","I hate fake people. You know what I’m talking about. Mannequins.",\ 255 "Everything is 10x funnier when you are not supposed to laugh.","It may look like I’m deep in thought, but 99% of the time I’m just thinking about what food to eat later.",\ 256 "\"Focusing\" on school work","That awkward moment when you realize that dora, who is 5, has more freedom than you.",\ 257 "That awkward when your eyes assumed “moment” was written after \"awkward\"","Never gonna let you down","Never gonna run around",\ 258 "https://www.youtube.com/watch?v=dQw4w9WgXcQ","I lost the game","Dont forget to like and subscribe!","Imagine putting in effort",\ 259 "I put the most effort into these quotes","If you have more status ideas, DM helaugheth#5815","Psst, is anyone watching these?",\ 260 "There are 10 types of people, those who understand binary and those who dont","I should focus on college homework","There are 13 lines of quotes for me to choose from.",\ 261 "Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn","#SupportC'thulu","#LearnParsletoung","I'm adding these during class","lol",\ 262 "XD","Bro this releaves so much boredom","Shoot, I should do homework","College classes are BORING","All around me are familiar faces...",\ 263 "What is this...\"Fish showcommands\" thing?","Yar dar dar and a hody hody do","https://www.youtube.com/watch?v=Q04Lkw91Gts"] 264 265 Status = random.choice(Options) 266 await bot.change_presence(activity = discord.Game(name = Status)) 267 268 #updates the Throne room file with information about it 269 @tasks.loop(hours = 1) 270 async def UpdateThroneRoomFile(new_m_data = None): 271 if ThroneRoomActive: 272 CurrentTime = int(datetime.now().timestamp()) 273 if ThroneRoomLoop.next_iteration != None: 274 LoopTime = int(ThroneRoomLoop.next_iteration.timestamp()) 275 TimeLeft = str(LoopTime - CurrentTime) 276 else: 277 TimeLeft = 'None' 278 LoopTime = 'None' 279 else: 280 TimeLeft = 'None' 281 LoopTime = 'None' 282 jsonData = getJSONFile() 283 284 jsonData['throne-room']['active'] = str(ThroneRoomActive) 285 jsonData['throne-room']['time-left'] = str(TimeLeft) 286 if new_m_data != None: 287 jsonData['throne-room']['messages'].append(new_m_data) 288 writeJSONFile(jsonData) 289 290 #Main throne room loop: 291 @tasks.loop(hours = 196) 292 async def ThroneRoomLoop(RebootedUp,timeLeft=None): 293 global ThroneRoomActive 294 Active = False 295 296 """ 297 RebootedUp - Server was rebooted while the throne room was running. Just needs to make sure perms are given and make an anouncement to admins 298 """ 299 if RebootedUp: 300 await importantChannels['throneroom'].set_permissions(CITIZENRY, view_channel = True) 301 await importantChannels['adminbots'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description="Server restarted, resuming the "+importantChannels['throneroom'].mention+" loop. Citizenry has been given access. No announcements made.")) 302 Active = True 303 timeLeft = datetime.fromtimestamp(int(timeLeft)) 304 t = (datetime.now()-timeLeft).total_seconds() 305 ThroneRoomLoop.change_interval(seconds=t) 306 else: 307 Active = True 308 if ThroneRoomLoop.current_loop == 0: 309 Active = True 310 elif (ThroneRoomLoop.current_loop % 2) == 0: 311 Active = True 312 else: 313 Active = False 314 315 if Active: 316 await importantChannels['throneroom'].purge() 317 await importantChannels['throneroom'].set_permissions(CITIZENRY, view_channel = True) 318 temp = "" 319 temp2 = "" 320 for role in Guild.roles: 321 if role.name == RoleHeigherarchy[1]: 322 temp = role.mention 323 elif role.name == RoleHeigherarchy2[1]: 324 temp2 == role.mention 325 break 326 await importantChannels['throneroom'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description=("Use the command `Fish title` to automatically request the rank higher than you are currently at. You must have the"+temp+"/"+temp2+"rank to request higher ranks. You can use `Fish Title help` to get more help."))) 327 Temp = await importantChannels['announcements'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description=(importantChannels['throneroom'].mention + " is now open all yall!"))) 328 await Temp.delete(delay = 346500) 329 else: 330 await importantChannels['throneroom'].set_permissions(CITIZENRY, view_channel = False) 331 Temp = await importantChannels['announcements'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description=("I just closed the "+importantChannels['throneroom'].mention+" so voting will be held and results will be announced somewhat soon, depends on how active members are."))) 332 Temp.delete(delay=30000) 333 for member in Guild.members: 334 Cleared = False #Citizenry check 335 Cleared2 = True #Check so that they do NOT have Good Lad/Lady 336 for role in member.roles: 337 if role.name == RoleHeigherarchy[0]: 338 Cleared = True 339 if role.name == RoleHeigherarchy[1] or role.name == RoleHeigherarchy2[1]: 340 Cleared2 = False 341 342 if Cleared and Cleared2: 343 for i in Guild.roles: 344 if i.name == RoleHeigherarchy[0]: 345 lad = i 346 elif i.name == RoleHeigherarchy2[0]: 347 lady = i 348 break 349 Message = await importantChannels['throneroom'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description=("Grant " + member.mention + " the "+lad.mention+"/"+lady.mention+" role?"))) 350 UpdateThroneRoomFile({"messageID":str(Message.id),"role":str(CITIZENRY.id),'discordID':str(Message.author.id)}) 351 352 jsonData = getJSONFile() 353 for i in jsonData['throne-room']['messages']: 354 message = await importantChannels['throneroom'].fetch_message(int(i['messageID'])) 355 await message.add_reaction("👍") 356 await message.add_reaction("👎") 357 358 ThroneRoomActive = Active 359 360 #Update server stats for people to be able to see 361 #@tasks.loop(minutes=5) 362 async def serverStats(): 363 jsonData = getJSONFile() 364 main_message = None 365 secondary_message = None 366 if type(jsonData['stats']['main']['messageID']) == type('temp'): 367 main_message = await importantChannels['serverstats'].fetch_message(int(jsonData['stats']['main']['messageID'])) 368 if type(jsonData['stats']['secondary']['messageID']) == type('temp'): 369 secondary_message = await importantChannels['serverstats'].fetch_message(int(jsonData['stats']['secondary']['messageID'])) 370 371 secondary_event = jsonData['stats']['secondary']['event'] 372 main_event = jsonData['stats']['main']['event'] 373 await statUpdate(jsonData['RCON']['main']['mainport'],True,'main',main_event,main_message) 374 await statUpdate(jsonData['RCON']['secondary']['mainport'],True,'secondary',secondary_event,secondary_message) 375 376 @bot.command(help='Duke level command') 377 @commands.has_any_role(*DukeCheck) 378 async def removelink(ctx): 379 ToDelete = [] 380 await ctx.message.delete() 381 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="Ping the discord user to force an unlink, *or* you can just slap the minecraft username in"))) 382 try: 383 response = await bot.wait_for("message",check=lambda i: i.author == ctx.message.author,timeout=60) 384 ToDelete.append(response) 385 except asyncio.TimeoutError: 386 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description=random.choice(TIMEOUTR)))) 387 else: 388 jsonData = getJSONFile() 389 discordUsed = False 390 if len(response.raw_mentions) > 0: 391 discordUsed = True 392 found = False 393 for i in jsonData['registry']: 394 if discordUsed: 395 if response.raw_mentions[0] == int(i['discordID']): 396 soup = bs4(requests.get("https://mcuuid.net/?q="+str(i['uuid'])).text,features="html.parser") 397 username = soup.find("input",attrs={"id":"results_username"})["value"] 398 user=Guild.get_member(response.raw_mentions[0]) 399 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description=(user.mention+' is linked to '+username+\ 400 '. Please confirm admin unlinkage and that the requestor has correctly inputted their username [yes/no] THIS CANNOT BE UNDONE')))) 401 found = True 402 break 403 else: 404 soup = bs4(requests.get("https://mcuuid.net/?q="+str(response.content)).text,features="html.parser") 405 username=response.content 406 user=Guild.get_member(int(i['discordID'])) 407 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description=(response.content+' is linked to '+user.mention+\ 408 '. Please confirm admin unlinkage and that the requestor has correctly inputted their username [yes/no] THIS CANNOT BE UNDONE')))) 409 found = True 410 break 411 if not found: 412 if not discordUsed: 413 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description='I couldn\'t find anyone linked up that Minecraft account, try again using the Discord ping mate'))) 414 else: 415 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description='I couldn\'t find anyone linked up that Discord account, try again using the Minecraft username mate'))) 416 else: 417 try: 418 response2 = await bot.wait_for("message",check=lambda i: i.author == ctx.message.author,timeout=60) 419 ToDelete.append(response) 420 except asyncio.TimeoutError: 421 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description=random.choice(TIMEOUTR)))) 422 else: 423 if response2.content.lower() == 'yes' or response2.content.lower() == 'y': 424 jsonData['registry'].remove(i) 425 writeJSONFile(jsonData) 426 await importantChannels['adminbots'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description=(str(ctx.message.author.mention)+' has forcefully removed the link between '+user.mention+' and '+username))) 427 textData = opCommand('whitelist remove '+username, user, 'main') 428 textData += ' ' + opCommand('whitelist remove '+username, user, 'secondary') 429 jsonData.remove(i) 430 writeJSONFile(jsonData) 431 await importantChannels['adminbots'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description='\u200b'+textData)) 432 433 elif response2.content.lower() == 'no' or response2.content.lower() == 'n': 434 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description='Right-o then'))) 435 else: 436 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description=random.choice(BADCOMMANDR)))) 437 """for i in ToDelete: 438 await i.delete(delay = 30)""" 439 440 @bot.command(help='Regent level command') 441 @commands.has_any_role(*RegentCheck) 442 async def errors(ctx): 443 file = discord.File(fp='./ERRORS.log', filename="ERRORS.log") 444 await importantChannels['adminbots'].send(file=file) 445 446 #help= says it all. They must have the Good Lad role to do this though 447 @bot.command(help = "Request 1 title higher than you currently have.") 448 @commands.has_any_role(*GoodLadCheck) 449 async def title(ctx): 450 Message = ctx.message 451 await Message.delete() 452 ToDelete = [] 453 jsonData = getJSONFile() 454 for i in jsonData['throne-room']['messages']: 455 if int(i['discordID']) == Message.author.id: 456 m = await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description='Hey now mate...You already requested a title, can\' be requesting two now can you. How would that be fair eh?')) 457 await m.delete(delay=30) 458 return 459 460 if ctx.channel == importantChannels['throneroom'] and ThroneRoomActive: 461 User = Message.author 462 RoleChosen = False 463 TitleList = Guild.roles 464 RequestedTitle = 'TEMP' 465 CurrentTitle = 'TEMP' 466 467 for role in User.roles: 468 if role.name == RoleHeigherarchy[1]: 469 CurrentTitle = {"Role":role,"Rank":1,"H":1} 470 elif role.name == RoleHeigherarchy[2]: 471 CurrentTitle = {"Role":role,"Rank":2,"H":1} 472 elif role.name == RoleHeigherarchy2[2]: 473 CurrentTitle = {"Role":role,"Rank":2,"H":2} 474 475 elif role.name == RoleHeigherarchy[3]: 476 CurrentTitle = {"Role":role,"Rank":3,"H":1} 477 elif role.name == RoleHeigherarchy2[3]: 478 CurrentTitle = {"Role":role,"Rank":3,"H":2} 479 480 elif role.name == RoleHeigherarchy[4] or role.name == RoleHeigherarchy2[4]: 481 CurrentTitle = {"Role":role,"Rank":4,"H":1} 482 elif role.name == RoleHeigherarchy[5] or role.name == RoleHeigherarchy2[5]: 483 CurrentTitle = {"Role":role,"Rank":5,"H":1} 484 elif role.name == RoleHeigherarchy[6]: 485 CurrentTitle = {"Role":role,"Rank":6,"H":1} 486 for Title in TitleList[1:]: 487 if Title == CurrentTitle["Role"]: 488 if CurrentTitle["Rank"] < 4: 489 if CurrentTitle["H"] == 1: 490 RequestedTitle = RoleHeigherarchy[CurrentTitle["Rank"] + 1] 491 RoleChosen = True 492 else: 493 RequestedTitle = RoleHeigherarchy2[CurrentTitle["Rank"] + 1] 494 RoleChosen = True 495 496 elif CurrentTitle["Rank"] == 4: 497 ToDelete.append(await ctx.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="That title is granted by the King (*cough cough* favoratism *cough cough*"))) 498 RoleChosen = False 499 500 elif CurrentTitle["Rank"] == 5: 501 ToDelete.append(await ctx.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="When the King ~~dies~~ leaves you are given his title. So dont get too ambitious or he might take special notice of that..."))) 502 RoleChosen = False 503 504 elif CurrentTitle["Rank"] == 6: 505 ToDelete.append(await ctx.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="You're already top of the ship mate. You cant request any higher. I mean you could by adding higher roles but then I'd start calling you an Egyptian or something"))) 506 507 if RoleChosen: 508 if Title.name == RequestedTitle: 509 NewMessage = await ctx.send(embed = discord.Embed(color=discord.Color.dark_gold(),description=User.mention + " Requests the title of: " + str(Title.name))) 510 await UpdateThroneRoomFile({"messageID":str(NewMessage.id),"role":str(Title.id),'discordID':str(Message.author.id)}) 511 else: 512 ToDelete.append(await ctx.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="Incorrect channel. Message has been deleted. Please only use this command in the"+importantChannels['throneroom'].mention))) 513 514 for i in ToDelete: 515 await i.delete(delay=10) 516 517 #Run a minecraft command from discord 518 @bot.command(help = "Regent level command") 519 @commands.has_any_role(*RegentCheck) 520 async def mccommand(ctx): 521 await ctx.message.delete() 522 ToDelete = [] 523 ToDelete.append(await ctx.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="Enter the command to run on the server").set_footer(text="THIS WILL BE RAN WITH OP PRIVLAGES - DO NOT USE THE `/` I ADD IT"))) 524 try: 525 response = await bot.wait_for("message",check=lambda i: i.author == ctx.message.author,timeout=90) 526 ToDelete.append(response) 527 except Exception as E: 528 await importantChannels['adminbots'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description=("ERROR RUNNING A MC-COMMAND. ERROR: "+str(E)))) 529 else: 530 if response.content.startswith('/'): 531 ToDelete.append(await ctx.send(embed = discord.Embed(color=discord.Color.dark_gold(),description='HEY! I said no inputting the `/` I will take care of it...I gotchu this time...Try not to in the future, I know it\'s weird though'))) 532 response.content = response.content[1:] 533 534 server = await serverCheck(ctx) 535 if server != 'FAIL': 536 537 textData = opCommand(response.content, ctx.message.author, server) 538 embed = discord.Embed(color=discord.Color.dark_gold()) 539 embed.add_field(name='Data returned',value=('\u200b'+textData)) 540 ToDelete.append(await importantChannels['adminbots'].send(embed=embed)) 541 await importantChannels['adminbots'].send(embed=discord.Embed(color=discord.Color.dark_gold(),description=(str(ctx.message.author)+' ran the command: '+str(response.content)+' @ '+str(time.asctime())))) 542 543 for i in ToDelete: 544 await i.delete(delay=20) 545 546 #The throne room loop 547 @bot.command(help = "Regent level command") 548 @commands.has_any_role(*RegentCheck) 549 async def loop(ctx, arg): 550 global ThroneRoomActive 551 await ctx.message.delete() 552 ToDelete = [] 553 if arg == "start": 554 if ThroneRoomLoop.is_running(): 555 if ThroneRoomActive: 556 ToDelete.append(await importantChannels['adminbots'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description=("The "+importantChannels['throneroom'].mention+" loop is already running. "+importantChannels['throneroom'].mention+" is currently open and will close on: " + str(ThroneRoomLoop.next_iteration))))) 557 else: 558 ToDelete.append(await importantChannels['adminbots'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description=("The "+importantChannels['throneroom'].mention+" loop is already running. "+importantChannels['throneroom'].mention+" is currently closed and will open on: " + str(ThroneRoomLoop.next_iteration))))) 559 else: 560 ToDelete.append(await importantChannels['adminbots'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description=("The "+importantChannels['throneroom'].mention+" loop has been started")))) 561 await ThroneRoomLoop.start(False) 562 563 elif arg == "stop": 564 if not ThroneRoomLoop.is_running(): 565 ToDelete.append(await importantChannels['adminbots'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description=("The "+importantChannels['throneroom'].mention+" loop is not running.")))) 566 else: 567 ToDelete.append(await importantChannels['adminbots'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description=("The "+importantChannels['throneroom'].mention+" loop has been stopped.")))) 568 ToDelete.append(await importantChannels['announcements'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description=(importantChannels['throneroom'].mention + " has closed. Voting will be held and results will be announced soon.")))) 569 ThroneRoomLoop.cancel() 570 await importantChannels['throneroom'].set_permissions(CITIZENRY, view_channel = False) 571 for member in Guild.members: 572 Cleared = False #Citizenry check 573 Cleared2 = True #Check so that they do NOT have Good Lad/Lady 574 for role in member.roles: 575 if role.name == RoleHeigherarchy[0]: 576 Cleared = True 577 if role.name == RoleHeigherarchy[1] or role.name == RoleHeigherarchy2[1]: 578 Cleared2 = False 579 580 if Cleared and Cleared2: 581 for i in Guild.roles: 582 print(i.name,RoleHeigherarchy[0],RoleHeigherarchy2[0]) 583 if i.name == RoleHeigherarchy[0]: 584 lad = i 585 elif i.name == RoleHeigherarchy2[0]: 586 lady = i 587 break 588 Message = await importantChannels['throneroom'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description=("Grant " + member.mention + " the "+lad.mention+"/"+lady.mention+" role?"))) 589 await UpdateThroneRoomFile({"messageID":str(Message.id),"role":str(CITIZENRY.id),'discordID':str(Message.author.id)}) 590 591 jsonData = getJSONFile() 592 593 for i in jsonData['throne-room']['messages']: 594 message = await importantChannels['throneroom'].fetch_message(i['messageID']) 595 await message.add_reaction("👍") 596 await message.add_reaction("👎") 597 598 elif arg == "status": 599 if not ThroneRoomLoop.is_running(): 600 ToDelete.append(await importantChannels['adminbots'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description=("The "+importantChannels['throneroom'].mention+" loop is not running at the moment")))) 601 else: 602 ToDelete.append(await importantChannels['adminbots'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description=(importantChannels['throneroom'].mention+" is currently running status will change in: " + str(ThroneRoomLoop.next_iteration))))) 603 604 elif arg == "help": 605 Help = discord.Embed(color=discord.Color.dark_gold()) 606 Help.add_field(name = "BOT PREFIX", value = "Fish") 607 Help.add_field(name = "Loop Commands", value = "`start` | `stop` | `status`") 608 Help.add_field(name = "start", value = "Starts the throne room loop EX: `Fish loop start`") 609 Help.add_field(name = "stop", value = "Stops the throne room loop EX: `Fish loop stop`") 610 Help.add_field(name = "status", value = "Check the status of the Throne Room. EX: `Fish loop status`") 611 ToDelete.append(await ctx.send(embed = Help)) 612 613 for i in ToDelete: 614 await i.delete(delay=20) 615 616 #Display the ServerFile 617 @bot.command(help = "Regent level command") 618 @commands.has_any_role(*RegentCheck) 619 async def serverfile(ctx): 620 await ctx.message.delete() 621 622 server = await serverCheck() 623 if server == 'FAIL': 624 return 625 jsonData = getJSONFile() 626 627 with open(jsonData['serverfiles'][server]['properties']) as F: 628 ServerFile = F.readlines() 629 Book=[] 630 Sheet = [] 631 title="" 632 data="" 633 await importantChannels['adminbots'].trigger_typing() 634 for Place, line in enumerate(ServerFile): 635 for i, letter in enumerate(line): 636 if letter == "=": 637 title = line[:i] 638 if line[i+1:] == "\n": 639 data = "NO DATA" 640 break 641 else: 642 data = line[i+1:len(line)-1] 643 break 644 645 if Place % 9 == 0 and Place != 0: 646 if Place == 9: 647 Sheet.pop(0) 648 Sheet.pop(0) 649 Book.append(Sheet) 650 Sheet = [] 651 else: 652 Sheet.append({"title":title,"data":data}) 653 Page = 0 654 Forward = "⏩" 655 Back = "⏪" 656 657 EmbedData = discord.Embed(color=discord.Color.dark_gold()) 658 for i in Book[Page]: 659 EmbedData.add_field(name = i["title"],value = '\u200b'+i["data"]) 660 661 file = discord.File(fp=jsonData['serverfiles'][server]['properties'], filename="server.propterties") 662 await importantChannels['adminbots'].send(file=file) 663 664 Message = await importantChannels['adminbots'].send(embed=EmbedData) 665 666 while True: 667 EmbedData = discord.Embed(color=discord.Color.dark_gold()) 668 for i in Book[Page]: 669 EmbedData.add_field(name = i["title"],value = '\u200b'+i["data"]) 670 EmbedData.set_footer(text = "The whitelist option MUST be done through commands in-game. Spigot has an issue where it will dump the contents of the whitelist file when it's edited manually. No idea why it does so. Further details can be located at: https://minecraft.gamepedia.com/Server.properties") 671 672 await Message.edit(embed=EmbedData) 673 674 left = Page != 0 675 right = Page != len(Book) - 1 676 677 if left: 678 await Message.add_reaction(Back) 679 if right: 680 await Message.add_reaction(Forward) 681 try: 682 Reaction = await bot.wait_for("reaction_add",check = ReactionCheck(Message,left,right),timeout=200) 683 except asyncio.TimeoutError: 684 await Message.delete() 685 return 686 else: 687 if str(Reaction[0]) == Back: 688 Page -= 1 689 await Message.remove_reaction(emoji=Back,member=ctx.message.author) 690 if Page == 0: 691 await Message.remove_reaction(emoji=Back,member=bot.user) 692 elif str(Reaction[0]) == Forward: 693 Page += 1 694 await Message.remove_reaction(emoji=Forward,member=ctx.message.author) 695 if Page == len(Book) - 1: 696 await Message.remove_reaction(emoji=Forward,member=bot.user) 697 698 #Show default commands available to everyone below a Count 699 @bot.command(help = "Shows available commands") 700 async def showcommands(ctx): 701 Help = discord.Embed(color=discord.Color.dark_gold()) 702 Help.add_field(name = "COMMANDS", value = "`title` | `link` | `userinfo`",inline=False) 703 Help.add_field(name = "title", value = "Only available when the Throne Room is available and if you have the Good Lad/Lady Title. EX: `Fish title`",inline=False) 704 Help.add_field(name = "link", value = "Link your discord account to your minecraft account. EX: `Fish link` then follow the prompts",inline=False) 705 Help.add_field(name = "unlink", value = "UnLink the minecraft account linked to your discord account. EX: `Fish unlink` then follow prompts",inline=False) 706 Help.add_field(name = "userinfo", value = "Show skin and name history of a player and what discord account they're linked to. EX: `Fish userinfo` then follow the prompts",inline=False) 707 #Help.add_field(name = "prank", value = "Allows those who have linked their discord and minecraft accounts to prank each other. EX: `Fish prank` then follow the prompts",inline=False) 708 Help.set_footer(text="BOT PREFIX: `Fish`") 709 i = await ctx.send(embed = Help) 710 await i.delete(delay=60) 711 712 #Clear a bunch of messages from a channel 713 @bot.command(help = "Count/Countess level command") 714 @commands.has_any_role(*CountCheck) 715 async def clear(ctx,arg): 716 if arg == "help": 717 await ctx.message.delete() 718 await ctx.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="Clear an amount of messages from a channel. `EX: Fish clear 6`")) 719 else: 720 await ctx.channel.purge(limit=int(arg) + 1) 721 722 #Link minecraft and discord accounts 723 @bot.command(help="Link discord to minecraft account") 724 async def link(ctx): 725 ToDelete=[] 726 await ctx.message.delete() 727 jsonData = getJSONFile() 728 for i in jsonData['registry']: 729 if i['discordID'] == str(ctx.message.author.id): 730 soup = bs4(requests.get("https://mcuuid.net/?q="+str(i['uuid'])).text,features="html.parser") 731 username = soup.find("input",attrs={"id":"results_username"})["value"] 732 temp = await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="Mate, you're already linked to a minecraft account... You're linked to an account with the name: "+username+'. You can unlink accounts by running the command `unlink` and following further prompts')) 733 await temp.delete(delay=30) 734 return 735 736 #ToDelete.append(await ctx.channel.send("You input your minecraft username and then I can link it to your discord account so then it will be updated frequently and other users can check who minecraft users are if they dont know who it is on discord. It also helps with keeping the player registry up to date, this replaces it actually.")) 737 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="Input your username here and I'll begin the linking process:"))) 738 try: 739 response = await bot.wait_for("message",check=lambda i: i.author == ctx.message.author,timeout=60) 740 ToDelete.append(response) 741 except asyncio.TimeoutError: 742 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description=random.choice(TIMEOUTR)))) 743 else: 744 details = discord.Embed(color=discord.Color.dark_gold()) 745 soup = bs4(requests.get("https://mcuuid.net/?q="+str(response.content)).text,features="html.parser") 746 Username = soup.find("input",attrs={"id":"results_username"})["value"] 747 uuid = soup.find("input",attrs={"id":"results_id"})["value"] 748 Skin = soup.find("img",attrs={"id":"results_avatar_body"})["src"] 749 Face = soup.find("img",attrs={"class":"results_avatar mx-auto"})["src"] 750 details.set_thumbnail(url=Face) 751 details.set_image(url=Skin) 752 details.add_field(name="Username",value='\u200b'+Username,inline=False) 753 details.set_footer(text="Please confirm if this is you [yes/no]") 754 ToDelete.append(await ctx.channel.send(embed = details)) 755 try: 756 response = await bot.wait_for("message", check = lambda i: i.author == ctx.message.author,timeout=60) 757 ToDelete.append(response) 758 except asyncio.TimeoutError: 759 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description=random.choice(TIMEOUTR)))) 760 else: 761 found = False 762 if response.content.lower() == "no": 763 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="Right-o then"))) 764 elif response.content.lower() == "yes": 765 jsonData = getJSONFile() 766 for i in jsonData['registry']: 767 if i['uuid'] == uuid: 768 found = True 769 if i['discordID'] != str(ctx.message.author.id): 770 await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="Hey now...That minecraft account {Username: "+Username+"} is already linked to someone...You cant be doing that now. It's linked to: "+Guild.get_member(int(i['discordID'])).mention),header=(Guild.get_member(ctx.message.author.id)+" tried to link to a already existing account")) 771 break 772 else: 773 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="You must have a bad memory my guy. You're already linked to that account so you already did that...I guess good job?"))) 774 break 775 elif i['discordID'] == str(ctx.message.author.id): 776 found = True 777 soup = bs4(requests.get("https://mcuuid.net/?q="+str(i['uuid'])).text,features="html.parser") 778 Username = soup.find("input",attrs={"id":"results_username"})["value"] 779 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="Mate, you're already linked to a minecraft account... You're linked to an account with the name: "+Username))) 780 break 781 if i == jsonData['registry'][-1]: 782 found = True 783 jsonData['registry'].append({'uuid':uuid,'discordID':str(ctx.message.author.id)}) 784 writeJSONFile(jsonData) 785 786 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="Accounts linked. Good job mate. You've earned a donut"))) 787 with open('./donut.png', 'rb') as f: 788 donut = discord.File(f,"./donut.png") 789 await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description=(str(ctx.message.author.mention)+' has linked his discord to the mincraft account: '+str()))) 790 ToDelete.append(await ctx.channel.send(file=donut)) 791 792 textData = opCommand(('whitelist add '+Username),ctx.message.author,'main') 793 temp = opCommand(('whitelist add '+Username),ctx.message.author,'secondary') 794 textData += ' ' +temp 795 await importantChannels['adminbots'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description='\u200b'+textData)) 796 break 797 798 if not found: 799 jsonData['registry'].append({'uuid':uuid,'discordID':str(ctx.message.author.id)}) 800 writeJSONFile(jsonData) 801 802 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="Accounts linked. Good job mate. You've earned a donut"))) 803 with open('./donut.png', 'rb') as f: 804 donut = discord.File(f,"donut.png") 805 ToDelete.append(await ctx.channel.send(file=donut)) 806 await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description=(str(ctx.message.author.mention)+' has linked his discord to the mincraft account: '+str(Username)))) 807 808 textData = opCommand(('whitelist add '+Username),ctx.message.author,'main') 809 temp = opCommand(('whitelist add '+Username),ctx.message.author,'secondary') 810 textData += ' ' +temp 811 await importantChannels['adminbots'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description='\u200b'+textData)) 812 813 else: 814 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="My guy, that aint the responce I was looking for...Try again from the beginning. A simple yes/no will do"))) 815 for i in ToDelete: 816 await i.delete(delay=30) 817 818 #Unlink minecraft and discord accounts 819 @bot.command(help="Unlink discord and minecraft account") 820 async def unlink(ctx): 821 ToDelete=[] 822 await ctx.message.delete() 823 found = False 824 jsonData = getJSONFile() 825 for i in jsonData['registry']: 826 if i['discordID'] == str(ctx.message.author.id): 827 found = True 828 details = discord.Embed(color=discord.Color.dark_gold()) 829 soup = bs4(requests.get("https://mcuuid.net/?q="+str(i['uuid'])).text,features="html.parser") 830 Username = soup.find("input",attrs={"id":"results_username"})["value"] 831 Skin = soup.find("img",attrs={"id":"results_avatar_body"})["src"] 832 Face = soup.find("img",attrs={"class":"results_avatar mx-auto"})["src"] 833 details.set_thumbnail(url=Face) 834 details.set_image(url=Skin) 835 details.add_field(name="Username",value='\u200b'+Username,inline=False) 836 details.set_footer(text="This is the account you're linked to. Confirm unlinkage? [yes/no]") 837 ToDelete.append(await ctx.channel.send(embed = details)) 838 try: 839 response = await bot.wait_for("message",check=lambda i: i.author == ctx.message.author,timeout=60) 840 ToDelete.append(response) 841 except asyncio.TimeoutError: 842 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description=random.choice(TIMEOUTR)))) 843 else: 844 if response.content.lower() == "yes": 845 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description="Deleting account linkage I s'pose"))) 846 847 textData = opCommand(('whitelist remove '+Username),ctx.message.author,'main') 848 temp = opCommand(('whitelist remove '+Username),ctx.message.author,'secondary') 849 textData += ' ' +temp 850 851 jsonData['registry'].remove(i) 852 writeJSONFile(jsonData) 853 854 await importantChannels['adminbots'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description='\u200b'+textData)) 855 elif response.content.lower() == "no": 856 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description="Right-o then"))) 857 else: 858 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="My guy, that aint the responce I was looking for...Try again from the beginning"))) 859 860 if not found: 861 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description="You aint linked to an account yet mate. You gotta link before you can unlink...No donut for you"))) 862 863 for i in ToDelete: 864 await i.delete(delay=15) 865 866 #Display low level info about a user 867 @bot.command(help="Queury the registry database for information about a specific player") 868 async def userinfo(ctx): 869 ToDelete = [] 870 await ctx.message.delete() 871 options = discord.Embed(color=discord.Color.dark_gold(),description="Enter a minecraft username to get some information about who that Minecraft account is linked to here on Discord. Just enter the username") 872 ToDelete.append(await ctx.channel.send(embed=options)) 873 try: 874 response = await bot.wait_for("message",check = lambda i: i.author == ctx.message.author,timeout=60) 875 ToDelete.append(response) 876 except asyncio.TimeoutError: 877 ToDelete.append(await ctx.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description=random.choice(TIMEOUTR)))) 878 else: 879 try: 880 soup = bs4(requests.get("https://mcuuid.net/?q="+str(response.content)).content,features="html.parser") 881 details = discord.Embed(color=discord.Color.dark_gold()) 882 Username = soup.find("input",attrs={"id":"results_username"})["value"] 883 uuid = soup.find("input",attrs={"id":"results_id"})["value"] 884 Skin = soup.find("img",attrs={"id":"results_avatar_body"})["src"] 885 Face = soup.find("img",attrs={"class":"results_avatar mx-auto"})["src"] 886 details.set_thumbnail(url=Face) 887 details.set_image(url=Skin) 888 details.add_field(name="Minecraft Username",value='\u200b'+Username,inline=False) 889 #details.add_field(name="Username",value=Username,inline=False) 890 jsonData = getJSONFile() 891 for i in jsonData['registry']: 892 if i['uuid'] == str(uuid): 893 DiscordUser = Guild.get_member(int(i['discordID'])) 894 details.add_field(name="Discord Account:",value='\u200b'+DiscordUser.mention,inline=False) 895 break 896 897 ToDelete.append(await ctx.channel.send(embed = details)) 898 for i in ToDelete: 899 await i.delete(delay=10) 900 901 except Exception as E: 902 i = await ctx.channel.send(embed=discord.Embed(colord=discord.Color.dark_gold(),description="There was an error finding that user, they most likely have not linked their accounts yet.")) 903 await i.delete(delay=10) 904 905 #Display the registry of the server 906 @bot.command(help="Duke/Duchess level command") 907 @commands.has_any_role(*DukeCheck) 908 async def registry(ctx): 909 await ctx.message.delete() 910 jsonData = getJSONFile() 911 912 details = discord.Embed(color=discord.Color.dark_gold(),title="Registry of the server") 913 page = [] 914 book = [] 915 916 for i in jsonData['registry']: 917 soup = bs4(requests.get("https://mcuuid.net/?q="+str(i['uuid'])).content,features="html.parser") 918 mcName = soup.find("input",attrs={"id":"results_username"})["value"] 919 disName = Guild.get_member(int(i['discordID'])).mention 920 if len(page) % 9 == 0 and len(page) != 0: 921 book.append(page) 922 page = [] 923 else: 924 page.append({"header":mcName,"value":disName}) 925 926 if len(book) == 0: 927 book.append(page) 928 929 Page = 0 930 Forward = "⏩" 931 Back = "⏪" 932 933 for i in book[Page]: 934 details.add_field(name = i["header"],value = '\u200b'+i["value"]) 935 details.set_footer(text = "Run `Fish userinfo` to get extended details about a user. A Admin version of that command will be made eventually but I honestly am tired of tweaking this and it not working so who knows anymore") 936 937 Message = await ctx.channel.send(embed=details) 938 while True: 939 EmbedData = discord.Embed(color=discord.Color.dark_gold()) 940 for i in book[Page]: 941 EmbedData.add_field(name = i["header"],value = '\u200b'+i["value"]) 942 EmbedData.set_footer(text = "Run `Fish userinfo [username]` to get extended details about a user. A Admin version of that command will be made eventually but I honestly am tired of tweaking this and it not working so who knows anymore") 943 944 await Message.edit(embed=EmbedData) 945 946 left = Page != 0 947 right = Page != len(book) - 1 948 949 if left: 950 await Message.add_reaction(Back) 951 if right: 952 await Message.add_reaction(Forward) 953 try: 954 Reaction = await bot.wait_for("reaction_add",check = ReactionCheck(Message,left,right),timeout=200) 955 except asyncio.TimeoutError: 956 await Message.delete() 957 return 958 else: 959 if str(Reaction[0]) == Back: 960 Page -= 1 961 await Message.remove_reaction(emoji=Back,member=ctx.message.author) 962 if Page == 0: 963 await Message.remove_reaction(emoji=Back,member=bot.user) 964 elif str(Reaction[0]) == Forward: 965 Page += 1 966 await Message.remove_reaction(emoji=Forward,member=ctx.message.author) 967 if Page == len(book) - 1: 968 await Message.remove_reaction(emoji=Forward,member=bot.user) 969 970 #Admin help 971 @bot.command(help = "Duke/Duchess level command") 972 @commands.has_any_role(*CountCheck) 973 async def adminhelp(ctx): 974 Help = discord.Embed(color=discord.Color.dark_gold()) 975 Help.add_field(name = "BOT PREFIX", value = "Fish") 976 Help.add_field(name = "FURTHER HELP", value = "Run the command with `help` after to get help. EX: `Fish clear help` - NOT FULLY IMPLIMENTED YET") 977 Help.add_field(name = "loop", value = "Has 3 sub-commands: Restart, Start and Stop. They will each do that to the Throne Room loop. EX: Fish loop start/stop/restart") 978 Help.add_field(name = "clear", value = "Will clear an amount of messages from a given channel if you have the correct rank. EX: `Fish clear 23`") 979 Help.add_field(name = "serverfile", value = "List the properties of the *server.properties* file the Minecraft server is using. EX: `Fish serverfile`") 980 Help.add_field(name = "mccommand", value = "Run a minecraft command from here in discord. Will be run with OP. EX: `Fish mccommand` then follow the prompts") 981 Help.add_field(name = 'prunecheck',value = 'Check what users would have roles revoked if I were to prune them') 982 Help.add_field(name = 'errors',value='Posts the Error logs from the bot') 983 await ctx.channel.send(embed = Help) 984 985 @bot.command(help='Regent level command') 986 @commands.has_any_role(*RegentCheck) 987 async def changechannel(ctx): 988 global importantChannels 989 ToDelete = [] 990 await ctx.message.delete() 991 embed = discord.Embed(color=discord.Color.dark_gold(),title='Which channel function are we working on today eh mate?') 992 embed.add_field(name='1',value='Admin bots') 993 embed.add_field(name='2',value='Throne room') 994 embed.add_field(name='3',value='Announcements') 995 embed.add_field(name='4',value='Server stats') 996 embed.add_field(name='5',value='Server rules') 997 embed.description='Just type out the number. I\'ll getcha more instructions ;)' 998 embedMessage = await ctx.channel.send(embed=embed) 999 ToDelete.append(embedMessage) 1000 try: 1001 update = await bot.wait_for('message',check=lambda i: i.author==ctx.message.author,timeout=60) 1002 except asyncio.TimeoutError: 1003 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description=random.choice(TIMEOUTR)))) 1004 else: 1005 await update.delete() 1006 if int(update.content) == 1: 1007 embed = discord.Embed(color=discord.Color.dark_gold(),description=('Mention the channel to replace '+importantChannels['adminbots'].mention+' with')) 1008 elif int(update.content) == 2: 1009 embed = discord.Embed(color=discord.Color.dark_gold(),description=('Mention the channel to replace '+importantChannels['throneroom'].mention+' with')) 1010 elif int(update.content) == 3: 1011 embed = discord.Embed(color=discord.Color.dark_gold(),description=('Mention the channel to replace '+importantChannels['announcements'].mention+' with')) 1012 elif int(update.content) == 4: 1013 embed = discord.Embed(color=discord.Color.dark_gold(),description=('Mention the channel to replace '+importantChannels['serverstats'].mention+' with')) 1014 elif int(update.content) == 5: 1015 embed = discord.Embed(color=discord.Color.dark_gold(),description=('Mention the channel to replace '+importantChannels['serverrules'].mention+' with')) 1016 1017 await embedMessage.edit(embed=embed) 1018 try: 1019 newChannel = await bot.wait_for('message',check=lambda i: i.author==ctx.message.author,timeout=60) 1020 ToDelete.append(newChannel) 1021 except asyncio.TimeoutError: 1022 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description=random.choice(TIMEOUTR)))) 1023 return 1024 else: 1025 jsonData = getJSONFile() 1026 if update.content == '1': 1027 importantChannels['adminbots'] = Guild.get_channel(newChannel.raw_channel_mentions[0]) 1028 jsonData['channels']['admin-bots'] = importantChannels['adminbots'].id 1029 ToDelete.append(await importantChannels['adminbots'].send(embed=discord.Embed(color=discord.Color.dark_gold(),description='New channel'))) 1030 elif update.content == '2': 1031 importantChannels['throneroom'] = Guild.get_channel(newChannel.raw_channel_mentions[0]) 1032 jsonData['channels']['throne-room'] = importantChannels['throneroom'].id 1033 ToDelete.append(await importantChannels['throneroom'].send(embed=discord.Embed(color=discord.Color.dark_gold(),description='New channel'))) 1034 elif update.content == '3': 1035 importantChannels['announcements'] = Guild.get_channel(newChannel.raw_channel_mentions[0]) 1036 jsonData['channels']['admin-bots'] = importantChannels['adminbots'].id 1037 ToDelete.append(await importantChannels['announcements'].send(embed=discord.Embed(color=discord.Color.dark_gold(),description='New channel'))) 1038 elif update.content == '4': 1039 importantChannels['serverstats'] = Guild.get_channel(newChannel.raw_channel_mentions[0]) 1040 jsonData['channels']['stats'] = importantChannels['stats'].id 1041 ToDelete.append(await importantChannels['serverstats'].send(embed=discord.Embed(color=discord.Color.dark_gold(),description='New channel'))) 1042 elif update.content == '5': 1043 importantChannels['serverrules'] = Guild.get_channel(newChannel.raw_channel_mentions[0]) 1044 jsonData['channels']['rules'] = importantChannels['serverrules'].id 1045 ToDelete.append(await importantChannels['serverrules'].send(embed=discord.Embed(color=discord.Color.dark_gold(),description='New channel'))) 1046 writeJSONFile(jsonData) 1047 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description='It has been done. Good job, you got past 3 steps in the process, 2 role checks, and 30 lines of code to get this done'))) 1048 1049 for i in ToDelete: 1050 await i.delete(delay=20) 1051 1052 @bot.command(help='Prank minecraft players') 1053 async def prank(ctx): 1054 def linkCheck(User): 1055 jsonData = getJSONFile() 1056 for i in jsonData['registry']: 1057 if i['discordID'] == User.id: 1058 return True 1059 return False 1060 1061 server = await serverCheck(ctx) 1062 jsonData = getJSONFile() 1063 if server == 'main': 1064 p = jsonData['RCON']['main']['mainport'] 1065 else: 1066 p = jsonData['RCON']['secondary']['mainport'] 1067 ping = mctools.PINGClient(host=jsonData['RCON']['ip'],port=int(p)) 1068 stats = ping.get_stats() 1069 pList = '' 1070 try: 1071 for index,i in enumerate(stats['players']['sample']): 1072 if index < len(stats['players']['sample'])-1: 1073 temp = i[0].replace('\x1b','') 1074 temp = temp.replace('[0m','') 1075 1076 pList += (temp+', ') 1077 else: 1078 temp = i[0].replace('\x1b','') 1079 temp = temp.replace('[0m','') 1080 pList += (temp) 1081 except Exception as E: 1082 pList='No one online...Sorry' 1083 1084 ToDelete=[] 1085 if linkCheck(ctx.message.author): 1086 await ctx.message.delete() 1087 commands = ['execute at PLAYER run playsound entity.creeper.primed master PLAYER ~ ~ ~ 1',\ 1088 'execute at PLAYER run playsound entity.enderman.scream master PLAYER ~ ~ ~ 1',\ 1089 'execute at PLAYER run particle minecraft:elder_guardian'] 1090 1091 temp = discord.Embed(color=discord.Color.dark_gold(),description='Give me the minecraft username of who you would like to prank') 1092 temp.set_footer(text=('Available players: '+pList)) 1093 ToDelete.append(await ctx.channel.send(embed=temp)) 1094 1095 try: 1096 prankee = await bot.wait_for('message',check = lambda i: i.author == ctx.message.author,timeout=60) 1097 ToDelete.append(prankee) 1098 except asyncio.TimeoutError: 1099 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description=random.choice(TIMEOUTR)))) 1100 else: 1101 options = discord.Embed(color=discord.Color.dark_gold(),title=('Please respond with the according number to what you would like to do to '+prankee.content)) 1102 options.add_field(name='1',value='Create a hissing creeper sound at the player') 1103 options.add_field(name='2',value='Create a Enderman scream sound at the player') 1104 options.add_field(name='3',value='Create the visual effect of an Elder Guardian cursing the player') 1105 options.set_footer(text='[1/2/3] is what you should put in the chat') 1106 ToDelete.append(await ctx.channel.send(embed = options)) 1107 try: 1108 toRun = await bot.wait_for('message',check = lambda i: i.author == ctx.message.author,timeout=60) 1109 ToDelete.append(toRun) 1110 except asyncio.TimeoutError: 1111 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description=random.choice(TIMEOUTR)))) 1112 else: 1113 c = commands[int(toRun.content)].replace('PLAYER',str(prankee.content)) 1114 textData = opCommand(c,ctx.message.author,server) 1115 1116 embed = discord.Embed(color=discord.Color.dark_gold()) 1117 embed.add_field(name='Server response',value=('\u200b'+textData)) 1118 embed.set_footer(text='If no value given, the player was either not online or you misspelled their username') 1119 ToDelete.append(await ctx.channel.send(embed=embed)) 1120 else: 1121 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description='Mate...You gotta link your accounts before you can prank other players...`Fish link` is the command for that'))) 1122 1123 for i in ToDelete: 1124 await i.delete(delay=15) 1125 1126 @bot.command(help='Duke/Duchess level command') 1127 @commands.has_any_role(*DukeCheck) 1128 async def event(ctx): 1129 ToDelete=[] 1130 await ctx.message.delete() 1131 server = await serverCheck(ctx) 1132 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description='Please give me the message to list as the upcoming event for the server'))) 1133 try: 1134 event = await bot.wait_for("message",check=lambda i: i.author == ctx.message.author,timeout=60) 1135 ToDelete.append(event) 1136 except asyncio.TimeoutError: 1137 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description=random.choice(TIMEOUTR)))) 1138 else: 1139 jsonData = getJSONFile() 1140 if server == 'main': 1141 jsonData['stats']['main']['event'] = event.content 1142 elif server == 'server': 1143 jsonData['stats']['secondary']['event'] = event.content 1144 writeJSONFile(jsonData) 1145 1146 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description='It is done...Farewhell. The event will show up soonish, the message updates every few minutes'))) 1147 1148 for i in ToDelete: 1149 await i.delete(delay=15) 1150 1151 @bot.command(help='Regent level command') 1152 @commands.has_any_role(*RegentCheck) 1153 async def prunecheck(ctx): 1154 await ctx.message.delete() 1155 ToDelete = [] 1156 temp=discord.Embed(color=discord.Color.dark_gold(),description='How long should I check back in the databases?') 1157 temp.set_footer(text='You need to put a integer or I\'ll be sad') 1158 temp=await ctx.channel.send(embed=temp) 1159 ToDelete.append(temp) 1160 response = (await bot.wait_for('message',check=lambda i: i.author == ctx.message.author,timeout=60)) 1161 ToDelete.append(response) 1162 days=int(response.content) 1163 prunedInt = str(await Guild.estimate_pruned_members(days=30,roles=Guild.roles)) 1164 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description='Amount of innactive members in the last '+str(days)+' days: '+prunedInt))) 1165 ToDelete.append(await ctx.channel.send('https://tenor.com/view/hacker-sombra-overwatch-hacking-gif-7952445')) 1166 memberList = [] 1167 for i in Guild.members: 1168 ID = i.id 1169 found = False 1170 for channel in Guild.text_channels: 1171 for message in await channel.history().flatten(): 1172 if message.author.id == ID and int(message.created_at.strftime('%s')) > int(time.time() - days*24*60*60): 1173 memberList.append(i) 1174 found = not found 1175 break 1176 if found: 1177 break 1178 1179 purgedMembers = '' 1180 for i in Guild.members: 1181 if i not in memberList: 1182 purgedMembers += str(i.mention)+' ' 1183 1184 embed = discord.Embed(color=discord.Color.dark_gold(),title='Users that would be effected by removing all heigherachical roles',description=purgedMembers) 1185 await ctx.channel.send(embed=embed) 1186 1187 for i in ToDelete: 1188 await i.delete(delay = 20) 1189 1190 #Just for voting in the throne room 1191 async def on_raw_reaction_add(payload): 1192 """def RoleGetter(Member,RoleNeeded): 1193 Cleared = False 1194 for role in Member.roles: 1195 if role.name == RoleNeeded: 1196 Cleared = True 1197 elif role.name == RoleHeigherarchy[6]: 1198 Cleared = True 1199 return Cleared""" 1200 1201 User = Guild.get_member(payload.member.id) 1202 if (payload.channel_id == importantChannels['throneroom'].id): 1203 jsonData = getJSONFile() 1204 for i in jsonData['throne-room']['messages']: 1205 message = await importantChannels['throneroom'].fetch_message(i['messageID']) 1206 requestedMale = message.mentions[0] 1207 requestedFemale = message.mentions[0] 1208 if not (requestedMale in User.roles or requestedFemale in User.roles): 1209 await message.remove_reaction(payload.emoji,payload.member) 1210 1211 #Respond to "E" 1212 @bot.listen("on_message") 1213 async def Responder(message): 1214 if message.content == "E": 1215 Message2 = await message.channel.send(embed = discord.Embed(color=discord.Color.dark_gold(),description="Oh?")) 1216 await message.delete(delay = 5) 1217 await Message2.delete(delay = 5) 1218 if bot.user.mentioned_in(message): 1219 await message.channel.send('https://tenor.com/view/summoned-gif-21949657') 1220 for i in message.author.roles: 1221 if i.name == RoleHeigherarchy[-1]: 1222 temp = await message.channel.send('https://tenor.com/view/roger-that-copy-that-yes-sir-yes-maam-ok-gif-18243692') 1223 await temp.delete(delay=5) 1224 break 1225 1226 @bot.event 1227 async def on_member_remove(member): 1228 jsonData = getJSONFile() 1229 for i in jsonData['registry']: 1230 if i['discordID'] == member.id: 1231 soup = bs4(requests.get("https://mcuuid.net/?q="+str(i['uuid'])),features="html.parser") 1232 Username = soup.find("input",attrs={"id":"results_username"})["value"] 1233 textData = opCommand('whitelist remove '+Username, member, 'main') 1234 textData += ' ' + opCommand('whitelist remove '+Username, member, 'secondary') 1235 jsonData.remove(i) 1236 writeJSONFile(jsonData) 1237 await importantChannels['adminbots'].send(embed = discord.Embed(color=discord.Color.dark_gold(),description='\u200b'+textData)) 1238 1239 @bot.event 1240 async def on_member_join(member): 1241 sysChannel = Guild.system_channel 1242 await sysChannel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description=(str(member.mention) + ' Please read the ' + importantChannels['serverrules'].mention + ' and a member of the Duchy will be with you soon to get you your roles and verify with you you read the ' + importantChannels['serverrules'].mention))) 1243 for role in Guild.roles: 1244 if role.name == RoleHeigherarchy[3]: 1245 r1 = role 1246 elif role.name == RoleHeigherarchy2[3]: 1247 r2 = role 1248 await importantChannels['adminbots'].send(text=(str(member.mention)+' is in need of roles and whatnot that I have been told I cant do ~~* cough cough * Vasco * cough cough *~~. Please see to it '+str(r1.mention)+'/'+str(r2.mention))) 1249 1250 #Handle errors 1251 """@bot.event 1252 async def on_command_error(ctx, error): 1253 ToDelete = [ctx.message] 1254 if isinstance(error, discord.ext.commands.CommandNotFound): 1255 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description=random.choice(BADCOMMANDR)))) 1256 elif isinstance(error,discord.ext.commands.errors.CommandOnCooldown): 1257 choices = ['My guy, try slowing your yee haws down for a minute','Holdup there cowboy, that\'s on a there cooldown','I dont know bout you, but I think you\'re running that command too often',\ 1258 'Just...Just stop that...You\'re too fast there mate'] 1259 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description=random.choice(choices)))) 1260 elif isinstance(error,discord.ext.commands.MissingAnyRole): 1261 choices=['Hey there cowboy...You dont have access to that command','Dont go tryin that now, you might catch attention of the big bad mods',\ 1262 'I see you dont have your papers...No access for you kiddo','INTRUDER - INTRUDER - INTRUDER - THEY DONT HAVE THE ROLES NEEDED','Come back when you have the correct role for that'] 1263 ToDelete.append(await ctx.channel.send(embed=discord.Embed(color=discord.Color.dark_gold(),description=random.choice(choices)))) 1264 elif isinstance(error,discord.ext.commands.NoPrivateMessage): 1265 choices = ['I told you to STTTOOOOOPPPPP running commands through DMs!','No you','I lost the game',\ 1266 'I\'m normally never going to let you down, but this time I\'m going to have to give you up','Tryin to bypass the system I see','Go away'] 1267 await ctx.author.send(embed=discord.Embed(color=discord.Color.dark_gold(),description=random.choice(choices))) 1268 logger.info(str(ctx.author)+' is DMing me this: '+str(ctx.message.content)) 1269 else: 1270 await importantChannels['adminbots'].send(embed=discord.Embed(color=discord.Color.dark_gold(),description='Error found. Check the ERRORS.log file')) 1271 logger.error(error) 1272 for i in ToDelete: 1273 await i.delete(delay=30)""" 1274 1275 bot.run(TOKEN)