from discord import option from discord.ext import commands, tasks import discord import requests from bs4 import BeautifulSoup import re import os class PalWorld(commands.Cog): def __init__(self, bot): self.bot: commands.Bot = bot # self.poll_server_population.start() palworld = discord.SlashCommandGroup("palworld", "Palworld related commands") async def get_all_pals(ctx: discord.AutocompleteContext): """ returns a list of all pals in the game, which can then be passed to the /ship command for auto complete """ import requests from bs4 import BeautifulSoup all_pals = [] url = "https://paldex.io/palworld/pals/" response = requests.get(url) soup = BeautifulSoup(response.text, "html.parser") x = soup.find_all( "p", class_="text-base lg:text-lg group-hover:underline underline-offset-4 text-center", ) for pal in x: all_pals.append(pal.text) return sorted(set(all_pals)) @palworld.command( guild_ids=None, name="paldeck", description="Looks up data about a pal", ) async def pal_lookup( self, ctx: commands.Context, pal: discord.Option( str, autocomplete=discord.utils.basic_autocomplete(get_all_pals), description="Pal to look up", ), ): pal_url = "https://paldex.io/palworld/pals/%s/" % pal.lower().replace(" ", "-") response = requests.get(pal_url) soup = BeautifulSoup(response.text, "html.parser") elements = {} pal_elements = soup.find("div", class_="flex flex-row flex-wrap gap-3") for div in pal_elements: pal_element_badge = div.find("img", class_="rounded-full w-12 px-2 py-2") element_type = pal_element_badge.find_next("p").text element_icon = "https://paldex.io" + pal_element_badge["src"] elements[element_type] = element_icon primary_element = list(elements.keys())[0] # https://discordpy.readthedocs.io/en/latest/api.html?highlight=colour#discord.Colour color_lookup = { "Dark": discord.Color.dark_purple(), "Dragon": discord.Color.purple(), "Earth": discord.Color.greyple(), "Electricity": discord.Color.yellow(), "Fire": discord.Color.red(), "Leaf": discord.Color.green(), "Ice": discord.Color.blue(), "Normal": discord.Color.lighter_grey(), "Water": discord.Color.dark_blue(), } embed = discord.Embed( description="-------", color=color_lookup[primary_element], type="rich", title=pal.capitalize(), ) embed.set_author( name=", ".join(elements.keys()), icon_url=elements[primary_element], url=pal_url, ) embed.set_thumbnail( url=soup.find( "img", class_="rounded-full w-32 sm:w-auto border-2 border-amber-500 aspect-square", )["src"] ) # embed.add_field(name="Work Skills", value="-----", inline=False) # work skills skills_emojis = { "Cooling": "❄️", "Farming": "🚜", "Gathering": "🍃", "Generating Electricity": "⚡️", "Handwork": "🤚", "Kindling": "🔥", "Lumbering": "🪵", "Medicine Production": "💉", "Mining": "⛏️", "Planting": "🌱", "Transporting": "📦", "Watering": "💦", } skill_table = soup.find("div", class_="flex flex-col gap-2") for div in skill_table.find_all( "div", class_=re.compile(".*border-amber-300\s+break-all") ): skill_name = div.find("p", class_="text-base sm:text-lg").text skill_level = div.find( "p", class_="text-base sm:text-lg mr-2 md:mr-4" ).text.split("Lv")[-1] embed.add_field( name=skills_emojis[skill_name] + " " + skill_name, value="%s" % (int(skill_level) * "⭐️"), inline=True, ) # Partner Skill embed.add_field(name="Partner Skill", value="-----", inline=False) skill_name = soup.find("h2", string="Partner Skill").find_next( "p", class_=re.compile(".*text-xl.*") ) skill_description = skill_name.find_next("p", class_="text-lg mr-4").text embed.add_field( name=skill_name.text, value=skill_description, inline=False, ) # Drops embed.add_field(name="Drops", value="-----", inline=False) for div in soup.find_all( "div", class_="inline-flex flex-col gap-1 items-center bg-black-300 border border-amber-300 break-all p-2", ): item = div.text item_name = item.split("Quantity")[0].split("Drop Chance") amount = item.split("Quantity")[-1].split("Drop Chance") embed.add_field( name=" ".join(item_name), value="", inline=False, ) await ctx.defer() await ctx.send_followup(embed=embed) @palworld.command( guild_ids=None, name="elements", description="Posts an infographic about which Pal elements are weak/strong against which", ) async def post_medpen_guide(self, ctx: commands.Context): await ctx.respond( "https://img.game8.co/3822502/5ae8382d16bd390dd19f343e87680d51.png/show" ) # @tasks.loop(seconds=60) # async def poll_server_population(self): # # Wait until the bot is ready before we actually start executing code # await self.bot.wait_until_ready() # from source_rcon import SourceRcon # from loguru import logger # logger.disable("source_rcon") # rcon = SourceRcon("192.168.1.200", 25575, os.getenv("pal_rcon_pass")) # num_players = len(rcon.send_command("ShowPlayers").split("\n")[1:-1]) # # channel = self.bot.get_channel(1201389692759842816) # test server # channel = self.bot.get_channel(1199397770746925239) # if str(num_players) in channel.name.split("/")[0]: # return # await channel.edit(name="Palworlders (%s/16 online)" % num_players) def setup(bot): bot.add_cog(PalWorld(bot))