2021-06-05 15:12:30 +00:00
# {{{ Imports
2021-06-30 01:10:54 +00:00
import discord , requests , json , time , os , hypixel_bot_tools . errors , tempfile
2021-06-05 15:12:30 +00:00
from discord . ext import commands
2021-07-21 01:56:13 +00:00
from hypixel_bot_tools import * #the modular aspect of HypiBot
2021-06-30 01:10:54 +00:00
from cairosvg import svg2png
2021-06-18 23:03:08 +00:00
hypierror = hypixel_bot_tools . errors
2021-06-05 15:12:30 +00:00
# }}}
# {{{ Get token
2021-06-05 14:43:39 +00:00
try :
2021-06-05 15:12:30 +00:00
from Token import HYPIXEL_API_KEY , DISCORD_API_KEY , PREFIX
2021-06-05 14:43:39 +00:00
except ImportError :
print ( " \t FATAL! \t Could not load Token.py file. Please change the Token.example.py to your liking and make sure that it is valid Python syntax " )
raise
2021-06-05 15:12:30 +00:00
# }}}
# {{{ Setup bot
bot = commands . Bot ( command_prefix = PREFIX )
@bot.event
async def on_ready ( ) :
print ( " Ready for action Rider sir! " )
print ( " PAW PATROL! PAW PATROL! WE ' LL BE THERE ON THE DOUBLEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE " )
2021-07-21 01:56:13 +00:00
#sorry
2021-06-05 15:12:30 +00:00
# }}}
# {{{ pre-gettext wrapper
def _ ( string ) :
2021-07-21 01:56:13 +00:00
return string #so that we don't have to do a major refac when (if) we add gettext
2021-06-05 15:12:30 +00:00
# }}}
2021-06-06 18:45:42 +00:00
# {{{ Command
2021-06-05 15:12:30 +00:00
@bot.command ( name = " uuid " )
2021-06-18 23:26:35 +00:00
async def uuid ( ctx , username ) :
2021-06-05 15:12:30 +00:00
"""
Gets the UUID of a player . based on their username .
"""
2021-06-05 23:31:22 +00:00
status = await ctx . send ( _ ( " Loading from API... " ) )
2021-06-05 15:12:30 +00:00
req = getuuid ( username )
2021-06-06 19:39:54 +00:00
await status . edit ( content = _ ( " Player UUID: %s " ) % req )
2021-06-05 16:35:19 +00:00
@bot.command ( )
async def ping ( ctx ) :
''' I ' m a good person! TOTALLY not stolen from https://www.programcreek.com/python/?code=Der-Eddy %2F discord_bot %2F discord_bot-master %2F cogs %2F utility.py '''
ping = ctx . message
2021-07-21 01:56:13 +00:00
pong = await ctx . send ( ' **:ping_pong:** Pong! ' )
2021-06-05 16:35:19 +00:00
delta = pong . created_at - ping . created_at
delta = int ( delta . total_seconds ( ) * 1000 )
hi1 = time . time ( )
await pong . edit ( content = f ' :ping_pong: Pong! ( { delta } ms) \n *Finding Discord message edit latency...* ' )
hi2 = time . time ( )
await pong . edit ( content = f ' :ping_pong: Pong! ( { delta } ms) \n *Discord message edit latency: { hi2 - hi1 } * ' )
2021-06-06 15:51:31 +00:00
@bot.command ( name = " hypixel " , aliases = ( " h " , " stats " ) )
2021-06-30 01:25:52 +00:00
async def hypixel ( ctx , player , ConvertToUUID = True , v2 = True ) :
2021-06-05 23:31:22 +00:00
"""
Checks overall stats
2021-06-06 20:32:38 +00:00
Change ConvertToUUID to False if you want to pass in the UUID , example : ` $ h < UUID > False ` instead of ` $ h < PlayerName > ` .
2021-06-05 23:31:22 +00:00
"""
2021-06-06 19:39:54 +00:00
if checkapi ( HYPIXEL_API_KEY ) is False :
2021-06-06 02:08:25 +00:00
await ctx . send ( _ ( " :warning: Ran out of API queries per minute. Please wait a little while before continuing... " ) )
return False
2021-06-06 02:11:21 +00:00
thing = await ctx . send ( _ ( " Fetching player data... If this message doesn ' t go away, the bot is _definitely_ not broken. :soundsrightbud: " ) )
2021-06-06 20:38:43 +00:00
try :
contents = overall ( HYPIXEL_API_KEY , player , ConvertToUUID )
2021-06-18 23:03:08 +00:00
except hypierror . InvalidPlayer :
2021-06-06 20:38:43 +00:00
await thing . edit ( content = _ ( " :warning: Invalid player! " ) ) ; raise
2021-06-07 00:50:49 +00:00
lenfriends = countfriends ( friends ( HYPIXEL_API_KEY , player , ConvertToUUID ) )
2021-06-07 20:46:27 +00:00
try :
statusAPI = contents [ ' settings ' ] [ ' apiSession ' ]
except KeyError :
statusAPI = True
if not statusAPI :
statusAPI_Message = _ ( " API access disabled " )
currentStatus_Message = _ ( " Unavailable - API access disabled " )
else :
item = status ( HYPIXEL_API_KEY , player , ConvertToUUID ) [ ' session ' ]
statusAPI_Message = item [ ' online ' ]
2021-07-21 01:56:13 +00:00
#todo: i'm a bit dubious about this code {{{
2021-06-07 20:46:27 +00:00
try :
2021-06-08 15:04:02 +00:00
for i in ( " gameType " , " mode " , " map " ) :
2021-07-21 01:56:13 +00:00
try : item [ i ]
2021-06-08 15:04:02 +00:00
except KeyError :
if i == " gameType " :
2021-07-21 01:56:13 +00:00
raise #set current status message to offline
2021-06-08 15:04:02 +00:00
item [ i ] = " N/A "
2021-06-07 20:46:27 +00:00
currentStatus_Message = f " { item [ ' gameType ' ] } ( { _ ( ' mode ' ) } { item [ ' mode ' ] } ); { _ ( ' on map ' ) } { item [ ' map ' ] } "
2021-06-30 01:10:54 +00:00
onlinecolour = " green "
2021-06-07 20:46:27 +00:00
except KeyError :
currentStatus_Message = _ ( " Offline " )
2021-06-30 01:10:54 +00:00
onlinecolour = " #454545 "
2021-07-21 01:56:13 +00:00
# }}} endtodo
2021-06-07 20:46:27 +00:00
for i in ( " karma " , ) : #these are fields that might not exist
try :
contents [ i ]
except KeyError :
contents [ i ] = 0
continue
2021-07-21 01:56:13 +00:00
#todo: move this to an if not v2
2021-06-06 02:08:25 +00:00
em = discord . Embed (
2021-06-06 15:51:31 +00:00
title = f " { contents [ ' displayname ' ] } ' { _ ( ' s Hypixel Stats ' ) } " ,
2021-06-06 02:08:25 +00:00
footer = _ ( " Thanks for using Hypibot! " ) )
2021-06-30 01:10:54 +00:00
val = f " { round ( RawXPToLevel ( contents [ ' networkExp ' ] ) , 2 ) } ( { _ ( ' raw ' ) } { int ( contents [ ' networkExp ' ] ) } ) "
2021-06-06 02:08:25 +00:00
em . add_field ( name = _ ( " UUID " ) , value = getuuid ( player ) , inline = True )
2021-06-06 21:17:54 +00:00
em . add_field ( name = _ ( " Rank " ) , value = contents [ ' rank ' ] , inline = True )
2021-06-30 01:10:54 +00:00
em . add_field ( name = _ ( " Network Level " ) , value = val , inline = True )
2021-06-07 00:50:49 +00:00
em . add_field ( name = _ ( " Karma " ) , value = contents [ ' karma ' ] , inline = True )
em . add_field ( name = _ ( " Friends " ) , value = lenfriends , inline = True )
2021-06-18 23:03:08 +00:00
em . add_field ( name = " \u200b " , value = " \u200b " , inline = True ) #newline; \u200b is a zero width space that is allowed by dcord
2021-06-07 20:46:27 +00:00
em . add_field ( name = _ ( " Online? " ) , value = statusAPI_Message , inline = True )
2021-06-30 01:25:52 +00:00
em . add_field ( name = _ ( " Current Game " ) , value = currentStatus_Message , inline = True )
2021-06-30 01:10:54 +00:00
with open ( " AnyConv.com__minecraft-2053886_960_7200.svg " ) as file :
2021-06-30 01:25:52 +00:00
svg = file . read ( ) . format ( uuid = getuuid ( player ) , userhtml = """ <text x= " 25 " y= " 100 " style= " font-size:40px; " > {rank}   {displayname} </text> """ . format ( rank = contents [ ' rank ' ] , displayname = contents [ ' displayname ' ] ) , exp = round ( RawXPToLevel ( contents [ ' networkExp ' ] ) , 2 ) , karma = contents [ ' karma ' ] , friends = lenfriends ,
2021-07-21 01:56:13 +00:00
onlinehtml = f ' <text x= " 20 " y= " 250 " style= " fill: { onlinecolour } ; font-size:31px; " > { currentStatus_Message } </text> ' ) #inject details
2021-06-30 01:10:54 +00:00
with tempfile . TemporaryDirectory ( ) as tmp :
2021-09-02 19:12:22 +00:00
print ( tmp )
2021-06-30 01:25:52 +00:00
if v2 :
path = os . path . join ( tmp , ' png.pngpng.png ' ) #https://stackoverflow.com/a/45803022/9654083
svg2png ( bytestring = svg , write_to = path ) #https://stackoverflow.com/questions/6589358/convert-svg-to-png-in-python
with open ( path , " rb " ) as file : #https://stackoverflow.com/questions/60913131/how-to-send-a-image-with-discord-py
file = discord . File ( file , filename = path )
await ctx . send ( " Player data down below. " , file = file )
await thing . delete ( )
2021-07-21 01:56:13 +00:00
if v2 is False : #todo: move em's declaration to here, also use return up above instead of this
2021-06-30 01:25:52 +00:00
await thing . edit ( embed = em , content = " Player data down below. " )
2021-06-23 02:27:30 +00:00
@bot.command ( )
2021-06-23 02:50:38 +00:00
async def bedwars ( ctx , player , ConvertToUUID = True ) :
if checkapi ( HYPIXEL_API_KEY ) is False : #todo; use exceptions instead
await ctx . send ( _ ( " :warning: Ran out of API queries per minute. Please wait a little while before continuing... " ) )
return False
try : contents = overall ( HYPIXEL_API_KEY , player , ConvertToUUID = ConvertToUUID )
except KeyError : raise InvalidPlayer
data = contents [ ' stats ' ] [ ' Bedwars ' ]
em = discord . Embed (
title = _ ( " %s ' s Bedwars Stats " % contents [ ' displayname ' ] ) ,
footer = _ ( " Thanks for using Hypibot! " )
)
em . add_field ( name = _ ( " Experience " ) , value = data [ ' Experience ' ] , inline = True )
em . add_field ( name = _ ( " Coins " ) , value = data [ ' coins ' ] , inline = True )
await ctx . send ( embed = em )
2021-06-23 02:27:30 +00:00
for i in ( " eight_one " , " eight_two " , " three_three " , " two_four " , " four_four " ) :
await ctx . send ( bedwarsToHuman ( i ) )
2021-06-05 15:12:30 +00:00
# }}}
2021-06-18 23:03:08 +00:00
# Error handling {{{
@bot.event
async def on_command_error ( ctx , error ) :
"""
Does some stuff in case of cooldown error .
Stolen from brewbot .
2021-07-21 01:56:13 +00:00
_please don ' t kill me trm..._
( I am the one who added this code btw so it doesn ' t matter)
2021-06-18 23:03:08 +00:00
"""
if hasattr ( ctx . command , ' on_error ' ) : #https://gist.github.com/EvieePy/7822af90858ef65012ea500bcecf1612
return
error = getattr ( error , ' original ' , error )
if isinstance ( error , commands . CommandOnCooldown ) :
potentialMessages = [ f ' This command is on cooldown, please wait { int ( error . retry_after ) } s. ' ]
2021-06-18 23:26:35 +00:00
message = ( random . choice ( potentialMessages ) )
2021-06-18 23:03:08 +00:00
print ( ' \n Someone tried to do a command that was on cooldown ' )
2021-06-18 23:35:03 +00:00
elif isinstance ( error , commands . MissingRequiredArgument ) :
2021-06-18 23:26:35 +00:00
strerror = str ( error ) . split ( ' ' ) [ 0 ]
2021-06-18 23:35:03 +00:00
message = _ ( " You seem to be missing a required argument \" {strerror} \" . Run ` {PREFIX} help [command]` for more information. " ) . format ( PREFIX = PREFIX , strerror = strerror )
elif isinstance ( error , hypierror . HypixelApiDown ) :
message = _ ( " We couldn ' t contact the hypixel API. Is the service down? " )
2021-06-23 02:50:38 +00:00
elif isinstance ( error , hypierror . InvalidPlayer ) :
2021-09-02 19:12:22 +00:00
message = _ ( " This seems to be an invalid player - it doesn ' t have an entry on Mojang ' s API. \n Try running {PREFIX} [command] {uuid} False to search by UUID instead. Run {PREFIX} help bedwars for more info. " ) . format ( PREFIX = PREFIX , uuid = error )
2021-12-07 23:15:46 +00:00
elif isinstance ( error , commands . errors . CommandNotFound ) :
2021-12-07 23:16:45 +00:00
message = _ ( " command not found. Try {PREFIX} help for a list! " ) . format ( PREFIX = PREFIX )
2021-06-18 23:26:35 +00:00
else :
message = " Unknown error ! "
2021-06-18 23:35:03 +00:00
em = discord . Embed ( title = _ ( " ⚠️ Oops! ⚠️ " ) , description = message )
em . set_footer ( text = error )
await ctx . send ( embed = em )
2021-06-18 23:11:09 +00:00
raise ( error )
2021-06-18 23:03:08 +00:00
# }}}
2021-06-05 15:12:30 +00:00
# {{{ Run bot
2021-06-07 00:50:49 +00:00
if __name__ == " __main__ " :
bot . run ( DISCORD_API_KEY )
2021-06-05 15:12:30 +00:00
# }}}