1
Fork 0
mirror of https://github.com/wlinator/luminara.git synced 2024-10-02 18:03:12 +00:00

Lots of refactoring

This commit is contained in:
wlinator 2024-08-14 07:36:12 -04:00
parent bbec1a2622
commit 0cfcfb8b29
13 changed files with 107 additions and 288 deletions

View file

@ -9,15 +9,12 @@ from discord.ext import commands
from discord.ext.commands import TextChannelConverter
from Client import LumiBot
from config.parser import JsonCache
from lib import formatter
from lib.constants import CONST
from services.blacklist_service import BlacklistUserService
from services.config_service import GuildConfig
from services.xp_service import XpRewardService, XpService
_strings = JsonCache.read_json("strings")
_messages = JsonCache.read_json("levels")
class XPHandler:
def __init__(self, client: LumiBot, message: discord.Message) -> None:
@ -199,7 +196,7 @@ class XPHandler:
Returns:
str: The generic level up message.
"""
return _strings["level_up"].format(author.name, level)
return CONST.STRINGS["level_up"].format(author.name, level)
@staticmethod
def messages_whimsical(level: int, author: discord.Member) -> str:
@ -214,7 +211,7 @@ class XPHandler:
str: The whimsical level up message.
"""
level_range: Optional[str] = None
for key in _messages.keys():
for key in CONST.LEVEL_MESSAGES.keys():
start, end = map(int, key.split("-"))
if start <= level <= end:
level_range = key
@ -224,9 +221,9 @@ class XPHandler:
# Generic fallback
return XPHandler.level_message_generic(level, author)
message_list = _messages[level_range]
message_list = CONST.LEVEL_MESSAGES[level_range]
random_message = random.choice(message_list)
start_string = _strings["level_up_prefix"].format(author.name)
start_string = CONST.STRINGS["level_up_prefix"].format(author.name)
return start_string + random_message.format(level)

View file

@ -3,11 +3,13 @@ from typing import Optional, Set
from config.parser import JsonCache
art = JsonCache.read_json("art")
resources = JsonCache.read_json("resources")
class Constants:
# JSON raw
ART = JsonCache.read_json("art")
RESOURCES = JsonCache.read_json("resources")
LEVEL_MESSAGES = JsonCache.read_json("levels")
# metadata
TITLE = "Luminara"
AUTHOR = "wlinator"
@ -57,35 +59,40 @@ class Constants:
# KRC
KRC_GUILD_ID: int = 719227135151046699
KRC_INTRO_CHANNEL_ID: int = 973619250507972618
KRC_QUESTION_MAPPING: dict[str, str] = resources["guild_specific"][
KRC_QUESTION_MAPPING: dict[str, str] = RESOURCES["guild_specific"][
"question_mapping"
]
# logo
LUMI_LOGO_TRANSPARENT = art["logo"]["transparent"]
LUMI_LOGO_OPAQUE = art["logo"]["opaque"]
LUMI_LOGO_TRANSPARENT = ART["logo"]["transparent"]
LUMI_LOGO_OPAQUE = ART["logo"]["opaque"]
# icons art
BOOST_ICON = art["icons"]["boost"]
CHECK_ICON = art["icons"]["check"]
CROSS_ICON = art["icons"]["cross"]
EXCLAIM_ICON = art["icons"]["exclaim"]
HAMMER_ICON = art["icons"]["hammer"]
MONEY_BAG_ICON = art["icons"]["money_bag"]
MONEY_COINS_ICON = art["icons"]["money_coins"]
QUESTION_ICON = art["icons"]["question"]
STREAK_ICON = art["icons"]["streak"]
WARNING_ICON = art["icons"]["warning"]
BOOST_ICON = ART["icons"]["boost"]
CHECK_ICON = ART["icons"]["check"]
CROSS_ICON = ART["icons"]["cross"]
EXCLAIM_ICON = ART["icons"]["exclaim"]
HAMMER_ICON = ART["icons"]["hammer"]
MONEY_BAG_ICON = ART["icons"]["money_bag"]
MONEY_COINS_ICON = ART["icons"]["money_coins"]
QUESTION_ICON = ART["icons"]["question"]
STREAK_ICON = ART["icons"]["streak"]
WARNING_ICON = ART["icons"]["warning"]
# art by JuicyBblue
FLOWERS_ART = art["juicybblue"]["flowers"]
TEAPOT_ART = art["juicybblue"]["teapot"]
MUFFIN_ART = art["juicybblue"]["muffin"]
FLOWERS_ART = ART["juicybblue"]["flowers"]
TEAPOT_ART = ART["juicybblue"]["teapot"]
MUFFIN_ART = ART["juicybblue"]["muffin"]
# birthdays
BIRTHDAY_MESSAGES = JsonCache.read_json("birthday")["birthday_messages"]
BIRTHDAY_MONTHS = JsonCache.read_json("birthday")["months"]
BIRTHDAY_GIF_URL = "https://media1.tenor.com/m/NXvU9jbBUGMAAAAC/fireworks.gif"
# economy
DAILY_REWARD = RESOURCES["daily_reward"]
SLOTS = RESOURCES["slots"]
BLACKJACK = RESOURCES["blackjack"]
CONST = Constants()

View file

@ -1,13 +1,6 @@
import discord
from config.parser import JsonCache
from lib import formatter
resources = JsonCache.read_json("art")
question_icon = resources["icons"]["question"]
exclaim_icon = resources["icons"]["exclaim"]
class Greet:
@staticmethod
@ -16,10 +9,11 @@ class Greet:
color=discord.Color.embed_background(),
description=f"_ _\n**Welcome** to **{member.guild.name}**",
)
if template:
embed.description += "↓↓↓\n" + formatter.template(template, member.name)
embed.description = (
f"{embed.description}\n↓↓↓\n{formatter.template(template, member.name)}"
)
embed.set_thumbnail(url=member.display_avatar)
embed.set_thumbnail(url=member.display_avatar.url)
return embed

View file

@ -1,77 +0,0 @@
import discord
from config.parser import JsonCache
from lib import formatter
resources = JsonCache.read_json("art")
question_icon = resources["icons"]["question"]
exclaim_icon = resources["icons"]["exclaim"]
streak_icon = resources["icons"]["streak"]
def clean_info_embed(ctx):
embed = discord.Embed(
color=discord.Color.blurple(),
description=f"**{ctx.author.name}** ",
)
return embed
class MiscInfo:
@staticmethod
def ping(ctx, client):
embed = clean_info_embed(ctx)
embed.description += "I'm online!"
embed.set_footer(
text=f"Latency: {round(1000 * client.latency)}ms",
icon_url=exclaim_icon,
)
return embed
@staticmethod
def uptime(ctx, client, unix_time):
embed = clean_info_embed(ctx)
embed.description += f"I've been online since <t:{unix_time}:R>"
embed.set_footer(
text=f"Latency: {round(1000 * client.latency)}ms",
icon_url=exclaim_icon,
)
return embed
@staticmethod
def set_prefix(ctx, prefix):
embed = clean_info_embed(ctx)
embed.description += f"my prefix changed to `{prefix}`"
return embed
@staticmethod
def get_prefix(ctx, prefix):
embed = clean_info_embed(ctx)
embed.description += f"my prefix is `{prefix}`"
embed.set_footer(
text=f"You can change this with '{formatter.get_prefix(ctx)}setprefix'",
icon_url=question_icon,
)
return embed
class BdayInfo:
@staticmethod
def set_month(ctx, month, day):
embed = clean_info_embed(ctx)
embed.description += f"your birthday was set to {month} {day}."
return embed
@staticmethod
def delete(ctx):
embed = clean_info_embed(ctx)
embed.description += "your birthday was deleted from this server."
return embed

View file

@ -1,18 +1,10 @@
import datetime
from typing import Optional
from lib.constants import CONST
import discord
from config.parser import JsonCache
from lib import formatter
resources = JsonCache.read_json("art")
check_icon = resources["icons"]["check"]
cross_icon = resources["icons"]["cross"]
exclaim_icon = resources["icons"]["exclaim"]
logo = resources["logo"]["transparent"]
def create_embed(
title: str,
@ -25,8 +17,8 @@ def create_embed(
description=description,
)
embed.set_author(name=title, icon_url=icon_url)
embed.set_footer(text="Reaction Service", icon_url=logo)
embed.timestamp = datetime.datetime.utcnow()
embed.set_footer(text="Reaction Service", icon_url=CONST.LUMI_LOGO_TRANSPARENT)
embed.timestamp = datetime.datetime.now(datetime.timezone.utc)
return embed
@ -47,7 +39,12 @@ def create_creation_embed(
f"{f'**Emoji ID:** `{str(emoji_id)}`' if is_emoji else f'**Response:** `{response}`'}\n"
f"**Full Match:** `{is_full_match}`"
)
return create_embed("Custom Reaction Created", description, 0xFF8C00, check_icon)
return create_embed(
"Custom Reaction Created",
description,
0xFF8C00,
CONST.CHECK_ICON,
)
def create_failure_embed(
@ -71,7 +68,7 @@ def create_failure_embed(
"Custom Reaction Creation Failed",
description,
0xFF4500,
cross_icon,
CONST.CROSS_ICON,
)
@ -81,14 +78,24 @@ def create_deletion_embed(trigger_text: str, is_emoji: bool) -> discord.Embed:
description = f"**Trigger Text:** `{trigger_text}`\n"
description += "Custom reaction has been successfully deleted."
return create_embed("Custom Reaction Deleted", description, 0xFF8C00, check_icon)
return create_embed(
"Custom Reaction Deleted",
description,
0xFF8C00,
CONST.CHECK_ICON,
)
def create_not_found_embed(reaction_id: int) -> discord.Embed:
description = f"**Reaction ID:** `{reaction_id}`\n"
description += "No custom reaction found with the provided ID."
return create_embed("Custom Reaction Not Found", description, 0xFF4500, cross_icon)
return create_embed(
"Custom Reaction Not Found",
description,
0xFF4500,
CONST.CROSS_ICON,
)
def create_no_triggers_embed() -> discord.Embed:
@ -107,5 +114,5 @@ def create_no_triggers_embed() -> discord.Embed:
"No Custom Reactions Found",
description,
0xFF8C00,
exclaim_icon,
CONST.EXCLAIM_ICON,
)

View file

@ -1,6 +1,5 @@
import discord
from discord.ext.commands import guild_only
from config.parser import JsonCache
from discord.commands import SlashCommandGroup
from discord.ext import bridge, commands
from modules.config import (
@ -14,8 +13,6 @@ from modules.config import (
xp_reward,
)
strings = JsonCache.read_json("strings")
class Config(commands.Cog):
def __init__(self, client):

View file

@ -1,9 +1,7 @@
import discord
from config.parser import JsonCache
from services.xp_service import XpRewardService
art = JsonCache.read_json("art")
from lib.constants import CONST
async def show(ctx):
@ -14,18 +12,20 @@ async def show(ctx):
description="",
)
icon = ctx.guild.icon if ctx.guild.icon else art["logo"]["opaque"]
icon = ctx.guild.icon or CONST.LUMI_LOGO_OPAQUE
embed.set_author(name="Level Rewards", icon_url=icon)
for level in sorted(level_reward.rewards.keys()):
role_id, persistent = level_reward.rewards.get(level)
role_id, persistent = level_reward.rewards[level]
role = ctx.guild.get_role(role_id)
if embed.description is None:
embed.description = ""
embed.description += (
f"\n**Level {level}** -> {role.mention if role else 'Role not found'}"
)
if bool(persistent):
if persistent:
embed.description += " (persistent)"
await ctx.respond(embed=embed)

View file

@ -6,13 +6,12 @@ import pytz
from discord.ext import commands
from loguru import logger
from config.parser import JsonCache
from lib import interaction
from lib.embeds.error import EconErrors
from services.currency_service import Currency
from services.stats_service import BlackJackStats
from lib.constants import CONST
resources = JsonCache.read_json("resources")
est = pytz.timezone("US/Eastern")
active_blackjack_games = {}
@ -47,16 +46,11 @@ async def cmd(ctx, bet: int):
active_blackjack_games[ctx.author.id] = True
try:
player_hand = []
dealer_hand = []
deck = get_new_deck()
multiplier = float(resources["blackjack"]["reward_multiplier"])
# deal initial cards (player draws two & dealer one)
player_hand.append(deal_card(deck))
player_hand.append(deal_card(deck))
dealer_hand.append(deal_card(deck))
multiplier = float(CONST.BLACKJACK["reward_multiplier"])
player_hand = [deal_card(deck), deal_card(deck)]
dealer_hand = [deal_card(deck)]
# calculate initial hands
player_hand_value = calculate_hand_value(player_hand)
dealer_hand_value = calculate_hand_value(dealer_hand)
@ -102,13 +96,8 @@ async def cmd(ctx, bet: int):
dealer_hand.append(deal_card(deck))
dealer_hand_value = calculate_hand_value(dealer_hand)
if dealer_hand_value > 21:
status = 3
break
else:
status = 4
break
status = 3 if dealer_hand_value > 21 else 4
break
else:
status = 6
break
@ -129,8 +118,8 @@ async def cmd(ctx, bet: int):
"""
At this point the game has concluded, generate a final output & backend
"""
payout = bet * multiplier if not status == 5 else bet * 2
is_won = False if status == 1 or status == 4 else True
payout = bet * 2 if status == 5 else bet * multiplier
is_won = status not in [1, 4]
embed = blackjack_finished(
ctx,
@ -204,8 +193,6 @@ def blackjack_show(
dealer_hand_value,
):
current_time = datetime.now(est).strftime("%I:%M %p")
thumbnail_url = None
embed = discord.Embed(
title="BlackJack",
color=discord.Color.dark_orange(),
@ -235,7 +222,7 @@ def blackjack_show(
icon_url="https://i.imgur.com/96jPPXO.png",
)
if thumbnail_url:
if thumbnail_url := None:
embed.set_thumbnail(url=thumbnail_url)
return embed
@ -306,8 +293,8 @@ def blackjack_finished(ctx, bet, player_hand_value, dealer_hand_value, payout, s
def get_new_deck():
suits = resources["blackjack"]["deck_suits"]
ranks = resources["blackjack"]["deck_ranks"]
suits = CONST.BLACKJACK["deck_suits"]
ranks = CONST.BLACKJACK["deck_ranks"]
deck = []
for suit in suits:
for rank in ranks:

View file

@ -7,11 +7,11 @@ import discord
import pytz
from discord.ext import commands
from config.parser import JsonCache
from services.currency_service import Currency
from services.stats_service import SlotsStats
resources = JsonCache.read_json("resources")
from lib.constants import CONST
est = pytz.timezone("US/Eastern")
@ -36,12 +36,8 @@ async def cmd(self, ctx, bet):
results = [random.randint(0, 6) for _ in range(3)]
calculated_results = calculate_slots_results(bet, results)
(type, payout, multiplier) = calculated_results
is_won = True
if type == "lost":
is_won = False
(result_type, payout, multiplier) = calculated_results
is_won = result_type != "lost"
# only get the emojis once
emojis = get_emotes(self.client)
@ -60,7 +56,7 @@ async def cmd(self, ctx, bet):
# output final result
finished_output = slots_finished(
ctx,
type,
result_type,
Currency.format_human(bet),
Currency.format_human(payout),
results,
@ -80,7 +76,7 @@ async def cmd(self, ctx, bet):
is_won=is_won,
bet=bet,
payout=payout,
spin_type=type,
spin_type=result_type,
icons=results,
)
@ -89,45 +85,38 @@ async def cmd(self, ctx, bet):
def get_emotes(client):
decoration = resources["slots"]["emotes"]
emojis = {name: client.get_emoji(emoji_id) for name, emoji_id in decoration.items()}
return emojis
decoration = CONST.SLOTS["emotes"]
return {name: client.get_emoji(emoji_id) for name, emoji_id in decoration.items()}
def calculate_slots_results(bet, results):
type = None
result_type = None
multiplier = None
rewards = resources["slots"]["reward_multipliers"]
rewards = CONST.SLOTS["reward_multipliers"]
# count occurrences of each item in the list
counts = Counter(results)
# no icons match
if len(counts) == 3:
type = "lost"
result_type = "lost"
multiplier = 0
# pairs
elif len(counts) == 2:
type = "pair"
multiplier = rewards[type]
result_type = "pair"
multiplier = rewards[result_type]
# 3 of a kind
elif len(counts) == 1:
if results[0] == 5:
type = "three_diamonds"
multiplier = rewards[type]
result_type = "three_diamonds"
elif results[0] == 6:
type = "jackpot"
multiplier = rewards[type]
result_type = "jackpot"
else:
type = "three_of_a_kind"
multiplier = rewards[type]
result_type = "three_of_a_kind"
multiplier = rewards[result_type]
payout = bet * multiplier
return type, int(payout), multiplier
return result_type, int(payout), multiplier
def slots_spinning(ctx, spinning_icons_amount, bet, results, emojis):

View file

@ -1,54 +0,0 @@
from config.parser import JsonCache
from services.currency_service import Currency
from services.stats_service import BlackJackStats, SlotsStats
strings = JsonCache.read_json("strings")
resources = JsonCache.read_json("resources")
async def cmd(self, ctx, game):
output = ""
if game == "BlackJack":
stats = BlackJackStats.get_user_stats(ctx.author.id)
# amount formatting
total_bet = Currency.format_human(stats["total_bet"])
total_payout = Currency.format_human(stats["total_payout"])
# output = f"{ctx.author.name}'s lumi stats\n\n"
output = strings["stats_blackjack"].format(
stats["amount_of_games"],
total_bet,
stats["winning_amount"],
total_payout,
)
elif game == "Slots":
stats = SlotsStats.get_user_stats(ctx.author.id)
# amount formatting
total_bet = Currency.format_human(stats["total_bet"])
total_payout = Currency.format_human(stats["total_payout"])
output = strings["stats_slots"].format(
stats["amount_of_games"],
total_bet,
total_payout,
)
output += "\n\n"
pair_emote = self.client.get_emoji(resources["slots"]["emotes"]["slots_0_id"])
three_emote = self.client.get_emoji(resources["slots"]["emotes"]["slots_4_id"])
diamonds_emote = self.client.get_emoji(
resources["slots"]["emotes"]["slots_5_id"],
)
seven_emote = self.client.get_emoji(resources["slots"]["emotes"]["slots_6_id"])
output += f"{pair_emote} | **{stats['games_won_pair']}** pairs.\n"
output += f"{three_emote} | **{stats['games_won_three_of_a_kind']}** three-of-a-kinds.\n"
output += f"{diamonds_emote} | **{stats['games_won_three_diamonds']}** triple diamonds.\n"
output += f"{seven_emote} | **{stats['games_won_jackpot']}** jackpots."
output += "\n\n *This command is still in beta, stats may be slightly inaccurate.*"
await ctx.respond(content=output)

View file

@ -17,7 +17,6 @@ class Levels(commands.Cog):
contexts={discord.InteractionContextType.guild},
)
@guild_only()
@commands.cooldown(1, 30, commands.BucketType.user)
async def level_command(self, ctx) -> None:
await level.rank(ctx)
@ -29,7 +28,6 @@ class Levels(commands.Cog):
contexts={discord.InteractionContextType.guild},
)
@guild_only()
@commands.cooldown(1, 180, commands.BucketType.user)
async def leaderboard_command(self, ctx) -> None:
await leaderboard.cmd(ctx)

View file

@ -2,16 +2,10 @@ import datetime
import discord
from discord.ext import bridge, pages
from config.parser import JsonCache
from lib.constants import CONST
from lib.embeds.triggers import create_no_triggers_embed
from services.reactions_service import CustomReactionsService
resources = JsonCache.read_json("art")
check_icon = resources["icons"]["check"]
logo = resources["logo"]["transparent"]
async def list_reactions(ctx: bridge.Context) -> None:
if ctx.guild is None:
@ -30,21 +24,15 @@ async def list_reactions(ctx: bridge.Context) -> None:
# Create pages for pagination
pages_list = []
for reaction in reactions:
description = (
f"**Trigger Text:** `{reaction['trigger_text']}`\n"
f"**Reaction Type:** {'Emoji' if reaction['is_emoji'] else 'Text'}\n"
f"{'**Emoji ID:** `{}`'.format(str(reaction['emoji_id'])) if reaction['is_emoji'] else '**Response:** `{}`'.format(reaction['response'])}\n"
f"**Full Match:** `{'True' if reaction['is_full_match'] else 'False'}`\n"
f"**Usage Count:** `{reaction['usage_count']}`"
)
description = f"""**Trigger Text:** `{reaction['trigger_text']}`\n**Reaction Type:** {'Emoji' if reaction['is_emoji'] else 'Text'}\n{f"**Emoji ID:** `{str(reaction['emoji_id'])}`" if reaction['is_emoji'] else f"**Response:** `{reaction['response']}`"}\n**Full Match:** `{'True' if reaction['is_full_match'] else 'False'}`\n**Usage Count:** `{reaction['usage_count']}`"""
embed = discord.Embed(
title=f"ID: {reaction['id']}",
description=description,
color=0xFF8C00,
)
embed.set_author(name="Custom Reactions", icon_url=check_icon)
embed.set_footer(text="Reaction Service", icon_url=logo)
embed.timestamp = datetime.datetime.utcnow()
embed.set_author(name="Custom Reactions", icon_url=CONST.CHECK_ICON)
embed.set_footer(text="Reaction Service", icon_url=CONST.LUMI_LOGO_TRANSPARENT)
embed.timestamp = datetime.datetime.now(datetime.timezone.utc)
pages_list.append(embed)
paginator = pages.Paginator(pages=pages_list, timeout=180.0)

View file

@ -2,13 +2,10 @@ from datetime import datetime, timedelta
from typing import List, Optional, Tuple
import pytz
from config.parser import JsonCache
from db import database
from lib.constants import CONST
from services.currency_service import Currency
resources = JsonCache.read_json("resources")
class Dailies:
def __init__(self, user_id: int) -> None:
@ -35,8 +32,7 @@ class Dailies:
def refresh(self) -> None:
if self.amount == 0:
self.amount = resources["daily_reward"]
self.amount = CONST.DAILY_REWARD
query: str = """
INSERT INTO dailies (user_id, amount, claimed_at, streak)
VALUES (%s, %s, %s, %s)
@ -57,14 +53,10 @@ class Dailies:
if self.claimed_at is None:
return True
else:
if self.time_now < self.reset_time:
self.reset_time -= timedelta(days=1)
if self.time_now < self.reset_time:
self.reset_time -= timedelta(days=1)
if self.claimed_at < self.reset_time <= self.time_now:
return True
return False
return self.claimed_at < self.reset_time <= self.time_now
def streak_check(self) -> bool:
"""
@ -118,13 +110,7 @@ class Dailies:
data: List[Tuple[int, int, str]] = database.select_query(query)
leaderboard: List[Tuple[int, int, str, int]] = []
rank: int = 1
for row in data:
row_user_id: int = row[0]
streak: int = row[1]
claimed_at: str = row[2]
leaderboard.append((row_user_id, streak, claimed_at, rank))
rank += 1
leaderboard: List[Tuple[int, int, str, int]] = [
(row[0], row[1], row[2], rank) for rank, row in enumerate(data, start=1)
]
return leaderboard