dragon-bot/app/cogs/tarkov.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

296 lines
9.8 KiB
Python
Executable File

from bs4 import BeautifulSoup
from datetime import datetime
from discord.ext import commands, tasks
import discord
import os
import json
import requests
import tarkov
if os.getenv("DRAGON_ENV") == "prod":
channel_id = 815310511776202773
time_limit = 600
else:
channel_id = 932476007439552522
time_limit = 10
class Tarkov(commands.Cog):
def __init__(self, bot):
self.bot: commands.Bot = bot
self.check_boss_spawns.start()
# tarkov = discord.SlashCommandGroup("tarkov", "Tarkov related commands")
@tasks.loop(seconds=time_limit)
async def check_boss_spawns(self):
# Wait until the bot is ready before we actually start executing code
await self.bot.wait_until_ready()
local_spawn_rates = "/tmp/boss_spawns.json"
spawns_from_api = tarkov.get_tarkov_boss_info()
if os.path.exists(local_spawn_rates):
embed = discord.Embed(
description="-------", color=discord.Color.blue(), type="rich"
)
with open(local_spawn_rates, "r") as f:
known_spawns = json.load(f)
if spawns_from_api != known_spawns:
embed.set_author(name="🎲 Boss Spawn Rates Have Changed 🎲")
# Send both dicts to this method to see if any spawn rates have been updated
changes_dict = tarkov.compare_boss_spawns(known_spawns, spawns_from_api)
for level, boss in changes_dict.items():
if boss:
embed.add_field(
name=level,
value="\n".join(
f"{boss_name}: {change}"
for boss_name, change in boss.items()
),
inline=False,
)
await self.bot.get_channel(channel_id).send(embed=embed)
with open(local_spawn_rates, "w") as f:
json.dump(spawns_from_api, f)
else:
with open(local_spawn_rates, "w") as f:
json.dump(spawns_from_api, f)
async def get_all_bosses(ctx: discord.AutocompleteContext):
"""
Returns a list of boss names to be used in auto complete
"""
bosses = tarkov.request_wiki("Bosses", "Bosses")
for boss in bosses:
if boss == "Knight":
bosses[bosses.index(boss)] = "The Goons"
return bosses
@commands.slash_command(
name="kappa",
description="Posts a link to a google doc containing all the tasks you need for kappa",
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_kappa(self, ctx: discord.ApplicationContext):
await ctx.respond(
"https://docs.google.com/spreadsheets/d/1lwU7T1Yxt0s28xZdfFRiDEYH7BbwOkZfsv-Ozv1Ka00/edit?gid=1115791232#gid=1115791232"
)
@commands.slash_command(
name="traders",
description="Time until trader resets",
contexts={
discord.InteractionContextType.guild,
discord.InteractionContextType.bot_dm,
discord.InteractionContextType.private_channel,
},
integration_types={
discord.IntegrationType.guild_install,
discord.IntegrationType.user_install,
},
)
async def trader_resets(self, ctx: discord.ApplicationContext):
await ctx.defer()
embed = discord.Embed(
description="-------", color=discord.Color.blue(), type="rich"
)
embed.set_author(name="PVE Trader Reset Times")
embed.set_thumbnail(
url="https://static1.thegamerimages.com/wordpress/wp-content/uploads/2023/03/from-left-to-right-the-escape-from-tarkov-trader-jaeger-the-escape-from-trakov-trader-therapist-and-the-escape-from-tarkov-trader-peacekeeper.jpg"
)
query = """
{
traders(gameMode:pve) {
name
resetTime
}
}
"""
response = tarkov.query_tarkov_api(query)["traders"]
# Sort the response alphabetically by trader name
response = sorted(response, key=lambda entry: entry["name"])
# Loop through the dataset
for entry in response:
trader_name = entry["name"]
# Convert to datetime object
reset_time = datetime.fromisoformat(
entry["resetTime"].replace("Z", "+00:00")
)
# Print the name and formatted time until reset
embed.add_field(
name=trader_name,
value=discord.utils.format_dt(reset_time, style="R"),
inline=True,
)
await ctx.send_followup(embed=embed)
@commands.slash_command(
name="spawns",
description="Boss Spawn Rates",
contexts={
discord.InteractionContextType.guild,
discord.InteractionContextType.bot_dm,
discord.InteractionContextType.private_channel,
},
integration_types={
discord.IntegrationType.guild_install,
discord.IntegrationType.user_install,
},
)
async def boss_spawns(
self,
ctx: discord.ApplicationContext,
boss_name: discord.Option(
str,
autocomplete=discord.utils.basic_autocomplete(get_all_bosses),
description="The boss you want to look up",
required=False,
),
):
await ctx.defer()
embed = discord.Embed(
description="-------",
color=discord.Color.blue(),
type="rich",
)
embed.set_author(name="🎲 Boss Spawn chances by map 🎲")
embed.set_thumbnail(url="https://i.ytimg.com/vi/Yis5rmgo_bM/maxresdefault.jpg")
if boss_name:
for item in tarkov.get_boss_pictures():
if item["name"] == boss_name:
embed.set_thumbnail(url=item["imagePortraitLink"])
break
embed.set_author(name=f"🎲 Spawn chance for {boss_name} 🎲")
levels = tarkov.get_tarkov_boss_info()
if not boss_name:
for key, value in levels.items():
embed.add_field(
name=key,
value="\n".join(
f"{k}: **{v['spawnChance']}**" for k, v in value.items()
),
inline=False,
)
else:
for key, value in levels.items():
if boss_name in value:
embed.add_field(
name=key,
value=f"{boss_name}: **{value[boss_name]['spawnChance']}**",
inline=False,
)
# break
embed.set_footer(text="Pulled from the api")
await ctx.send_followup(embed=embed)
@commands.slash_command(
guild_ids=None,
name="boss",
description="Boss Info",
contexts={
discord.InteractionContextType.guild,
discord.InteractionContextType.bot_dm,
discord.InteractionContextType.private_channel,
},
integration_types={
discord.IntegrationType.guild_install,
discord.IntegrationType.user_install,
},
)
async def boss_info(
self,
ctx: discord.ApplicationContext,
boss_name: discord.Option(
str, autocomplete=discord.utils.basic_autocomplete(get_all_bosses)
),
):
await ctx.defer()
embed = discord.Embed(
description="-------",
color=discord.Color.blue(),
type="rich",
title=f"Boss info for {boss_name}",
)
wiki_url = "https://escapefromtarkov.fandom.com/wiki/"
response = requests.get(wiki_url + boss_name).text
soup = BeautifulSoup(response, "html.parser")
# boss_info = tarkov.get_tarkov_boss_info()
# for k, v in boss_info.items():
# if boss_name in v:
# print(k, v)
# embed.set_thumbnail(url=v[boss_name]["picture"])
# embed.add_field(
# name="Followers", value=v[boss_name]["escorts"], inline=False
# )
# embed.add_field(
# name="Spawn Chance",
# value=f"{v[boss_name]['spawnChance']}",
# inline=False,
# )
# break
portraits = tarkov.get_boss_pictures()
for boss in portraits:
if boss["name"] == boss_name:
embed.set_thumbnail(url=boss["imagePortraitLink"])
break
health = soup.find("table", class_="wikitable").find_next("td").text.rstrip()
embed.add_field(name="Health", value=health, inline=False)
followers = "None"
if soup.find("span", id="Followers"):
# Find the amount of followers in the text
followers = soup.find("span", id="Followers").find_next("p").text
embed.add_field(name="Followers", value=followers, inline=False)
spawn_chance = "%\n".join(
soup.find("td", class_="va-infobox-label", string="Spawn chance")
.find_next("td", class_="va-infobox-content")
.text.split("%")
)
embed.add_field(name="Spawn Chance", value=f"**{spawn_chance}**", inline=False)
embed.add_field(
name="Link", value=f"{wiki_url + boss_name.replace(' ', '_')}", inline=False
)
await ctx.send_followup(embed=embed)
def setup(bot):
bot.add_cog(Tarkov(bot))