Skip to content
This repository was archived by the owner on Jun 25, 2024. It is now read-only.

Commit 34c5f9b

Browse files
committed
first commit
1 parent 844209a commit 34c5f9b

32 files changed

+3710
-0
lines changed

.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.env
2+
.vscode
3+
__pycache__
4+
gameDB
5+
bot.log
6+
config.json

Dockerfile

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM python:3.8-slim
2+
3+
ENV NO_LOG_FILE=Yes
4+
5+
COPY . /app
6+
7+
WORKDIR /app
8+
9+
RUN pip3 install -r requirements.txt
10+
11+
CMD ["python3", "main.py"]

cogs/admin.py

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import logging
2+
from utils.errors import create_debug_embed
3+
from main import AIKyaru
4+
import discord
5+
from discord.ext import commands
6+
from discord.ext.commands import Context
7+
import utils
8+
import asyncio
9+
import uuid
10+
11+
12+
class Admin(commands.Cog):
13+
def __init__(self, bot: AIKyaru):
14+
self.bot = bot
15+
self.logger = logging.getLogger("AIKyaru.Admin")
16+
17+
@commands.command(brief="呼叫凱留", aliases=["呼叫凱留"], usage="<訊息(選填)>", hidden=True)
18+
async def callHelp(self, ctx: Context, *, msg: str = None):
19+
def check(reaction, user):
20+
return user == ctx.author and str(reaction.emoji) == "\u2705"
21+
22+
is_guild = isinstance(ctx.channel, discord.TextChannel)
23+
if is_guild:
24+
message = await ctx.send("請點擊下方 :white_check_mark: 來同意機器人蒐集必要資料以供除錯")
25+
await message.add_reaction("\u2705")
26+
27+
try:
28+
await self.bot.wait_for("reaction_add", timeout=60.0, check=check)
29+
except asyncio.TimeoutError:
30+
return await message.delete()
31+
32+
await message.edit(content="獲取資料中...")
33+
await message.clear_reactions()
34+
else:
35+
message = await ctx.send("獲取資料中...")
36+
37+
tracking_uuid = str(uuid.uuid4())
38+
embed = await create_debug_embed(self.bot, ctx, tracking_uuid=tracking_uuid, message=msg)
39+
await self.bot.send_debug(embed=embed)
40+
await message.edit(content=f"已呼叫, 追蹤碼: `{tracking_uuid}`")
41+
42+
@commands.is_owner()
43+
@commands.group(hidden=True)
44+
async def admin(self, ctx: Context):
45+
"""
46+
Admin commands
47+
"""
48+
if ctx.invoked_subcommand is None:
49+
return
50+
51+
@admin.command(aliases=["r"])
52+
async def reply(self, ctx: Context, channel_id: int, *, msg: str):
53+
await self.bot.get_channel(channel_id).send(msg)
54+
55+
@admin.command()
56+
async def activity(self, ctx: Context, *, text: str):
57+
"""
58+
Change bot's activity
59+
"""
60+
await self.bot.change_presence(
61+
status=discord.Status.online,
62+
activity=discord.Activity(
63+
type=self.config.get(["activity", "type"]),
64+
name=f"{self.bot.config.get(['activity','prefix'])}{text}",
65+
),
66+
)
67+
await self.bot.send_debug(embed=utils.notice_embed(f"Activity has been changed", text, ctx.author))
68+
await ctx.send(":white_check_mark: Sucess")
69+
70+
@admin.command(aliases=["uc"])
71+
async def usage(self, ctx: Context):
72+
"""
73+
Show command usage counts
74+
"""
75+
counts = self.bot.counter.as_list()
76+
77+
count_str = "```autohotkey\n"
78+
for i, j in counts:
79+
temp = f"{i}: {j}\n"
80+
if len(count_str) + len(temp) >= 2000:
81+
await ctx.send(count_str + "```")
82+
count_str = "```autohotkey\n"
83+
count_str += temp
84+
85+
await ctx.send(count_str + "```")
86+
87+
@admin.command()
88+
async def reload(self, ctx: Context, cog: str):
89+
"""
90+
Reload cog
91+
"""
92+
try:
93+
self.bot.reload_extension(cog)
94+
await ctx.send(":white_check_mark: Sucess")
95+
except Exception as e:
96+
await self.bot.send_debug(embed=utils.error_embed(f"Failed when reloading cog: {cog}", str(e), ctx.author))
97+
98+
@admin.command()
99+
async def load(self, ctx: Context, cog: str):
100+
"""
101+
Load cog
102+
"""
103+
try:
104+
self.bot.load_extension(cog)
105+
await ctx.send(":white_check_mark: Sucess")
106+
except Exception as e:
107+
await self.bot.send_debug(embed=utils.error_embed(f"Failed when loading cog: {cog}", str(e), ctx.author))
108+
109+
@admin.command()
110+
async def unload(self, ctx: Context, cog: str):
111+
"""
112+
Unload cog
113+
"""
114+
try:
115+
self.bot.unload_extension(cog)
116+
await ctx.send(":white_check_mark: Sucess")
117+
except Exception as e:
118+
await self.bot.send_debug(embed=utils.error_embed(f"Failed when unloading cog: {cog}", str(e), ctx.author))
119+
120+
@admin.command()
121+
async def stop(self, ctx: Context):
122+
"""
123+
Stop the bot :(
124+
"""
125+
await self.bot.send_debug(embed=utils.notice_embed(f"Bot has been stopped", author=ctx.author))
126+
await ctx.send(":thumbsup: Bye~")
127+
await self.bot.close()
128+
129+
@admin.command()
130+
async def exec(self, ctx: Context, *, command: str):
131+
"""
132+
Execute command
133+
"""
134+
self.logger.info(f"Execute: {command}")
135+
if command.startswith("await "):
136+
exe = await eval(command[6:])
137+
else:
138+
print(command)
139+
exe = eval(command)
140+
self.logger.info(f"Execute result: {exe}")
141+
142+
@admin.command()
143+
async def clean_cache(self, ctx: Context, id: int = None):
144+
"""
145+
Clear specific id or all state caches.
146+
"""
147+
self.bot.stateManger.clean_cache(id)
148+
await ctx.send(":white_check_mark: Sucess")
149+
150+
151+
def setup(bot):
152+
bot.add_cog(Admin(bot))

cogs/character/__init__.py

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
from typing import Union
2+
from discord_slash.context import ComponentContext
3+
from discord_slash.model import ButtonStyle
4+
from cogs.character.embeds import Embeds
5+
from main import AIKyaru
6+
from utils import Unit
7+
from utils.custom_id import pref_custom_id, un_pref_custom_id
8+
from discord.ext import commands
9+
from discord.ext.commands import Context
10+
from discord_slash import cog_ext, SlashContext
11+
from discord_slash.utils.manage_commands import create_option
12+
from discord_slash.utils.manage_components import create_button, create_actionrow
13+
from copy import deepcopy
14+
15+
type_buttons = create_actionrow(
16+
*[
17+
create_button(
18+
style=ButtonStyle.green,
19+
label="簡介",
20+
emoji={"name": "info", "id": 850732950600679464},
21+
),
22+
create_button(
23+
style=ButtonStyle.gray,
24+
label="專武",
25+
emoji={"name": "ue", "id": 850732950642884608},
26+
),
27+
create_button(
28+
style=ButtonStyle.blue,
29+
label="技能",
30+
emoji={"name": "skill", "id": 850732950847881226},
31+
),
32+
create_button(
33+
style=ButtonStyle.gray,
34+
label="攻擊",
35+
emoji={"name": "icon_skill_attack", "id": 605337612835749908},
36+
),
37+
create_button(
38+
style=ButtonStyle.red,
39+
label="RANK推薦",
40+
emoji={"name": "rank", "id": 850732950525575178},
41+
),
42+
]
43+
)
44+
45+
46+
class Character(commands.Cog):
47+
def __init__(self, bot: AIKyaru):
48+
self.bot = bot
49+
self.embedMaker = Embeds(bot)
50+
51+
@commands.command(name="info", brief="角色資訊", description="查詢角色資訊", aliases=["i"], usage="<角色關鍵字>")
52+
async def cmd_info(self, ctx: Context, *, keyword: str):
53+
await self._init_embed(ctx, keyword, 1)
54+
55+
@commands.command(name="ue", brief="角色專武", description="查詢角色專屬武器", usage="<角色關鍵字>")
56+
async def cmd_ue(self, ctx: Context, *, keyword: str):
57+
await self._init_embed(ctx, keyword, 2)
58+
59+
@commands.command(name="skill", brief="角色技能", description="查詢角色技能", usage="<角色關鍵字>")
60+
async def cmd_skill(self, ctx: Context, *, keyword: str):
61+
await self._init_embed(ctx, keyword, 3)
62+
63+
@commands.command(name="attack", brief="角色攻擊模式", description="查詢角色攻擊模式", aliases=["atk"], usage="<角色關鍵字>")
64+
async def cmd_attack(self, ctx: Context, *, keyword: str):
65+
await self._init_embed(ctx, keyword, 4)
66+
67+
@commands.command(name="rank", brief="RANK推薦", description="查詢RANK推薦", usage="<角色關鍵字>")
68+
async def cmd_rank(self, ctx: Context, *, keyword: str):
69+
await self._init_embed(ctx, keyword, 5)
70+
71+
@cog_ext.cog_slash(
72+
name="character",
73+
description="查詢角色資訊",
74+
options=[create_option(name="角色", description="可以是角色名稱或關鍵字", option_type=3, required=True)],
75+
connector={"角色": "keyword"},
76+
)
77+
async def cog_menu(self, ctx: SlashContext, keyword: str):
78+
type = await ctx.state.get_user(keys=["config", "character_default_type"]) or 1
79+
80+
await self._init_embed(ctx, keyword, type)
81+
82+
@cog_ext.cog_component()
83+
async def pref_character(self, ctx: ComponentContext):
84+
await self._handle_button(ctx)
85+
86+
async def _init_embed(self, ctx: Union[Context, SlashContext], keyword: str, type: int):
87+
unit = self.bot.config.get_character(keyword)
88+
if not unit:
89+
return await ctx.send(f"找不到跟`{keyword}`有關的角色...")
90+
91+
await ctx.send(**self.create_embed(unit, type))
92+
93+
async def _handle_button(self, ctx: ComponentContext):
94+
# i = unit_id, t = type
95+
data = un_pref_custom_id(custom_id="character", data=ctx.custom_id)
96+
unit = self.bot.config.get_character_by_id(data["i"])
97+
98+
await ctx.edit_origin(**self.create_embed(unit, data["t"]))
99+
100+
def create_embed(self, unit: Unit, type: int):
101+
if type == 1:
102+
embed = self.embedMaker.profile(unit)
103+
elif type == 2:
104+
embed = self.embedMaker.unique_equipment(unit)
105+
elif type == 3:
106+
embed = self.embedMaker.skill(unit)
107+
elif type == 4:
108+
embed = self.embedMaker.atk_pattern(unit)
109+
elif type == 5:
110+
embed = self.embedMaker.rank(unit)
111+
112+
# set button
113+
buttons = deepcopy(type_buttons)
114+
buttons["components"][type - 1]["disabled"] = True
115+
116+
for i, j in enumerate(buttons["components"]):
117+
# i = unit_id, t = type
118+
j["custom_id"] = pref_custom_id(custom_id="character", data={"i": unit.id, "t": i + 1})
119+
120+
return {"embed": embed, "components": [buttons]}
121+
122+
123+
def setup(bot):
124+
bot.add_cog(Character(bot))

0 commit comments

Comments
 (0)