Skip to content

Commit

Permalink
Fix: v0.10.2
Browse files Browse the repository at this point in the history
This release fixes the marketplace and other bugs. For more info, please check out the changelog ~ Noelle
  • Loading branch information
No767 authored Aug 1, 2023
2 parents 563e4c7 + 2ee8250 commit 3b36529
Show file tree
Hide file tree
Showing 22 changed files with 422 additions and 320 deletions.
200 changes: 100 additions & 100 deletions Bot/Cogs/dev-tools.py
Original file line number Diff line number Diff line change
@@ -1,100 +1,100 @@
from typing import Literal, Optional

import discord
from discord import app_commands
from discord.ext import commands
from discord.ext.commands import Context, Greedy
from kumikocore import KumikoCore


def is_nat():
def pred(ctx):
return (
ctx.guild is not None and ctx.author.id == 1028431063321686036
) # natalie's account

return commands.check(pred)


class DevTools(commands.Cog, command_attrs=dict(hidden=True)):
"""Tools for developing Kumiko"""

def __init__(self, bot: KumikoCore):
self.bot = bot

@property
def display_emoji(self) -> discord.PartialEmoji:
return discord.PartialEmoji(name="\U0001f6e0")

@commands.hybrid_command(name="sync")
@commands.guild_only()
@commands.check_any(commands.is_owner(), is_nat())
async def sync(
self,
ctx: Context,
guilds: Greedy[discord.Object],
spec: Optional[Literal["~", "*", "^"]] = None,
) -> None:
"""Performs a sync of the tree. This will sync, copy globally, or clear the tree.
Args:
ctx (Context): Context of the command
guilds (Greedy[discord.Object]): Which guilds to sync to. Greedily accepts a number of guilds
spec (Optional[Literal["~", "*", "^"], optional): Specs to sync.
"""
await ctx.defer()
if not guilds:
if spec == "~":
synced = await self.bot.tree.sync(guild=ctx.guild)
elif spec == "*":
self.bot.tree.copy_global_to(guild=ctx.guild) # type: ignore
synced = await self.bot.tree.sync(guild=ctx.guild)
elif spec == "^":
self.bot.tree.clear_commands(guild=ctx.guild)
await self.bot.tree.sync(guild=ctx.guild)
synced = []
else:
synced = await self.bot.tree.sync()

await ctx.send(
f"Synced {len(synced)} commands {'globally' if spec is None else 'to the current guild.'}"
)
return

ret = 0
for guild in guilds:
try:
await self.bot.tree.sync(guild=guild)
except discord.HTTPException:
pass
else:
ret += 1

await ctx.send(f"Synced the tree to {ret}/{len(guilds)}.")

@commands.hybrid_command(name="dispatch")
@commands.guild_only()
@commands.check_any(commands.is_owner(), is_nat())
@app_commands.describe(event="The event to dispatch")
async def dispatch_event(self, ctx: commands.Context, event: str) -> None:
"""Dispatches an custom event
Args:
ctx (commands.Context): _description_
"""
self.bot.dispatch(event, ctx.guild, ctx.author)
await ctx.send("Dispatched event")

@commands.check_any(commands.is_owner(), is_nat())
@commands.command(name="arg-check", usage="<user: discord.Member>")
async def arg_check(self, ctx: commands.Context, user: discord.Member):
"""Testing arg checks
Args:
user (discord.Member): The member to ping lol
"""
await ctx.send(user.name)


async def setup(bot: KumikoCore):
await bot.add_cog(DevTools(bot))
from typing import Literal, Optional

import discord
from discord import app_commands
from discord.ext import commands
from discord.ext.commands import Context, Greedy
from kumikocore import KumikoCore


def is_nat():
def pred(ctx):
return (
ctx.guild is not None and ctx.author.id == 1028431063321686036
) # natalie's account

return commands.check(pred)


class DevTools(commands.Cog, command_attrs=dict(hidden=True)):
"""Tools for developing Kumiko"""

def __init__(self, bot: KumikoCore):
self.bot = bot

@property
def display_emoji(self) -> discord.PartialEmoji:
return discord.PartialEmoji(name="\U0001f6e0")

@commands.hybrid_command(name="sync")
@commands.guild_only()
@commands.check_any(commands.is_owner(), is_nat())
async def sync(
self,
ctx: Context,
guilds: Greedy[discord.Object],
spec: Optional[Literal["~", "*", "^"]] = None,
) -> None:
"""Performs a sync of the tree. This will sync, copy globally, or clear the tree.
Args:
ctx (Context): Context of the command
guilds (Greedy[discord.Object]): Which guilds to sync to. Greedily accepts a number of guilds
spec (Optional[Literal["~", "*", "^"], optional): Specs to sync.
"""
await ctx.defer()
if not guilds:
if spec == "~":
synced = await self.bot.tree.sync(guild=ctx.guild)
elif spec == "*":
self.bot.tree.copy_global_to(guild=ctx.guild) # type: ignore
synced = await self.bot.tree.sync(guild=ctx.guild)
elif spec == "^":
self.bot.tree.clear_commands(guild=ctx.guild)
await self.bot.tree.sync(guild=ctx.guild)
synced = []
else:
synced = await self.bot.tree.sync()

await ctx.send(
f"Synced {len(synced)} commands {'globally' if spec is None else 'to the current guild.'}"
)
return

ret = 0
for guild in guilds:
try:
await self.bot.tree.sync(guild=guild)
except discord.HTTPException:
pass
else:
ret += 1

await ctx.send(f"Synced the tree to {ret}/{len(guilds)}.")

@commands.hybrid_command(name="dispatch")
@commands.guild_only()
@commands.check_any(commands.is_owner(), is_nat())
@app_commands.describe(event="The event to dispatch")
async def dispatch_event(self, ctx: commands.Context, event: str) -> None:
"""Dispatches an custom event
Args:
ctx (commands.Context): _description_
"""
self.bot.dispatch(event, ctx.guild)
await ctx.send("Dispatched event")

@commands.check_any(commands.is_owner(), is_nat())
@commands.command(name="arg-check", usage="<user: discord.Member>")
async def arg_check(self, ctx: commands.Context, user: discord.Member):
"""Testing arg checks
Args:
user (discord.Member): The member to ping lol
"""
await ctx.send(user.name)


async def setup(bot: KumikoCore):
await bot.add_cog(DevTools(bot))
6 changes: 3 additions & 3 deletions Bot/Cogs/economy.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ async def inventory(self, ctx: commands.Context) -> None:
"""View your inventory"""
query = """
SELECT eco_item.id, eco_item.name, eco_item.description, eco_item.price, eco_item.amount, eco_item.producer_id
FROM eco_item_lookup
INNER JOIN eco_item ON eco_item.id = eco_item_lookup.item_id
WHERE eco_item.guild_id = $1 AND eco_item.owner_id = $2;
FROM user_inv
INNER JOIN eco_item ON eco_item.id = user_inv.item_id
WHERE eco_item.guild_id = $1 AND user_inv.owner_id = $2;
"""
rows = await self.pool.fetch(query, ctx.guild.id, ctx.author.id) # type: ignore
if len(rows) == 0:
Expand Down
3 changes: 2 additions & 1 deletion Bot/Cogs/events-handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,11 @@ async def on_guild_remove(self, guild: discord.Guild) -> None:
async with self.pool.acquire() as conn:
async with conn.transaction():
await conn.execute("DELETE FROM guild WHERE id = $1", guild.id)
del self.bot.prefixes[guild.id]
await cache.deleteJSONCache(
key=f"cache:kumiko:{guild.id}:guild_config", path="$"
)
if guild.id in self.bot.prefixes:
del self.bot.prefixes[guild.id]

@commands.Cog.listener()
async def on_member_join(self, member: discord.Member) -> None:
Expand Down
3 changes: 2 additions & 1 deletion Bot/Cogs/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ def check(msg):
query = """
SELECT eco_item_lookup.item_id, job_lookup.job_id
FROM eco_item_lookup
INNER JOIN job_lookup ON eco_item_lookup.producer_id = job_lookup.worker_id
INNER JOIN job_lookup ON eco_item_lookup.producer_id = job_lookup.creator_id
WHERE eco_item_lookup.guild_id=$1 AND LOWER(eco_item_lookup.name)=$2 AND eco_item_lookup.producer_id=$3;
"""
status = await createJobOutputItem(
Expand All @@ -483,6 +483,7 @@ def check(msg):
if status[-1] != "0":
rows = await conn.fetchrow(query, ctx.guild.id, name, ctx.author.id) # type: ignore
if rows is None:
# this is bugged for some odd reason
await ctx.send("You aren't the producer of the item!")
return
record = dict(rows)
Expand Down
44 changes: 36 additions & 8 deletions Bot/Cogs/marketplace.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ async def marketplace(self, ctx: commands.Context) -> None:
SELECT eco_item.id, eco_item.name, eco_item.description, eco_item.price, eco_item.amount, eco_item.producer_id
FROM eco_item_lookup
INNER JOIN eco_item ON eco_item.id = eco_item_lookup.item_id
WHERE eco_item.guild_id = $1 AND eco_item.owner_id IS NULL;
WHERE eco_item.guild_id = $1;
"""
rows = await self.pool.fetch(query, ctx.guild.id) # type: ignore
if len(rows) == 0:
Expand All @@ -52,22 +52,28 @@ async def buy(
flags: PurchaseFlags,
) -> None:
"""Buy an item from the marketplace"""
# I have committed several sins
query = """
SELECT eco_item.id, eco_item.price, eco_item.amount, eco_item.producer_id
FROM eco_item_lookup
INNER JOIN eco_item ON eco_item.id = eco_item_lookup.item_id
WHERE eco_item_lookup.guild_id=$1 AND LOWER(eco_item_lookup.name)=$2 AND eco_item_lookup.owner_id IS NULL;
WHERE eco_item_lookup.guild_id=$1 AND LOWER(eco_item_lookup.name)=$2;
"""
setOwnerQuery = """
purchaseItem = """
WITH item_update AS (
UPDATE eco_item
SET owner_id = $2, amount = $4
SET amount = $4
WHERE guild_id = $1 AND name = $3
RETURNING id
)
UPDATE eco_item_lookup
SET owner_id = $2
WHERE id = (SELECT id FROM item_update);
INSERT INTO user_inv (owner_id, guild_id, amount_owned, item_id)
VALUES ($2, $1, $5, (SELECT id FROM item_update));
"""
fetchCreatedItem = """
SELECT eco_item.id, user_inv.owner_id
FROM user_inv
INNER JOIN eco_item ON eco_item.id = user_inv.item_id
WHERE user_inv.owner_id = $1 AND user_inv.guild_id = $2 AND LOWER(eco_item.name) = $3;
"""
updateBalanceQuery = """
UPDATE eco_user
Expand All @@ -79,6 +85,10 @@ async def buy(
SET petals = petals - $2
WHERE id = $1;
"""
createLinkUpdate = """
INSERT INTO user_item_relations (item_id, user_id)
VALUES ($1, $2);
"""
async with self.pool.acquire() as conn:
rows = await conn.fetchrow(query, ctx.guild.id, name.lower()) # type: ignore
if rows is None:
Expand All @@ -95,13 +105,31 @@ async def buy(
totalPrice = records["price"] * flags.amount
if await isPaymentValid(records, ctx.author.id, flags.amount, conn) is True:
async with conn.transaction():
await conn.execute(setOwnerQuery, ctx.guild.id, ctx.author.id, name.lower(), records["amount"] - flags.amount) # type: ignore
await conn.execute(
updateBalanceQuery,
records["producer_id"],
totalPrice,
)
await conn.execute(updatePurchaserQuery, ctx.author.id, totalPrice)
status = await conn.execute(purchaseItem, ctx.guild.id, ctx.author.id, name.lower(), records["amount"] - flags.amount, flags.amount) # type: ignore
if status[-1] != "0":
createdRows = await conn.fetchrow(fetchCreatedItem, ctx.author.id, ctx.guild.id, name.lower()) # type: ignore
if createdRows is None:
await ctx.send(
"No items fetched. This is a bug in the system"
)
return
createdRecords = dict(createdRows)
await conn.execute(
createLinkUpdate,
createdRecords["id"],
createdRecords["owner_id"],
)
else:
await ctx.send(
"Something went wrong with the purchase. This is usually due to the fact that there are extras. Please try again"
)
return
await ctx.send(f"Purchased item `{name}` for `{totalPrice}`")
else:
await ctx.send(
Expand Down
2 changes: 1 addition & 1 deletion Bot/Cogs/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from Libs.utils import Embed
from psutil._common import bytes2human

VERSION = "v0.10.0"
VERSION = "v0.10.2"


class Meta(commands.Cog):
Expand Down
4 changes: 4 additions & 0 deletions Bot/Cogs/prefix.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ async def addPrefixes(self, ctx: commands.Context, prefix: PrefixConverter) -> N
desc = "There was an validation issue. This is because of two reasons:\n- You have more than 10 prefixes for your server\n- Your prefix fails the validation rules"
raise ValidationError(desc)

if prefix in self.bot.prefixes[ctx.guild.id]: # type: ignore
await ctx.send("The prefix you want to set already exists")
return

query = """
UPDATE guild
SET prefix = ARRAY_APPEND(prefix, $1)
Expand Down
Loading

0 comments on commit 3b36529

Please sign in to comment.