Skip to content

Commit 3b36529

Browse files
authored
Fix: v0.10.2
This release fixes the marketplace and other bugs. For more info, please check out the changelog ~ Noelle
2 parents 563e4c7 + 2ee8250 commit 3b36529

22 files changed

+422
-320
lines changed

Bot/Cogs/dev-tools.py

Lines changed: 100 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,100 @@
1-
from typing import Literal, Optional
2-
3-
import discord
4-
from discord import app_commands
5-
from discord.ext import commands
6-
from discord.ext.commands import Context, Greedy
7-
from kumikocore import KumikoCore
8-
9-
10-
def is_nat():
11-
def pred(ctx):
12-
return (
13-
ctx.guild is not None and ctx.author.id == 1028431063321686036
14-
) # natalie's account
15-
16-
return commands.check(pred)
17-
18-
19-
class DevTools(commands.Cog, command_attrs=dict(hidden=True)):
20-
"""Tools for developing Kumiko"""
21-
22-
def __init__(self, bot: KumikoCore):
23-
self.bot = bot
24-
25-
@property
26-
def display_emoji(self) -> discord.PartialEmoji:
27-
return discord.PartialEmoji(name="\U0001f6e0")
28-
29-
@commands.hybrid_command(name="sync")
30-
@commands.guild_only()
31-
@commands.check_any(commands.is_owner(), is_nat())
32-
async def sync(
33-
self,
34-
ctx: Context,
35-
guilds: Greedy[discord.Object],
36-
spec: Optional[Literal["~", "*", "^"]] = None,
37-
) -> None:
38-
"""Performs a sync of the tree. This will sync, copy globally, or clear the tree.
39-
40-
Args:
41-
ctx (Context): Context of the command
42-
guilds (Greedy[discord.Object]): Which guilds to sync to. Greedily accepts a number of guilds
43-
spec (Optional[Literal["~", "*", "^"], optional): Specs to sync.
44-
"""
45-
await ctx.defer()
46-
if not guilds:
47-
if spec == "~":
48-
synced = await self.bot.tree.sync(guild=ctx.guild)
49-
elif spec == "*":
50-
self.bot.tree.copy_global_to(guild=ctx.guild) # type: ignore
51-
synced = await self.bot.tree.sync(guild=ctx.guild)
52-
elif spec == "^":
53-
self.bot.tree.clear_commands(guild=ctx.guild)
54-
await self.bot.tree.sync(guild=ctx.guild)
55-
synced = []
56-
else:
57-
synced = await self.bot.tree.sync()
58-
59-
await ctx.send(
60-
f"Synced {len(synced)} commands {'globally' if spec is None else 'to the current guild.'}"
61-
)
62-
return
63-
64-
ret = 0
65-
for guild in guilds:
66-
try:
67-
await self.bot.tree.sync(guild=guild)
68-
except discord.HTTPException:
69-
pass
70-
else:
71-
ret += 1
72-
73-
await ctx.send(f"Synced the tree to {ret}/{len(guilds)}.")
74-
75-
@commands.hybrid_command(name="dispatch")
76-
@commands.guild_only()
77-
@commands.check_any(commands.is_owner(), is_nat())
78-
@app_commands.describe(event="The event to dispatch")
79-
async def dispatch_event(self, ctx: commands.Context, event: str) -> None:
80-
"""Dispatches an custom event
81-
82-
Args:
83-
ctx (commands.Context): _description_
84-
"""
85-
self.bot.dispatch(event, ctx.guild, ctx.author)
86-
await ctx.send("Dispatched event")
87-
88-
@commands.check_any(commands.is_owner(), is_nat())
89-
@commands.command(name="arg-check", usage="<user: discord.Member>")
90-
async def arg_check(self, ctx: commands.Context, user: discord.Member):
91-
"""Testing arg checks
92-
93-
Args:
94-
user (discord.Member): The member to ping lol
95-
"""
96-
await ctx.send(user.name)
97-
98-
99-
async def setup(bot: KumikoCore):
100-
await bot.add_cog(DevTools(bot))
1+
from typing import Literal, Optional
2+
3+
import discord
4+
from discord import app_commands
5+
from discord.ext import commands
6+
from discord.ext.commands import Context, Greedy
7+
from kumikocore import KumikoCore
8+
9+
10+
def is_nat():
11+
def pred(ctx):
12+
return (
13+
ctx.guild is not None and ctx.author.id == 1028431063321686036
14+
) # natalie's account
15+
16+
return commands.check(pred)
17+
18+
19+
class DevTools(commands.Cog, command_attrs=dict(hidden=True)):
20+
"""Tools for developing Kumiko"""
21+
22+
def __init__(self, bot: KumikoCore):
23+
self.bot = bot
24+
25+
@property
26+
def display_emoji(self) -> discord.PartialEmoji:
27+
return discord.PartialEmoji(name="\U0001f6e0")
28+
29+
@commands.hybrid_command(name="sync")
30+
@commands.guild_only()
31+
@commands.check_any(commands.is_owner(), is_nat())
32+
async def sync(
33+
self,
34+
ctx: Context,
35+
guilds: Greedy[discord.Object],
36+
spec: Optional[Literal["~", "*", "^"]] = None,
37+
) -> None:
38+
"""Performs a sync of the tree. This will sync, copy globally, or clear the tree.
39+
40+
Args:
41+
ctx (Context): Context of the command
42+
guilds (Greedy[discord.Object]): Which guilds to sync to. Greedily accepts a number of guilds
43+
spec (Optional[Literal["~", "*", "^"], optional): Specs to sync.
44+
"""
45+
await ctx.defer()
46+
if not guilds:
47+
if spec == "~":
48+
synced = await self.bot.tree.sync(guild=ctx.guild)
49+
elif spec == "*":
50+
self.bot.tree.copy_global_to(guild=ctx.guild) # type: ignore
51+
synced = await self.bot.tree.sync(guild=ctx.guild)
52+
elif spec == "^":
53+
self.bot.tree.clear_commands(guild=ctx.guild)
54+
await self.bot.tree.sync(guild=ctx.guild)
55+
synced = []
56+
else:
57+
synced = await self.bot.tree.sync()
58+
59+
await ctx.send(
60+
f"Synced {len(synced)} commands {'globally' if spec is None else 'to the current guild.'}"
61+
)
62+
return
63+
64+
ret = 0
65+
for guild in guilds:
66+
try:
67+
await self.bot.tree.sync(guild=guild)
68+
except discord.HTTPException:
69+
pass
70+
else:
71+
ret += 1
72+
73+
await ctx.send(f"Synced the tree to {ret}/{len(guilds)}.")
74+
75+
@commands.hybrid_command(name="dispatch")
76+
@commands.guild_only()
77+
@commands.check_any(commands.is_owner(), is_nat())
78+
@app_commands.describe(event="The event to dispatch")
79+
async def dispatch_event(self, ctx: commands.Context, event: str) -> None:
80+
"""Dispatches an custom event
81+
82+
Args:
83+
ctx (commands.Context): _description_
84+
"""
85+
self.bot.dispatch(event, ctx.guild)
86+
await ctx.send("Dispatched event")
87+
88+
@commands.check_any(commands.is_owner(), is_nat())
89+
@commands.command(name="arg-check", usage="<user: discord.Member>")
90+
async def arg_check(self, ctx: commands.Context, user: discord.Member):
91+
"""Testing arg checks
92+
93+
Args:
94+
user (discord.Member): The member to ping lol
95+
"""
96+
await ctx.send(user.name)
97+
98+
99+
async def setup(bot: KumikoCore):
100+
await bot.add_cog(DevTools(bot))

Bot/Cogs/economy.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ async def inventory(self, ctx: commands.Context) -> None:
121121
"""View your inventory"""
122122
query = """
123123
SELECT eco_item.id, eco_item.name, eco_item.description, eco_item.price, eco_item.amount, eco_item.producer_id
124-
FROM eco_item_lookup
125-
INNER JOIN eco_item ON eco_item.id = eco_item_lookup.item_id
126-
WHERE eco_item.guild_id = $1 AND eco_item.owner_id = $2;
124+
FROM user_inv
125+
INNER JOIN eco_item ON eco_item.id = user_inv.item_id
126+
WHERE eco_item.guild_id = $1 AND user_inv.owner_id = $2;
127127
"""
128128
rows = await self.pool.fetch(query, ctx.guild.id, ctx.author.id) # type: ignore
129129
if len(rows) == 0:

Bot/Cogs/events-handler.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,11 @@ async def on_guild_remove(self, guild: discord.Guild) -> None:
6565
async with self.pool.acquire() as conn:
6666
async with conn.transaction():
6767
await conn.execute("DELETE FROM guild WHERE id = $1", guild.id)
68-
del self.bot.prefixes[guild.id]
6968
await cache.deleteJSONCache(
7069
key=f"cache:kumiko:{guild.id}:guild_config", path="$"
7170
)
71+
if guild.id in self.bot.prefixes:
72+
del self.bot.prefixes[guild.id]
7273

7374
@commands.Cog.listener()
7475
async def on_member_join(self, member: discord.Member) -> None:

Bot/Cogs/jobs.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ def check(msg):
467467
query = """
468468
SELECT eco_item_lookup.item_id, job_lookup.job_id
469469
FROM eco_item_lookup
470-
INNER JOIN job_lookup ON eco_item_lookup.producer_id = job_lookup.worker_id
470+
INNER JOIN job_lookup ON eco_item_lookup.producer_id = job_lookup.creator_id
471471
WHERE eco_item_lookup.guild_id=$1 AND LOWER(eco_item_lookup.name)=$2 AND eco_item_lookup.producer_id=$3;
472472
"""
473473
status = await createJobOutputItem(
@@ -483,6 +483,7 @@ def check(msg):
483483
if status[-1] != "0":
484484
rows = await conn.fetchrow(query, ctx.guild.id, name, ctx.author.id) # type: ignore
485485
if rows is None:
486+
# this is bugged for some odd reason
486487
await ctx.send("You aren't the producer of the item!")
487488
return
488489
record = dict(rows)

Bot/Cogs/marketplace.py

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ async def marketplace(self, ctx: commands.Context) -> None:
3131
SELECT eco_item.id, eco_item.name, eco_item.description, eco_item.price, eco_item.amount, eco_item.producer_id
3232
FROM eco_item_lookup
3333
INNER JOIN eco_item ON eco_item.id = eco_item_lookup.item_id
34-
WHERE eco_item.guild_id = $1 AND eco_item.owner_id IS NULL;
34+
WHERE eco_item.guild_id = $1;
3535
"""
3636
rows = await self.pool.fetch(query, ctx.guild.id) # type: ignore
3737
if len(rows) == 0:
@@ -52,22 +52,28 @@ async def buy(
5252
flags: PurchaseFlags,
5353
) -> None:
5454
"""Buy an item from the marketplace"""
55+
# I have committed several sins
5556
query = """
5657
SELECT eco_item.id, eco_item.price, eco_item.amount, eco_item.producer_id
5758
FROM eco_item_lookup
5859
INNER JOIN eco_item ON eco_item.id = eco_item_lookup.item_id
59-
WHERE eco_item_lookup.guild_id=$1 AND LOWER(eco_item_lookup.name)=$2 AND eco_item_lookup.owner_id IS NULL;
60+
WHERE eco_item_lookup.guild_id=$1 AND LOWER(eco_item_lookup.name)=$2;
6061
"""
61-
setOwnerQuery = """
62+
purchaseItem = """
6263
WITH item_update AS (
6364
UPDATE eco_item
64-
SET owner_id = $2, amount = $4
65+
SET amount = $4
6566
WHERE guild_id = $1 AND name = $3
6667
RETURNING id
6768
)
68-
UPDATE eco_item_lookup
69-
SET owner_id = $2
70-
WHERE id = (SELECT id FROM item_update);
69+
INSERT INTO user_inv (owner_id, guild_id, amount_owned, item_id)
70+
VALUES ($2, $1, $5, (SELECT id FROM item_update));
71+
"""
72+
fetchCreatedItem = """
73+
SELECT eco_item.id, user_inv.owner_id
74+
FROM user_inv
75+
INNER JOIN eco_item ON eco_item.id = user_inv.item_id
76+
WHERE user_inv.owner_id = $1 AND user_inv.guild_id = $2 AND LOWER(eco_item.name) = $3;
7177
"""
7278
updateBalanceQuery = """
7379
UPDATE eco_user
@@ -79,6 +85,10 @@ async def buy(
7985
SET petals = petals - $2
8086
WHERE id = $1;
8187
"""
88+
createLinkUpdate = """
89+
INSERT INTO user_item_relations (item_id, user_id)
90+
VALUES ($1, $2);
91+
"""
8292
async with self.pool.acquire() as conn:
8393
rows = await conn.fetchrow(query, ctx.guild.id, name.lower()) # type: ignore
8494
if rows is None:
@@ -95,13 +105,31 @@ async def buy(
95105
totalPrice = records["price"] * flags.amount
96106
if await isPaymentValid(records, ctx.author.id, flags.amount, conn) is True:
97107
async with conn.transaction():
98-
await conn.execute(setOwnerQuery, ctx.guild.id, ctx.author.id, name.lower(), records["amount"] - flags.amount) # type: ignore
99108
await conn.execute(
100109
updateBalanceQuery,
101110
records["producer_id"],
102111
totalPrice,
103112
)
104113
await conn.execute(updatePurchaserQuery, ctx.author.id, totalPrice)
114+
status = await conn.execute(purchaseItem, ctx.guild.id, ctx.author.id, name.lower(), records["amount"] - flags.amount, flags.amount) # type: ignore
115+
if status[-1] != "0":
116+
createdRows = await conn.fetchrow(fetchCreatedItem, ctx.author.id, ctx.guild.id, name.lower()) # type: ignore
117+
if createdRows is None:
118+
await ctx.send(
119+
"No items fetched. This is a bug in the system"
120+
)
121+
return
122+
createdRecords = dict(createdRows)
123+
await conn.execute(
124+
createLinkUpdate,
125+
createdRecords["id"],
126+
createdRecords["owner_id"],
127+
)
128+
else:
129+
await ctx.send(
130+
"Something went wrong with the purchase. This is usually due to the fact that there are extras. Please try again"
131+
)
132+
return
105133
await ctx.send(f"Purchased item `{name}` for `{totalPrice}`")
106134
else:
107135
await ctx.send(

Bot/Cogs/meta.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from Libs.utils import Embed
1010
from psutil._common import bytes2human
1111

12-
VERSION = "v0.10.0"
12+
VERSION = "v0.10.2"
1313

1414

1515
class Meta(commands.Cog):

Bot/Cogs/prefix.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ async def addPrefixes(self, ctx: commands.Context, prefix: PrefixConverter) -> N
6565
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"
6666
raise ValidationError(desc)
6767

68+
if prefix in self.bot.prefixes[ctx.guild.id]: # type: ignore
69+
await ctx.send("The prefix you want to set already exists")
70+
return
71+
6872
query = """
6973
UPDATE guild
7074
SET prefix = ARRAY_APPEND(prefix, $1)

0 commit comments

Comments
 (0)