dragon-bot/app/cogs/palworld.py
Luke Robles 99776dbae6
All checks were successful
Build and push / changes (push) Successful in 13s
Build and push / Lint-Python (push) Successful in 2s
Build and push / Build-and-Push-Docker (push) Successful in 1m13s
Build and push / sync-argocd-app (push) Successful in 3s
Build and push / post-failure-to-discord (push) Has been skipped
Build and push / post-success-to-discord (push) Successful in 1s
Use ruff and conert stock to fstrings
2025-05-07 15:23:32 -07:00

224 lines
7.1 KiB
Python
Executable File

from discord.ext import commands
import discord
import requests
from bs4 import BeautifulSoup
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
url = "https://palworld.gg/pals"
response = requests.get(url).text
soup = BeautifulSoup(response, "html.parser")
pal_list = []
all_pals = soup.find_all("div", class_="pal")
try:
for pal in all_pals:
name = pal.find("div", class_="name").text.split("#", 1)[0].strip()
pal_list.append(name)
except:
pass
return pal_list
@palworld.command(
guild_ids=None,
name="paldeck",
description="Looks up data about a pal",
contexts={
discord.InteractionContextType.guild,
discord.InteractionContextType.bot_dm,
discord.InteractionContextType.private_channel,
},
integration_types={
discord.IntegrationType.guild_install,
discord.IntegrationType.user_install,
},
)
async def pal_lookup(
self,
ctx: discord.ApplicationContext,
pal: discord.Option(
str,
autocomplete=discord.utils.basic_autocomplete(get_all_pals),
description="Pal to look up",
),
):
pal_url = f"https://palworld.gg/pal/{pal.lower().replace(' ', '-')}"
response = requests.get(pal_url)
soup = BeautifulSoup(response.text, "html.parser")
elements = {}
# Get the pal's primary element
pal_elements_div = soup.find("div", class_="elements")
element_icon = "https://palworld.gg" + pal_elements_div.find("img")["src"]
element_type = pal_elements_div.find_next("div")
elements[element_type.text] = element_icon
# 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.dark_orange(),
"Electricity": discord.Color.yellow(),
"Fire": discord.Color.red(),
"Leaf": discord.Color.green(),
"Ice": discord.Color.blue(),
"Neutral": discord.Color.lighter_grey(),
"Water": discord.Color.dark_blue(),
}
embed = discord.Embed(
description="-------",
color=color_lookup[element_type.text],
type="rich",
title=pal.capitalize(),
)
embed.set_author(
name="/".join(
[x.text for x in pal_elements_div.find_all("div", class_="name")]
),
icon_url=elements[element_type.text],
url=pal_url,
)
embed.set_thumbnail(
url="https://palworld.gg"
+ soup.find("div", class_="image").find_next("img")["src"]
)
# embed.add_field(name="Work Skills", value="-----", inline=False)
# work skills
skills_emojis = {
"Cooling": "❄️",
"Farming": "🚜",
"Gathering": "🍃",
"Generating Electricity": "⚡️",
"Handiwork": "🤚",
"Kindling": "🔥",
"Deforesting": "🪵",
"Medicine Production": "💉",
"Mining": "⛏️",
"Planting": "🌱",
"Transporting": "📦",
"Watering": "💦",
"Oil Extracting": "🛢️",
}
work_suit = (
soup.find("h2", string="Work Suitability")
.find_next("div", class_="items")
.find_all("div", class_="active item")
)
for skill in work_suit:
skill_name, skill_level = skill.text.split("Lv")
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 = soup.find("div", class_="passive skills")
skill_name = skill.find_next("div", class_="name").text
skill_description = (
skill.find_next("p")
.text.replace("COMMON_ELEMENT_NAME_", "")
.replace("\n", " ")
)
embed.add_field(
name=skill_name,
value=skill_description,
inline=False,
)
# Drops
embed.add_field(name="Drops", value="-----", inline=False)
try:
drops = [
x.text
for x in soup.find("h2", string="Possible Drops")
.find_next("table")
.find_all("div", class_="name")
]
except:
drops = ["None"]
for item in drops:
embed.add_field(
name=item,
value="",
inline=False,
)
embed.add_field(
name="",
value=f"https://palworld.gg/pal/{pal.lower().replace(' ', '-')}",
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",
contexts={
discord.InteractionContextType.guild,
discord.InteractionContextType.bot_dm,
discord.InteractionContextType.private_channel,
},
integration_types={
discord.IntegrationType.guild_install,
discord.IntegrationType.user_install,
},
)
async def post_medpen_guide(self, ctx: discord.ApplicationContext):
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))