async def check_user(self, ctx: commands.Context): user = GameUser(self.bot.con, str(ctx.author.id)) check_money = self.bot.config["game"]["check_money"] check_time = self.bot.config["game"]["check_time"] unit = self.bot.config["game"]["unit"] if time.time() - user.check_time < check_time: return await ctx.reply( embed=make_text_embed( ctx.author, f"{seconds_to_timestr(check_time - int(time.time() - user.check_time))}후에 다시 출석체크가 가능합니다.", colors.RED, ) ) user.money += check_money user.check_time = time.time() user.commit() return await ctx.reply( embed=make_text_embed( ctx.author, f"출석체크 완료! {format_money(check_money, unit)}을(를) 얻었습니다.\n" f"현재 돈: {format_money(user.money, unit)}\n\n" f"{seconds_to_timestr(check_time)}후에 다시 출석체크가 가능합니다.", colors.GREEN, ) )
async def join_user(self, ctx: commands.Context): if GameUser.exist_user(self.bot.con, str(ctx.author.id)): return await ctx.reply( embed=make_text_embed( ctx.author, f"{ctx.author.name}님은 이미 {self.bot.config['game']['name']} 서비스에 가입하셨습니다.", colors.RED, ) ) user = GameUser.join( self.bot.con, str(ctx.author.id), gift=self.bot.config["game"]["register_money"], ) for i in self.bot.config["game"]["stock"]["stocks"]: user.stock[i] = [] user.commit() await ctx.reply( embed=make_text_embed( ctx.author, f"{ctx.author.name}님은 {self.bot.config['game']['name']} 서비스에 가입하셨습니다.", ) )
async def remove_user(self, ctx: commands.Context): user = GameUser(self.bot.con, str(ctx.author.id)) user.remove() await ctx.reply(embed=make_text_embed( ctx.author, f"{ctx.author.name}님은 {self.bot.config['game']['name']} 서비스에서 탈퇴하셨습니다.", colors.RED, ))
async def info_user(self, ctx: commands.Context, target: discord.User = None): if target: if not GameUser.exist_user(ctx.bot.con, str(target.id)): return await ctx.reply( embed=make_text_embed( ctx.author, f"유저 {target}는(은) 가입을 하지 않았습니다.", colors.RED ) ) else: if not GameUser.exist_user(ctx.bot.con, str(ctx.author.id)): return await ctx.reply( embed=make_text_embed(ctx.author, "가입이 필요한 커맨드입니다.", colors.RED) ) target = ctx.author user = GameUser(self.bot.con, str(target.id)) embed = make_text_embed( ctx.author, f"{seconds_to_timestr(int(time.time() - user.join_time))} 전 가입" if time.time() - user.join_time < 21600 else f"{timestamp_to_timestr(user.join_time)} 가입", colors.AQUA, ) itemsstr = "\n".join(map(lambda item: item.name, user.items)) embed.add_field( name="돈", value=format_money(user.money, self.bot.config["game"]["unit"]), inline=False, ) embed.add_field( name="주식", value="\n".join(map(lambda x: f"{x}: {len(user.stock[x])}주", user.stock)), inline=False, ) embed.add_field( name="아이템", value=itemsstr if itemsstr else "보유 중인 아이템이 없습니다.", inline=False, ) embed.set_author(name=target.name, icon_url=target.avatar_url) await ctx.reply(embed=embed)
async def stock(self, ctx: commands.Context): if ctx.invoked_subcommand is None: await ctx.reply(embed=make_text_embed( ctx.author, f"{ctx.prefix}주식 정보 (주식 이름)\n" f"{ctx.prefix}주식 매수 [주식 이름] [주]\n" f"{ctx.prefix}주식 매도 [주식 이름] [주]\n\n" f"`[]` 필수 `()` 선택", colors.ORANGE, ))
async def stock_sell(self, ctx: commands.Context, name: str, shares: int = None): if shares and shares < 1: return await ctx.reply(embed=make_text_embed( ctx.author, "1주 이상부터 판매할수 있습니다.", colors.RED)) try: data = get_stock_info(self.bot.con, name) except NameError: return await ctx.reply(embed=make_text_embed( ctx.author, f"찾을 수 없는 주식 `{name}` 입니다.", colors.RED)) user = GameUser(self.bot.con, str(ctx.author.id)) if not shares: shares = len(user.stock[name]) if not shares: return await ctx.reply(embed=make_text_embed( ctx.author, f"보유하고 있는 `{name}` 의 주식이 없습니다.", colors.RED, )) price = data["price"] * shares unit = self.bot.config["game"]["unit"] if len(user.stock[name]) < shares: more = shares - len(user.stock[name]) return await ctx.reply(embed=make_text_embed( ctx.author, f"`{name}` 의 주식을 {shares}주 판매하려면 {more}주가 더 필요합니다.", colors.RED, )) buy, message = await one_more_check( ctx, f"`{name}` 의 주식 {shares}주를 {format_money(price, unit)}으로 판매할까요?") if not buy: return await message.edit(embed=make_text_embed( ctx.author, "판매를 취소했습니다.", colors.ORANGE, )) user.money += price for i in range(shares): del user.stock[name][0] user.commit() return await message.edit(embed=make_text_embed( ctx.author, f"`{name}` 의 주식을 {shares}주 판매해 {format_money(price, unit)}을(를) 얻었습니다.\n" f"현재 보유 금액: {format_money(user.money, unit)}", ))
async def stock_buy(self, ctx: commands.Context, name: str, shares: int = None): if shares and shares < 1: return await ctx.reply(embed=make_text_embed( ctx.author, "1주 이상부터 구매할수 있습니다.", colors.RED)) try: data = get_stock_info(self.bot.con, name) except NameError: return await ctx.reply(embed=make_text_embed( ctx.author, f"찾을 수 없는 주식 `{name}` 입니다.", colors.RED)) user = GameUser(self.bot.con, str(ctx.author.id)) if not shares: shares = user.money // data["price"] if not shares: return await ctx.reply(embed=make_text_embed( ctx.author, f"보유하고 있는 돈으로는 `{name}` 의 주식을 1주도 구매할 수 없습니다.", colors.RED, )) price = data["price"] * shares unit = self.bot.config["game"]["unit"] if user.money < price: more = format_money(price - user.money, unit) return await ctx.reply(embed=make_text_embed( ctx.author, f"`{name}` 의 주식을 {shares}주 구매하려면 {more}이(가) 더 필요합니다.", colors.RED, )) buy, message = await one_more_check( ctx, f"`{name}` 의 주식 {shares}주를 {format_money(price, unit)}으로 구매할까요?") if not buy: return await message.edit(embed=make_text_embed( ctx.author, "구매를 취소했습니다.", colors.ORANGE, )) user.money -= price for i in range(shares): user.stock[name].append(data["price"]) user.commit() return await message.edit(embed=make_text_embed( ctx.author, f"`{name}` 의 주식을 {format_money(price, unit)}으로 {shares}주 구매했습니다.\n" f"현재 보유 금액: {format_money(user.money, unit)}", ))
async def one_more_check(ctx: commands.Context, text: str) -> Tuple[bool, discord.Message]: message: discord.Message = await ctx.reply( embed=make_text_embed(ctx.author, text, colors.AQUA)) await message.add_reaction("✅") await message.add_reaction("❎") try: reaction, _ = await ctx.bot.wait_for( "reaction_add", check=lambda r, u: r.message.id == message.id and u == ctx.author, timeout=60.0, ) return reaction.emoji == "✅", message except asyncio.TimeoutError: return False, message
async def work(self, ctx: commands.Context): user = GameUser(self.bot.con, str(ctx.author.id)) cooltime = 5 for item in list(user.items): effect: ItemEffect = item.effect if effect.name == "work-speed": if cooltime > effect.effect: cooltime = effect.effect if effect.use_remove: user.items.remove(item) user.commit() if (self.cooldown.get(ctx.author.id) and time() - self.cooldown[ctx.author.id] < cooltime): raise commands.CommandOnCooldown( commands.Cooldown(1, cooltime, commands.BucketType.user), cooltime - (time() - self.cooldown[ctx.author.id]), ) x, y = map(int, self.bot.config["game"]["work_money"].split("-")) for item in list(user.items): effect: ItemEffect = item.effect if effect.name == "work-power": if y > effect.effect: y *= int(effect.effect) if effect.use_remove: user.items.remove(item) user.commit() add = randint(x, y) user.money += add user.commit() self.cooldown[ctx.author.id] = time() await ctx.reply(embed=make_text_embed( ctx.author, f"당신은 일을 해서 {format_money(add, self.bot.config['game']['unit'])}을(를) 얻었습니다." f"\n다음 일은 {seconds_to_timestr(cooltime)}후에 가능합니다.", ))
async def stock_info(self, ctx: commands.Context, name: str = None): data = {} stocks: List[str] = self.bot.config["game"]["stock"]["stocks"] for stock in stocks: data[stock] = get_stock_info(self.bot.con, stock) if data.get(name): history = list(data[name]["history"]) if len(history) > 20: for i, _ in enumerate(history): if i % 5 != 0: history[i]["time"] = "" * i x = list(map(lambda o: o["time"], history)) y = list(map(lambda o: o["price"], history)) buf = make_graph(x, y) dynamic = "" unit = self.bot.config["game"]["unit"] price = data[name]["price"] if GameUser.exist_user(self.bot.con, str(ctx.author.id)): user = GameUser(self.bot.con, str(ctx.author.id)) shares = len(user.stock[name]) if shares != 0: avg = sum(user.stock[name]) / shares pal = int(price - avg) times = round(price / avg, 2) dynamic = f"{shares}주 보유 중\n" dynamic += f"손익: {format_money(pal, unit)} ( {times}x )\n" dynamic += f"가진 {shares}주를 전부 팔면 {format_money(shares * price, unit)}을(를) 얻습니다" embed = make_text_embed( ctx.author, f"**주가: {format_money(price, unit)}**\n{dynamic}", title=name, ) embed.set_image(url="attachment://graph.png") return await ctx.reply(embed=embed, file=discord.File(buf, filename="graph.png")) next_time = seconds_to_timestr( (self.stock_change_loop.next_iteration.replace(tzinfo=None) - datetime.utcnow()).seconds) unit = self.bot.config["game"]["unit"] chart = [] for i in data: price = data[i]["price"] if len(data[i]["history"]) >= 2: status = data[i]["history"][-2]["price"] < data[i]["price"] value = abs(data[i]["price"] - data[i]["history"][-2]["price"]) chart.append( f"{'+' if status else '-'} {i} {format_money(price, unit)} ( {'▲' if status else '▼'} {value} )" ) else: chart.append(f"? {i} {format_money(price, unit)}") chart = "\n".join(chart) await ctx.reply(embed=make_text_embed( ctx.author, f"**주식 차트**\n```diff\n{chart}\n```\n`{next_time} 후 가격 변동`", ))
async def predicate(ctx): if GameUser.exist_user(ctx.bot.con, str(ctx.author.id)): return True await ctx.reply( embed=make_text_embed(ctx.author, "가입이 필요한 커맨드입니다.", RED)) return False