Archived
1
0
Fork 0
This commit is contained in:
yzhh 2023-12-17 21:31:11 +08:00
commit 1b992a080e
30 changed files with 229 additions and 207 deletions

View file

@ -3,48 +3,26 @@ import discord
from bots.discord.client import client from bots.discord.client import client
from bots.discord.slash_parser import slash_parser from bots.discord.slash_parser import slash_parser
arcaea = client.create_group("arcaea", "查询arcaea的相关信息") arcaea = client.create_group("arcaea", "Queries about Arcaea.")
@arcaea.command(description="Get the latest version of game apk.")
@arcaea.command(description="查询best30列表")
async def b30(ctx: discord.ApplicationContext):
await slash_parser(ctx, "b30")
@arcaea.command(description="查询最近游玩记录")
async def info(ctx: discord.ApplicationContext):
await slash_parser(ctx, "info")
@arcaea.command(description="绑定账户")
@discord.option(name="friendcode", description="好友代码")
async def bind(ctx: discord.ApplicationContext, friendcode: str):
await slash_parser(ctx, f"bind {friendcode}")
@arcaea.command(description="取消绑定账户")
async def unbind(ctx: discord.ApplicationContext):
await slash_parser(ctx, "unbind")
@arcaea.command(description="获取最新版本的arcaea安卓版链接")
async def download(ctx: discord.ApplicationContext): async def download(ctx: discord.ApplicationContext):
await slash_parser(ctx, "download") await slash_parser(ctx, "download")
@arcaea.command(description="随机一首歌曲") @arcaea.command(description="Random a song.")
async def random(ctx: discord.ApplicationContext): async def random(ctx: discord.ApplicationContext):
await slash_parser(ctx, "random") await slash_parser(ctx, "random")
rank = arcaea.create_subgroup("rank", "查询arcaea日排行榜的相关信息") rank = arcaea.create_subgroup("rank", "View the current daily rank of Arcaea songs.")
@rank.command(description="查询arcaea免费包当前日排行榜") @rank.command(description="View the current rank of the free packs.")
async def free(ctx: discord.ApplicationContext): async def free(ctx: discord.ApplicationContext):
await slash_parser(ctx, "rank free") await slash_parser(ctx, "rank free")
@rank.command(description="查询arcaea收费包当前日排行榜") @rank.command(description="View the current rank of the paid packs.")
async def paid(ctx: discord.ApplicationContext): async def paid(ctx: discord.ApplicationContext):
await slash_parser(ctx, "rank paid") await slash_parser(ctx, "rank paid")

View file

@ -6,10 +6,9 @@ from bots.discord.slash_parser import slash_parser
async def auto_search(ctx: discord.AutocompleteContext): async def auto_search(ctx: discord.AutocompleteContext):
if ctx.options["mojiraid"] == '': if ctx.options["mojiraid"] == '':
return ['MC-', 'MCPE-', 'MCD-', 'MCL-', 'REALMS-', 'WEB-', 'MCCE-'] return ['BDS-', 'MCPE-', 'MCD-', 'MCL-', 'MCLG-', 'REALMS-', 'MC-', 'WEB-']
@client.command(description="Query the corresponding ticket on Mojira.")
@client.command(description="查询一个已记录在Mojira上的bug信息")
@discord.option(name="mojiraid", autocomplete=auto_search) @discord.option(name="mojiraid", autocomplete=auto_search)
async def bug(ctx: discord.ApplicationContext, mojiraid: str): async def bugtracker(ctx: discord.ApplicationContext, mojiraid: str):
await slash_parser(ctx, mojiraid) await slash_parser(ctx, mojiraid)

View file

@ -3,30 +3,30 @@ import discord
from bots.discord.client import client from bots.discord.client import client
from bots.discord.slash_parser import slash_parser from bots.discord.slash_parser import slash_parser
cytoid = client.create_group("cytoid", "查询Cytoid的相关信息") cytoid = client.create_group("cytoid", "Query about Cytoid.")
@cytoid.command(description="查询Best30列表") @cytoid.command(description="Query the Best 30 list.")
async def b30(ctx: discord.ApplicationContext): async def b30(ctx: discord.ApplicationContext):
await slash_parser(ctx, "b30") await slash_parser(ctx, "b30")
@cytoid.command(description="查询Recent30列表") @cytoid.command(description="Query the Recent 30 list.")
async def r30(ctx: discord.ApplicationContext): async def r30(ctx: discord.ApplicationContext):
await slash_parser(ctx, "r30") await slash_parser(ctx, "r30")
@cytoid.command(description="查询个人信息") @cytoid.command(description="Query user profile.")
async def profile(ctx: discord.ApplicationContext): async def profile(ctx: discord.ApplicationContext):
await slash_parser(ctx, "profile") await slash_parser(ctx, "profile")
@cytoid.command(description="绑定用户") @cytoid.command(description="Bind user.")
@discord.option(name="username", description="用户名") @discord.option(name="username", description="Your Cytoid username.")
async def bind(ctx: discord.ApplicationContext, username: str): async def bind(ctx: discord.ApplicationContext, username: str):
await slash_parser(ctx, f"bind {username}") await slash_parser(ctx, f"bind {username}")
@cytoid.command(description="取消绑定用户") @cytoid.command(description="Unbind user.")
async def unbind(ctx: discord.ApplicationContext): async def unbind(ctx: discord.ApplicationContext):
await slash_parser(ctx, "unbind") await slash_parser(ctx, "unbind")

View file

@ -4,7 +4,7 @@ from bots.discord.client import client
from bots.discord.slash_parser import slash_parser from bots.discord.slash_parser import slash_parser
@client.slash_command(description="获取一个Minecraft玩家的信息") @client.slash_command(description="Get Minecraft player information.")
@discord.option(name="player", description="玩家名") @discord.option(name="username_or_uuid", description="The name or UUID of Minecraft player.")
async def mcplayer(ctx: discord.ApplicationContext, player: str): async def mcplayer(ctx: discord.ApplicationContext, username_or_uuid: str):
await slash_parser(ctx, player) await slash_parser(ctx, username_or_uuid)

View file

@ -4,21 +4,26 @@ from bots.discord.client import client
from bots.discord.slash_parser import slash_parser from bots.discord.slash_parser import slash_parser
@client.slash_command(description="获取Minecraft Java版的最新版本信息") @client.slash_command(description="Get the latest version of Minecraft: Java Edition in the launcher.")
async def mcv(ctx: discord.ApplicationContext): async def mcv(ctx: discord.ApplicationContext):
await slash_parser(ctx, '') await slash_parser(ctx, '')
@client.slash_command(description="获取Minecraft基岩版的最新版本信息") @client.slash_command(description="Get the latest version of Minecraft: Bedrock Edition on Mojira.")
async def mcbv(ctx: discord.ApplicationContext): async def mcbv(ctx: discord.ApplicationContext):
await slash_parser(ctx, '') await slash_parser(ctx, '')
@client.slash_command(description="获取Minecraft Dungeons的最新版本信息") @client.slash_command(description="Get the latest version of Minecraft Dungeons on Mojira.")
async def mcdv(ctx: discord.ApplicationContext): async def mcdv(ctx: discord.ApplicationContext):
await slash_parser(ctx, '') await slash_parser(ctx, '')
@client.slash_command(description="获取Minecraft教育版的最新版本信息") @client.slash_command(description="Get the latest version of Minecraft: Education Edition in Windows Edition.")
async def mcev(ctx: discord.ApplicationContext): async def mcev(ctx: discord.ApplicationContext):
await slash_parser(ctx, '') await slash_parser(ctx, '')
@client.slash_command(description="Get the latest version of Minecraft Legends on Mojira.")
async def mclgv(ctx: discord.ApplicationContext):
await slash_parser(ctx, '')

View file

@ -10,7 +10,7 @@ async def auto_search(ctx: discord.AutocompleteContext):
return [ctx.options["address"]] return [ctx.options["address"]]
@client.slash_command(description="获取一个Minecraft服务器的信息") @client.slash_command(description="Get Minecraft: Java/Bedrock Edition server motd.")
@discord.option(name="address", description="服务器地址", autocomplete=auto_search) @discord.option(name="address", description="The server address.", autocomplete=auto_search)
async def server(ctx: discord.ApplicationContext, address: str): async def server(ctx: discord.ApplicationContext, address: str):
await slash_parser(ctx, address) await slash_parser(ctx, address)

View file

@ -3,10 +3,10 @@ import discord
from bots.discord.client import client from bots.discord.client import client
from bots.discord.slash_parser import slash_parser from bots.discord.slash_parser import slash_parser
tweet = client.create_group("tweet", "获取推文摘要") tweet = client.create_group("tweet", "Get tweet image from tweet ID or link.")
@tweet.command() @tweet.command()
@discord.option(name="tweetid", description="推文ID") @discord.option(name="tweet", description="The tweet ID or tweet link.")
async def get(ctx: discord.ApplicationContext, tweetid: str): async def get(ctx: discord.ApplicationContext, tweet: str):
await slash_parser(ctx, tweetid) await slash_parser(ctx, tweet)

View file

@ -2,7 +2,7 @@
"arcaea.help.calc": "Calculate the single Potential based on scores and rating.", "arcaea.help.calc": "Calculate the single Potential based on scores and rating.",
"arcaea.help.desc": "Queries about Arcaea.", "arcaea.help.desc": "Queries about Arcaea.",
"arcaea.help.download": "Get the latest version of game apk.", "arcaea.help.download": "Get the latest version of game apk.",
"arcaea.help.random": "Random a track.", "arcaea.help.random": "Random a song.",
"arcaea.help.rank.free": "View the current rank of the free packs.", "arcaea.help.rank.free": "View the current rank of the free packs.",
"arcaea.help.rank.paid": "View the current rank of the paid packs.", "arcaea.help.rank.paid": "View the current rank of the paid packs.",
"arcaea.message.download": "Current latest version is ${version}.\nDownload: ${url}", "arcaea.message.download": "Current latest version is ${version}.\nDownload: ${url}",

View file

@ -1,7 +1,7 @@
{ {
"core.help.admin": "Commands available to group administrators.",
"core.help.admin.add": "Set members as bot administrators, implement the function of managing the robot without setting members as group administrators. It's no longer needed to set up it when you are already a group administrator.", "core.help.admin.add": "Set members as bot administrators, implement the function of managing the robot without setting members as group administrators. It's no longer needed to set up it when you are already a group administrator.",
"core.help.admin.ban": "Limit someone to use bot in the group.", "core.help.admin.ban": "Limit someone to use bot in the group.",
"core.help.admin.desc": "Commands available to group administrators.",
"core.help.admin.list": "View all bot administrators.", "core.help.admin.list": "View all bot administrators.",
"core.help.admin.remove": "Remove bot administrator from member.", "core.help.admin.remove": "Remove bot administrator from member.",
"core.help.admin.unban": "Remove limit someone to use bot in the group.", "core.help.admin.unban": "Remove limit someone to use bot in the group.",
@ -11,8 +11,8 @@
"core.help.alias.remove": "Remove custom command alias.", "core.help.alias.remove": "Remove custom command alias.",
"core.help.alias.reset": "Reset custom command alias.", "core.help.alias.reset": "Reset custom command alias.",
"core.help.leave": "Let the bot leave the group.", "core.help.leave": "Let the bot leave the group.",
"core.help.locale": "View bot running language.", "core.help.locale.desc": "Control bot language.",
"core.help.locale.set": "Set bot running language.", "core.help.locale.set": "Set the bot running languages.",
"core.help.module.disable": "Disable single/multiple module(s).", "core.help.module.disable": "Disable single/multiple module(s).",
"core.help.module.disable_all": "Disable all modules.", "core.help.module.disable_all": "Disable all modules.",
"core.help.module.enable": "Enable single/multiple module(s).", "core.help.module.enable": "Enable single/multiple module(s).",
@ -30,9 +30,10 @@
"core.help.prefix.list": "View custom command prefixes.", "core.help.prefix.list": "View custom command prefixes.",
"core.help.prefix.remove": "Remove custom command prefix.", "core.help.prefix.remove": "Remove custom command prefix.",
"core.help.prefix.reset": "Reset custom command prefix.", "core.help.prefix.reset": "Reset custom command prefix.",
"core.help.toggle.check": "Toggles whether to display command check prompts.", "core.help.setup.check": "setups whether to display command check prompts.",
"core.help.toggle.typing": "Toggle whether to display input prompts.", "core.help.setup.desc": "Set up bot actions.",
"core.help.toggle.timeoffset": "Set the time offset.", "core.help.setup.timeoffset": "Set the time offset.",
"core.help.setup.typing": "setup whether to display input prompts.",
"core.help.version": "View bot version.", "core.help.version": "View bot version.",
"core.help.whoami": "Get the ID of the user account that sent the command inside the bot.", "core.help.whoami": "Get the ID of the user account that sent the command inside the bot.",
"core.message.abuse.ban.success": "Successfully banned ${user}.", "core.message.abuse.ban.success": "Successfully banned ${user}.",
@ -153,13 +154,13 @@
"core.message.set.help.option.success": "The following parameters were set for the object: ${k} -> ${v}", "core.message.set.help.option.success": "The following parameters were set for the object: ${k} -> ${v}",
"core.message.set.invalid": "Invalid ID format.", "core.message.set.invalid": "Invalid ID format.",
"core.message.set.module.success": "The following modules were successfully configured for the object: ", "core.message.set.module.success": "The following modules were successfully configured for the object: ",
"core.message.setup.check.disable": "Check prompt disabled.",
"core.message.setup.check.enable": "Check prompt enabled.",
"core.message.setup.timeoffset.invalid": "Invalid time offset.",
"core.message.setup.timeoffset.success": "The time offset has been set to UTC${offset}.",
"core.message.setup.typing.disable": "Input prompt disabled.",
"core.message.setup.typing.enable": "Input prompt enabled.",
"core.message.superuser.invalid": "Invalid ID format. The format should be \"${target}|<User ID>\".", "core.message.superuser.invalid": "Invalid ID format. The format should be \"${target}|<User ID>\".",
"core.message.toggle.check.disable": "Check prompt disabled.",
"core.message.toggle.check.enable": "Check prompt enabled.",
"core.message.toggle.timeoffset.invalid": "Invalid time offset.",
"core.message.toggle.timeoffset.success": "The time offset has been set to UTC${offset}.",
"core.message.toggle.typing.disable": "Input prompt disabled.",
"core.message.toggle.typing.enable": "Input prompt enabled.",
"core.message.update.failed": "Failed to fetch update from GitHub. Please try again later.", "core.message.update.failed": "Failed to fetch update from GitHub. Please try again later.",
"core.message.version": "Current bot version: ${commit}", "core.message.version": "Current bot version: ${commit}",
"core.message.version.unknown": "Unable to get version. This instance may not be deployed using Git.", "core.message.version.unknown": "Unable to get version. This instance may not be deployed using Git.",

View file

@ -1,7 +1,7 @@
{ {
"core.help.admin": "一些群组管理员可使用的命令。",
"core.help.admin.add": "设置成员为机器人管理员。以实现不设置成员为群组管理员的状況下管理机器人的效果。已是群组管理员无需设置此项目。", "core.help.admin.add": "设置成员为机器人管理员。以实现不设置成员为群组管理员的状況下管理机器人的效果。已是群组管理员无需设置此项目。",
"core.help.admin.ban": "限制某人在本群使用机器人。", "core.help.admin.ban": "限制某人在本群使用机器人。",
"core.help.admin.desc": "一些群组管理员可使用的命令。",
"core.help.admin.list": "查看所有机器人管理员。", "core.help.admin.list": "查看所有机器人管理员。",
"core.help.admin.remove": "取消成员的机器人管理员。", "core.help.admin.remove": "取消成员的机器人管理员。",
"core.help.admin.unban": "解除对某人在本群使用机器人的限制。", "core.help.admin.unban": "解除对某人在本群使用机器人的限制。",
@ -11,7 +11,7 @@
"core.help.alias.remove": "移除自定义命令别名。", "core.help.alias.remove": "移除自定义命令别名。",
"core.help.alias.reset": "重置自定义命令别名。", "core.help.alias.reset": "重置自定义命令别名。",
"core.help.leave": "使机器人离开群组。", "core.help.leave": "使机器人离开群组。",
"core.help.locale": "查看机器人运行语言。", "core.help.locale.desc": "控制机器人语言。",
"core.help.locale.set": "设置机器人运行语言。", "core.help.locale.set": "设置机器人运行语言。",
"core.help.module.disable": "关闭一个/多个模块。", "core.help.module.disable": "关闭一个/多个模块。",
"core.help.module.disable_all": "关闭所有模块。", "core.help.module.disable_all": "关闭所有模块。",
@ -30,9 +30,10 @@
"core.help.prefix.list": "查看自定义命令前缀列表。", "core.help.prefix.list": "查看自定义命令前缀列表。",
"core.help.prefix.remove": "移除自定义命令前缀。", "core.help.prefix.remove": "移除自定义命令前缀。",
"core.help.prefix.reset": "重置自定义命令前缀。", "core.help.prefix.reset": "重置自定义命令前缀。",
"core.help.toggle.check": "切换是否展示命令错字检查提示。", "core.help.setup.check": "切换是否展示命令错字检查提示。",
"core.help.toggle.typing": "切换是否展示输入提示。", "core.help.setup.desc": "设置机器人行为。",
"core.help.toggle.timeoffset": "设置时间偏移量。", "core.help.setup.timeoffset": "设置时间偏移量。",
"core.help.setup.typing": "切换是否展示输入提示。",
"core.help.version": "查看机器人的版本号。", "core.help.version": "查看机器人的版本号。",
"core.help.whoami": "获取发送命令的账号在机器人内部的 ID。", "core.help.whoami": "获取发送命令的账号在机器人内部的 ID。",
"core.message.abuse.ban.success": "成功封禁 ${user}。", "core.message.abuse.ban.success": "成功封禁 ${user}。",
@ -153,13 +154,13 @@
"core.message.set.help.option.success": "成功为对象设置了以下参数:${k} -> ${v}", "core.message.set.help.option.success": "成功为对象设置了以下参数:${k} -> ${v}",
"core.message.set.invalid": "ID 格式错误。", "core.message.set.invalid": "ID 格式错误。",
"core.message.set.module.success": "成功为对象配置了以下模块:", "core.message.set.module.success": "成功为对象配置了以下模块:",
"core.message.setup.check.disable": "已关闭错字检查提示。",
"core.message.setup.check.enable": "已开启错字检查提示。",
"core.message.setup.timeoffset.invalid": "无效的时间偏移量。",
"core.message.setup.timeoffset.success": "已将时间偏移量设定为 UTC${offset}。",
"core.message.setup.typing.disable": "已关闭输入提示。",
"core.message.setup.typing.enable": "已开启输入提示。",
"core.message.superuser.invalid": "ID 格式错误,格式应为“${target}|<用户 ID>”。", "core.message.superuser.invalid": "ID 格式错误,格式应为“${target}|<用户 ID>”。",
"core.message.toggle.check.disable": "已关闭错字检查提示。",
"core.message.toggle.check.enable": "已开启错字检查提示。",
"core.message.toggle.timeoffset.invalid": "无效的时间偏移量。",
"core.message.toggle.timeoffset.success": "已将时间偏移量设定为 UTC${offset}。",
"core.message.toggle.typing.disable": "已关闭输入提示。",
"core.message.toggle.typing.enable": "已开启输入提示。",
"core.message.update.failed": "尝试从 GitHub 获取更新失败,请稍后重试。", "core.message.update.failed": "尝试从 GitHub 获取更新失败,请稍后重试。",
"core.message.version": "当前机器人版本号:${commit}", "core.message.version": "当前机器人版本号:${commit}",
"core.message.version.unknown": "无法获取版本号。此实例可能没有使用 Git 进行部署。", "core.message.version.unknown": "无法获取版本号。此实例可能没有使用 Git 进行部署。",

View file

@ -1,7 +1,7 @@
{ {
"core.help.admin": "一些群組管理員可使用的指令。",
"core.help.admin.add": "設定成員為機器人管理員,以實現不設定成員為群組管理員的狀況下管理機器人的效果。已是群組管理員無須設定此指令。", "core.help.admin.add": "設定成員為機器人管理員,以實現不設定成員為群組管理員的狀況下管理機器人的效果。已是群組管理員無須設定此指令。",
"core.help.admin.ban": "限制某人在此群組使用機器人。", "core.help.admin.ban": "限制某人在此群組使用機器人。",
"core.help.admin.desc": "一些群組管理員可使用的指令。",
"core.help.admin.list": "檢視所有機器人管理員。", "core.help.admin.list": "檢視所有機器人管理員。",
"core.help.admin.remove": "取消成員的機器人管理員。", "core.help.admin.remove": "取消成員的機器人管理員。",
"core.help.admin.unban": "解除對某人在此群組使用機器人的限制。", "core.help.admin.unban": "解除對某人在此群組使用機器人的限制。",
@ -11,7 +11,7 @@
"core.help.alias.remove": "移除自訂指令別名。", "core.help.alias.remove": "移除自訂指令別名。",
"core.help.alias.reset": "重設自訂指令別名。", "core.help.alias.reset": "重設自訂指令別名。",
"core.help.leave": "使機器人離開群組。", "core.help.leave": "使機器人離開群組。",
"core.help.locale": "檢視機器人使用的語言。", "core.help.locale.desc": "控制機器人語言。",
"core.help.locale.set": "設定機器人使用的語言。", "core.help.locale.set": "設定機器人使用的語言。",
"core.help.module.disable": "停用一個/多個模組。", "core.help.module.disable": "停用一個/多個模組。",
"core.help.module.disable_all": "停用所有模組。", "core.help.module.disable_all": "停用所有模組。",
@ -30,9 +30,10 @@
"core.help.prefix.list": "檢視自訂指令前綴列表。", "core.help.prefix.list": "檢視自訂指令前綴列表。",
"core.help.prefix.remove": "移除自訂指令前綴。", "core.help.prefix.remove": "移除自訂指令前綴。",
"core.help.prefix.reset": "重設自訂指令前綴。", "core.help.prefix.reset": "重設自訂指令前綴。",
"core.help.toggle.check": "切換是否顯示指令錯誤檢查提醒。", "core.help.setup.check": "切換是否顯示指令錯誤檢查提醒。",
"core.help.toggle.typing": "切換是否顯示輸入提醒。", "core.help.setup.desc": "設定機器人行動",
"core.help.toggle.timeoffset": "設定時間偏移量。", "core.help.setup.timeoffset": "設定時間偏移量。",
"core.help.setup.typing": "切換是否顯示輸入提醒。",
"core.help.version": "檢視機器人的版本號。", "core.help.version": "檢視機器人的版本號。",
"core.help.whoami": "取得傳送指令的帳戶在機器人內部的 ID。", "core.help.whoami": "取得傳送指令的帳戶在機器人內部的 ID。",
"core.message.abuse.ban.success": "成功封鎖 ${user}。", "core.message.abuse.ban.success": "成功封鎖 ${user}。",
@ -153,13 +154,13 @@
"core.message.set.help.option.success": "成功為物件設定了以下參數:${k} -> ${v}", "core.message.set.help.option.success": "成功為物件設定了以下參數:${k} -> ${v}",
"core.message.set.invalid": "ID 格式錯誤。", "core.message.set.invalid": "ID 格式錯誤。",
"core.message.set.module.success": "成功為物件配置了以下模組:", "core.message.set.module.success": "成功為物件配置了以下模組:",
"core.message.setup.check.disable": "已停用指令錯誤檢查提醒。",
"core.message.setup.check.enable": "已啟用指令錯誤檢查提醒。",
"core.message.setup.timeoffset.invalid": "無效的時間偏移量。",
"core.message.setup.timeoffset.success": "已將時間偏移量設定為 UTC${offset}。",
"core.message.setup.typing.disable": "已停用輸入提醒。",
"core.message.setup.typing.enable": "已啟用輸入提醒。",
"core.message.superuser.invalid": "ID 格式錯誤,格式應為「${target}|<使用者 ID>」。", "core.message.superuser.invalid": "ID 格式錯誤,格式應為「${target}|<使用者 ID>」。",
"core.message.toggle.check.disable": "已停用指令錯誤檢查提醒。",
"core.message.toggle.check.enable": "已啟用指令錯誤檢查提醒。",
"core.message.toggle.timeoffset.invalid": "無效的時間偏移量。",
"core.message.toggle.timeoffset.success": "已將時間偏移量設定為 UTC${offset}。",
"core.message.toggle.typing.disable": "已停用輸入提醒。",
"core.message.toggle.typing.enable": "已啟用輸入提醒。",
"core.message.update.failed": "嘗試從 GitHub 取得更新失敗,請稍後重試。", "core.message.update.failed": "嘗試從 GitHub 取得更新失敗,請稍後重試。",
"core.message.version": "目前機器人版本號:${commit}", "core.message.version": "目前機器人版本號:${commit}",
"core.message.version.unknown": "無法取得版本號。此實例可能沒有使用 Git 進行部署。", "core.message.version.unknown": "無法取得版本號。此實例可能沒有使用 Git 進行部署。",

View file

@ -15,10 +15,10 @@ from database import BotDBUtil
jwt_secret = Config('jwt_secret') jwt_secret = Config('jwt_secret')
ver = module('version', base=True, desc='{core.help.version}') ver = module('version', base=True)
@ver.command() @ver.command('{{core.help.version}}')
async def bot_version(msg: Bot.MessageSession): async def bot_version(msg: Bot.MessageSession):
if Info.version: if Info.version:
await msg.finish(msg.locale.t('core.message.version', commit=Info.version[0:6])) await msg.finish(msg.locale.t('core.message.version', commit=Info.version[0:6]))
@ -26,12 +26,12 @@ async def bot_version(msg: Bot.MessageSession):
await msg.finish(msg.locale.t('core.message.version.unknown')) await msg.finish(msg.locale.t('core.message.version.unknown'))
ping = module('ping', base=True, desc='{core.help.ping}') ping = module('ping', base=True)
started_time = datetime.now() started_time = datetime.now()
@ping.command() @ping.command('{{core.help.ping}}')
async def _(msg: Bot.MessageSession): async def _(msg: Bot.MessageSession):
checkpermisson = msg.check_super_user() checkpermisson = msg.check_super_user()
result = "Pong!" result = "Pong!"
@ -70,7 +70,7 @@ async def _(msg: Bot.MessageSession):
await msg.finish(result) await msg.finish(result)
admin = module('admin', base=True, required_admin=True, desc='{core.help.admin}') admin = module('admin', base=True, required_admin=True, desc='{core.help.admin.desc}')
@admin.command([ @admin.command([
@ -125,10 +125,10 @@ async def config_ban(msg: Bot.MessageSession):
await msg.finish(msg.locale.t("core.message.admin.ban.not_yet")) await msg.finish(msg.locale.t("core.message.admin.ban.not_yet"))
locale = module('locale', base=True) locale = module('locale', base=True, desc='{core.help.locale.desc}')
@locale.command('{{core.help.locale}}') @locale.command()
async def _(msg: Bot.MessageSession): async def _(msg: Bot.MessageSession):
avaliable_lang = msg.locale.t("message.delimiter").join(get_available_locales()) avaliable_lang = msg.locale.t("message.delimiter").join(get_available_locales())
await msg.finish( await msg.finish(
@ -171,33 +171,33 @@ async def _(msg: Bot.MessageSession):
disable_secret_check=True) disable_secret_check=True)
tog = module('toggle', base=True, required_admin=True) setup = module('setup', base=True, required_admin=True, desc='{core.help.setup.desc}')
@tog.command('typing {{core.help.toggle.typing}}') @setup.command('typing {{core.help.setup.typing}}')
async def _(msg: Bot.MessageSession): async def _(msg: Bot.MessageSession):
target = BotDBUtil.SenderInfo(msg.target.sender_id) target = BotDBUtil.SenderInfo(msg.target.sender_id)
state = target.query.disable_typing state = target.query.disable_typing
if not state: if not state:
target.edit('disable_typing', True) target.edit('disable_typing', True)
await msg.finish(msg.locale.t('core.message.toggle.typing.disable')) await msg.finish(msg.locale.t('core.message.setup.typing.disable'))
else: else:
target.edit('disable_typing', False) target.edit('disable_typing', False)
await msg.finish(msg.locale.t('core.message.toggle.typing.enable')) await msg.finish(msg.locale.t('core.message.setup.typing.enable'))
@tog.command('check {{core.help.toggle.check}}') @setup.command('check {{core.help.setup.check}}')
async def _(msg: Bot.MessageSession): async def _(msg: Bot.MessageSession):
state = msg.options.get('typo_check') state = msg.options.get('typo_check')
if state: if state:
msg.data.edit_option('typo_check', False) msg.data.edit_option('typo_check', False)
await msg.finish(msg.locale.t('core.message.toggle.check.enable')) await msg.finish(msg.locale.t('core.message.setup.check.enable'))
else: else:
msg.data.edit_option('typo_check', True) msg.data.edit_option('typo_check', True)
await msg.finish(msg.locale.t('core.message.toggle.check.disable')) await msg.finish(msg.locale.t('core.message.setup.check.disable'))
@tog.command('timeoffset <offset> {{core.help.toggle.timeoffset}}') @setup.command('timeoffset <offset> {{core.help.setup.timeoffset}}')
async def _(msg: Bot.MessageSession, offset: str): async def _(msg: Bot.MessageSession, offset: str):
try: try:
tstr_split = [int(part) for part in offset.split(':')] tstr_split = [int(part) for part in offset.split(':')]
@ -211,15 +211,15 @@ async def _(msg: Bot.MessageSession, offset: str):
if hour > 12 or minute >= 60: if hour > 12 or minute >= 60:
raise ValueError raise ValueError
except ValueError: except ValueError:
await msg.finish(msg.locale.t('core.message.toggle.timeoffset.invalid')) await msg.finish(msg.locale.t('core.message.setup.timeoffset.invalid'))
msg.data.edit_option('timezone_offset', offset) msg.data.edit_option('timezone_offset', offset)
await msg.finish(msg.locale.t('core.message.toggle.timeoffset.success', offset=offset)) await msg.finish(msg.locale.t('core.message.setup.timeoffset.success', offset=offset))
mute = module('mute', base=True, required_admin=True, desc='{core.help.mute}') mute = module('mute', base=True, required_admin=True)
@mute.command() @mute.command('{{core.help.mute}}')
async def _(msg: Bot.MessageSession): async def _(msg: Bot.MessageSession):
state = msg.data.switch_mute() state = msg.data.switch_mute()
if state: if state:
@ -228,16 +228,10 @@ async def _(msg: Bot.MessageSession):
await msg.finish(msg.locale.t('core.message.mute.disable')) await msg.finish(msg.locale.t('core.message.mute.disable'))
leave = module( leave = module('leave', base=True, required_admin=True, available_for='QQ|Group', alias='dismiss')
'leave',
base=True,
required_admin=True,
available_for='QQ|Group',
alias='dismiss',
desc='{core.help.leave}')
@leave.command() @leave.command('{{core.help.leave}}')
async def _(msg: Bot.MessageSession): async def _(msg: Bot.MessageSession):
confirm = await msg.wait_confirm(msg.locale.t('core.message.confirm')) confirm = await msg.wait_confirm(msg.locale.t('core.message.confirm'))
if confirm: if confirm:
@ -245,10 +239,10 @@ async def _(msg: Bot.MessageSession):
await msg.call_api('set_group_leave', group_id=msg.session.target) await msg.call_api('set_group_leave', group_id=msg.session.target)
token = module('token', base=True, desc='{core.help.token}') token = module('token', base=True)
@token.command('<code>') @token.command('<code> {{core.help.token}}')
async def _(msg: Bot.MessageSession): async def _(msg: Bot.MessageSession):
await msg.finish(jwt.encode({ await msg.finish(jwt.encode({
'exp': datetime.utcnow() + timedelta(seconds=60 * 60 * 24 * 7), # 7 days 'exp': datetime.utcnow() + timedelta(seconds=60 * 60 * 24 * 7), # 7 days

View file

@ -1,7 +1,7 @@
{ {
"cytoid.help.b30": "Query the Best 30 list of Cytoid user. ", "cytoid.help.b30": "Query the Best 30 list of Cytoid user. ",
"cytoid.help.bind": "Bind Cytoid user.", "cytoid.help.bind": "Bind Cytoid user.",
"cytoid.help.desc": "Query Cytoid related content.", "cytoid.help.desc": "Query about Cytoid.",
"cytoid.help.profile": "Query user profile.", "cytoid.help.profile": "Query user profile.",
"cytoid.help.r30": "Query the Recent 30 list of Cytoid user. ", "cytoid.help.r30": "Query the Recent 30 list of Cytoid user. ",
"cytoid.help.unbind": "Unbind user.", "cytoid.help.unbind": "Unbind user.",

View file

@ -1,5 +1,3 @@
import ujson as json
from core.builtins import Bot, Image, Plain from core.builtins import Bot, Image, Plain
from core.utils.http import get_url from core.utils.http import get_url
from .dbutils import CytoidBindInfoManager from .dbutils import CytoidBindInfoManager

View file

@ -210,7 +210,7 @@ async def get_rating(msg: Bot.MessageSession, uid, query_type):
# shutil.rmtree(workdir) # shutil.rmtree(workdir)
return {'status': True, 'path': savefilename} return {'status': True, 'path': savefilename}
except Exception as e: except Exception as e:
if str(e).startswith('404'): if e.args == (404,):
await msg.finish(msg.locale.t("cytoid.message.user_not_found")) await msg.finish(msg.locale.t("cytoid.message.user_not_found"))
traceback.print_exc() traceback.print_exc()
return {'status': False, 'text': msg.locale.t("error") + str(e)} return {'status': False, 'text': msg.locale.t("error") + str(e)}

View file

@ -2,7 +2,7 @@ from core.builtins import Bot
from core.component import module from core.component import module
from modules.github import repo, user, search from modules.github import repo, user, search
github = module('github', alias='gh', developers=['Dianliang233']) github = module('github', alias='gh', developers=['Dianliang233'], desc='{github.help.desc}')
@github.handle('<name> {{github.help}}') @github.handle('<name> {{github.help}}')
@ -18,7 +18,7 @@ async def _(msg: Bot.MessageSession):
await repo.repo(msg) await repo.repo(msg)
@github.handle(('user <name> {{github.help.user}}')) @github.handle('user <name> {{github.help.user}}')
async def _(msg: Bot.MessageSession): async def _(msg: Bot.MessageSession):
await user.user(msg) await user.user(msg)

View file

@ -1,12 +1,13 @@
{ {
"github.help.desc": "Github query tool.",
"github.help": "Trying to automatically identifying and distinguishing repo/user.", "github.help": "Trying to automatically identifying and distinguishing repo/user.",
"github.help.repo": "Getting GitHub repository information.", "github.help.repo": "Get GitHub repository information.",
"github.help.search": "Searching repositories on GitHub.", "github.help.search": "Search repositories on GitHub.",
"github.help.user": "Getting GitHub user or organization information.", "github.help.user": "Get GitHub user or organization information.",
"github.message.repo.not_found": "The repository does not exist, please check your input.", "github.message.repo.not_found": "The repository does not exist. Please check your input.",
"github.message.search": "Successfully to search for ${result} results:", "github.message.search": "Successfully to search for ${result} results:",
"github.message.search.none": "搜索成功,未找到结果。", "github.message.search.none": "No results found.",
"github.message.search.more_information": "Truncated due to chat limits; ${more_result} more results may not be shown.", "github.message.search.more_information": "Truncated due to chat limits; ${more_result} more results may not be shown.",
"github.message.search.not_found": "The repository cannot be found; please check your input.", "github.message.search.not_found": "The repository cannot be found. Please check your input.",
"github.message.user.not_found": "The user cannot be found; please check your input." "github.message.user.not_found": "The user cannot be found. Please check your input."
} }

View file

@ -1,12 +1,13 @@
{ {
"github.help": "尝试自动识别并区分 repo/user。", "github.help": "尝试自动识别并区分 repo/user。",
"github.help.desc": "GitHub 查询工具。",
"github.help.repo": "获取 GitHub 存储库信息。", "github.help.repo": "获取 GitHub 存储库信息。",
"github.help.search": "搜索 GitHub 上的存储库。", "github.help.search": "搜索 GitHub 上的存储库。",
"github.help.user": "获取 GitHub 用户或组织信息。", "github.help.user": "获取 GitHub 用户或组织信息。",
"github.message.repo.not_found": "此存储库不存在,请检查输入。", "github.message.repo.not_found": "此存储库不存在,请检查输入。",
"github.message.search": "搜索成功,共 ${result} 条结果:", "github.message.search": "搜索成功,共 ${result} 条结果:",
"github.message.search.none": "搜索成功,未找到结果。",
"github.message.search.more_information": "另有 ${more_result} 条结果未显示。", "github.message.search.more_information": "另有 ${more_result} 条结果未显示。",
"github.message.search.none": "搜索成功,未找到结果。",
"github.message.search.not_found": "未找到存储库,请检查输入。", "github.message.search.not_found": "未找到存储库,请检查输入。",
"github.message.user.not_found": "查无此人,请检查输入。" "github.message.user.not_found": "查无此人,请检查输入。"
} }

View file

@ -1,4 +1,5 @@
{ {
"github.help.desc": "GitHub 查詢工具。",
"github.help": "嘗試自動辨識並區分 repo/user。", "github.help": "嘗試自動辨識並區分 repo/user。",
"github.help.repo": "取得 Github 儲存庫資訊。", "github.help.repo": "取得 Github 儲存庫資訊。",
"github.help.search": "搜尋 Github 上的儲存庫。", "github.help.search": "搜尋 Github 上的儲存庫。",

View file

@ -1,4 +1,3 @@
import asyncio
import traceback import traceback
from core.builtins import Bot, Image, Plain, Url from core.builtins import Bot, Image, Plain, Url

View file

@ -1,4 +1,4 @@
from core.builtins import command_prefix import math
import traceback import traceback
from config import Config from config import Config
@ -59,7 +59,7 @@ async def _(msg: Bot.MessageSession, constant: float, constant_max: float = None
result_set = await base_level_q(constant) result_set = await base_level_q(constant)
s = msg.locale.t("maimai.message.base", constant=round(constant, 1)) + "\n" s = msg.locale.t("maimai.message.base", constant=round(constant, 1)) + "\n"
for elem in result_set: for elem in result_set:
s += f"{elem[0]}\u200B. {elem[1]}{' (DX)' if elem[5] == 'DX' else ''} {elem[3]} {elem[4]} ({elem[2]})\n" s += f"{elem[0]}\u200B. {elem[1]}{msg.locale.t('message.brackets', msg='DX') if elem[5] == 'DX' else ''} {elem[3]} {elem[4]} ({elem[2]})\n"
if len(result_set) == 0: if len(result_set) == 0:
await msg.finish(msg.locale.t("maimai.message.music_not_found")) await msg.finish(msg.locale.t("maimai.message.music_not_found"))
elif len(result_set) > 200: elif len(result_set) > 200:
@ -94,7 +94,7 @@ async def _(msg: Bot.MessageSession, level: str):
result_set = await diff_level_q(level) result_set = await diff_level_q(level)
s = msg.locale.t("maimai.message.level", level=level) + "\n" s = msg.locale.t("maimai.message.level", level=level) + "\n"
for elem in result_set: for elem in result_set:
s += f"{elem[0]}\u200B. {elem[1]}{' (DX)' if elem[5] == 'DX' else ''} {elem[3]} {elem[4]} ({elem[2]})\n" s += f"{elem[0]}\u200B. {elem[1]}{msg.locale.t('message.brackets', msg='DX') if elem[5] == 'DX' else ''} {elem[3]} {elem[4]} ({elem[2]})\n"
if len(result_set) == 0: if len(result_set) == 0:
await msg.finish(msg.locale.t("maimai.message.music_not_found")) await msg.finish(msg.locale.t("maimai.message.music_not_found"))
elif len(result_set) <= 10: elif len(result_set) <= 10:
@ -130,7 +130,7 @@ async def _(msg: Bot.MessageSession, keyword: str):
else: else:
search_result = msg.locale.t("maimai.message.search", keyword=name) + "\n" search_result = msg.locale.t("maimai.message.search", keyword=name) + "\n"
for music in sorted(res, key=lambda i: int(i['id'])): for music in sorted(res, key=lambda i: int(i['id'])):
search_result += f"{music['id']}\u200B. {music['title']}{' (DX)' if music['type'] == 'DX' else ''}\n" search_result += f"{music['id']}\u200B. {music['title']}{msg.locale.t('message.brackets', msg='DX') if music['type'] == 'DX' else ''}\n"
if len(res) <= 10: if len(res) <= 10:
await msg.finish([Plain(search_result.strip())]) await msg.finish([Plain(search_result.strip())])
else: else:
@ -150,7 +150,7 @@ async def _(msg: Bot.MessageSession, sid: str):
if not music: if not music:
await msg.finish(msg.locale.t("maimai.message.music_not_found")) await msg.finish(msg.locale.t("maimai.message.music_not_found"))
title = await get_info(music, cover=False) title = await get_info(msg, music, cover=False)
alias = await get_alias(msg, sid) alias = await get_alias(msg, sid)
if len(alias) == 0: if len(alias) == 0:
await msg.finish(msg.locale.t("maimai.message.alias.alias_not_found")) await msg.finish(msg.locale.t("maimai.message.alias.alias_not_found"))
@ -162,10 +162,10 @@ async def _(msg: Bot.MessageSession, sid: str):
@mai.command('b50 [<username>] {{maimai.help.b50}}') @mai.command('b50 [<username>] {{maimai.help.b50}}')
async def _(msg: Bot.MessageSession, username: str = None): async def _(msg: Bot.MessageSession, username: str = None):
if username is None and msg.target.sender_from == "QQ": if not username and msg.target.sender_from == "QQ":
payload = {'qq': msg.session.sender, 'b50': True} payload = {'qq': msg.session.sender, 'b50': True}
else: else:
if username is None: if not username:
await msg.finish(msg.locale.t("maimai.message.no_username")) await msg.finish(msg.locale.t("maimai.message.no_username"))
payload = {'username': username, 'b50': True} payload = {'username': username, 'b50': True}
img = await generate(msg, payload) img = await generate(msg, payload)
@ -187,7 +187,7 @@ async def _(msg: Bot.MessageSession, id_or_alias: str, diff: str = None):
res = msg.locale.t("maimai.message.song.prompt") + "\n" res = msg.locale.t("maimai.message.song.prompt") + "\n"
for sid in sorted(sid_list, key=int): for sid in sorted(sid_list, key=int):
s = (await total_list.get()).by_id(sid) s = (await total_list.get()).by_id(sid)
res += f"{s['id']}\u200B. {s['title']}{' (DX)' if s['type'] == 'DX' else ''}\n" res += f"{s['id']}\u200B. {s['title']}{msg.locale.t('message.brackets', msg='DX') if s['type'] == 'DX' else ''}\n"
await msg.finish(res.strip()) await msg.finish(res.strip())
else: else:
sid = str(sid_list[0]) sid = str(sid_list[0])
@ -225,7 +225,7 @@ async def _(msg: Bot.MessageSession, id_or_alias: str, diff: str = None):
touch=chart['notes'][3], touch=chart['notes'][3],
brk=chart['notes'][4], brk=chart['notes'][4],
charter=chart['charter']) charter=chart['charter'])
await msg.finish(await get_info(music, Plain(message))) await msg.finish(await get_info(msg, music, Plain(message)))
else: else:
message = msg.locale.t( message = msg.locale.t(
"maimai.message.song", "maimai.message.song",
@ -234,7 +234,7 @@ async def _(msg: Bot.MessageSession, id_or_alias: str, diff: str = None):
bpm=music['basic_info']['bpm'], bpm=music['basic_info']['bpm'],
version=music['basic_info']['from'], version=music['basic_info']['from'],
level='/'.join((str(ds) for ds in music['ds']))) level='/'.join((str(ds) for ds in music['ds'])))
await msg.finish(await get_info(music, Plain(message))) await msg.finish(await get_info(msg, music, Plain(message)))
@mai.command('info <id_or_alias> [<username>] {{maimai.help.info}}') @mai.command('info <id_or_alias> [<username>] {{maimai.help.info}}')
@ -250,7 +250,7 @@ async def _(msg: Bot.MessageSession, id_or_alias: str, username: str = None):
res = msg.locale.t("maimai.message.song.prompt") + "\n" res = msg.locale.t("maimai.message.song.prompt") + "\n"
for sid in sorted(sid_list, key=int): for sid in sorted(sid_list, key=int):
s = (await total_list.get()).by_id(sid) s = (await total_list.get()).by_id(sid)
res += f"{s['id']}\u200B. {s['title']}{' (DX)' if s['type'] == 'DX' else ''}\n" res += f"{s['id']}\u200B. {s['title']}{msg.locale.t('message.brackets', msg='DX') if s['type'] == 'DX' else ''}\n"
await msg.finish(res.strip()) await msg.finish(res.strip())
else: else:
sid = str(sid_list[0]) sid = str(sid_list[0])
@ -268,15 +268,15 @@ async def _(msg: Bot.MessageSession, id_or_alias: str, username: str = None):
output = await get_player_score(msg, payload, sid) output = await get_player_score(msg, payload, sid)
await msg.finish(await get_info(music, Plain(output))) await msg.finish(await get_info(msg, music, Plain(output)))
@mai.command('plate <plate> [<username>] {{maimai.help.plate}}') @mai.command('plate <plate> [<username>] {{maimai.help.plate}}')
async def _(msg: Bot.MessageSession, plate: str, username: str = None): async def _(msg: Bot.MessageSession, plate: str, username: str = None):
if username is None and msg.target.sender_from == "QQ": if not username and msg.target.sender_from == "QQ":
payload = {'qq': msg.session.sender} payload = {'qq': msg.session.sender}
else: else:
if username is None: if not username:
await msg.finish(msg.locale.t("maimai.message.no_username")) await msg.finish(msg.locale.t("maimai.message.no_username"))
payload = {'username': username} payload = {'username': username}
@ -313,10 +313,10 @@ async def _(msg: Bot.MessageSession, level: str, goal: str, username: str = None
"FDX", "FDX",
"FDX+"] "FDX+"]
if username is None and msg.target.sender_from == "QQ": if not username and msg.target.sender_from == "QQ":
payload = {'qq': msg.session.sender} payload = {'qq': msg.session.sender}
else: else:
if username is None: if not username:
await msg.finish(msg.locale.t("maimai.message.no_username")) await msg.finish(msg.locale.t("maimai.message.no_username"))
payload = {'username': username} payload = {'username': username}
@ -325,10 +325,10 @@ async def _(msg: Bot.MessageSession, level: str, goal: str, username: str = None
if level_num < 8: if level_num < 8:
await msg.finish(msg.locale.t("maimai.message.process.less_than_8")) await msg.finish(msg.locale.t("maimai.message.process.less_than_8"))
else: else:
await msg.finish(msg.locale.t("maimai.message.process.error.goal_invalid")) await msg.finish(msg.locale.t("maimai.message.level_invalid"))
if goal.upper() not in goal_list: if goal.upper() not in goal_list:
await msg.finish(msg.locale.t("maimai.message.process.error.goal_invalid")) await msg.finish(msg.locale.t("maimai.message.goal_invalid"))
output, get_img = await get_level_process(msg, payload, level, goal) output, get_img = await get_level_process(msg, payload, level, goal)
@ -341,10 +341,10 @@ async def _(msg: Bot.MessageSession, level: str, goal: str, username: str = None
@mai.command('rank [<username>] {{maimai.help.rank}}') @mai.command('rank [<username>] {{maimai.help.rank}}')
async def _(msg: Bot.MessageSession, username: str = None): async def _(msg: Bot.MessageSession, username: str = None):
if username is None and msg.target.sender_from == "QQ": if not username and msg.target.sender_from == "QQ":
payload = {'qq': msg.session.sender} payload = {'qq': msg.session.sender}
else: else:
if username is None: if not username:
await msg.finish(msg.locale.t("maimai.message.no_username")) await msg.finish(msg.locale.t("maimai.message.no_username"))
payload = {'username': username} payload = {'username': username}
@ -353,10 +353,10 @@ async def _(msg: Bot.MessageSession, username: str = None):
@mai.command('scorelist <level> [<username>] {{maimai.help.scorelist}}') @mai.command('scorelist <level> [<username>] {{maimai.help.scorelist}}')
async def _(msg: Bot.MessageSession, level: str, username: str = None): async def _(msg: Bot.MessageSession, level: str, username: str = None):
if username is None and msg.target.sender_from == "QQ": if not username and msg.target.sender_from == "QQ":
payload = {'qq': msg.session.sender} payload = {'qq': msg.session.sender}
else: else:
if username is None: if not username:
await msg.finish(msg.locale.t("maimai.message.no_username")) await msg.finish(msg.locale.t("maimai.message.no_username"))
payload = {'username': username} payload = {'username': username}
@ -403,7 +403,7 @@ async def _(msg: Bot.MessageSession, dx_type: str = None):
await msg.finish(msg.locale.t("maimai.message.music_not_found")) await msg.finish(msg.locale.t("maimai.message.music_not_found"))
else: else:
music = music_data.random() music = music_data.random()
await msg.finish(await get_info(music, Plain(f"\n{'/'.join(str(ds) for ds in music.ds)}"))) await msg.finish(await get_info(msg, music, Plain(f"\n{'/'.join(str(ds) for ds in music.ds)}")))
except ValueError: except ValueError:
await msg.finish(msg.locale.t("maimai.message.random.error")) await msg.finish(msg.locale.t("maimai.message.random.error"))
@ -411,11 +411,11 @@ async def _(msg: Bot.MessageSession, dx_type: str = None):
@mai.command('random {{maimai.help.random}}') @mai.command('random {{maimai.help.random}}')
async def _(msg: Bot.MessageSession): async def _(msg: Bot.MessageSession):
music = (await total_list.get()).random() music = (await total_list.get()).random()
await msg.finish(await get_info(music, Plain(f"\n{'/'.join(str(ds) for ds in music.ds)}"))) await msg.finish(await get_info(msg, music, Plain(f"\n{'/'.join(str(ds) for ds in music.ds)}")))
@mai.command('scoreline <sid> <diff> <scoreline> {{maimai.help.scoreline}}') @mai.command('scoreline <sid> <diff> <score> {{maimai.help.scoreline}}')
async def _(msg: Bot.MessageSession, diff: str, sid: str, scoreline: float): async def _(msg: Bot.MessageSession, diff: str, sid: str, score: float):
try: try:
if not sid.isdigit(): if not sid.isdigit():
if sid[:2].lower() == "id": if sid[:2].lower() == "id":
@ -434,7 +434,7 @@ async def _(msg: Bot.MessageSession, diff: str, sid: str, scoreline: float):
bonus_score = total_score * 0.01 / brk # 奖励分 bonus_score = total_score * 0.01 / brk # 奖励分
break_2550_reduce = bonus_score * 0.25 # 一个 BREAK 2550 减少 25% 奖励分 break_2550_reduce = bonus_score * 0.25 # 一个 BREAK 2550 减少 25% 奖励分
break_2000_reduce = bonus_score * 0.6 + 500 # 一个 BREAK 2000 减少 500 基础分和 60% 奖励分 break_2000_reduce = bonus_score * 0.6 + 500 # 一个 BREAK 2000 减少 500 基础分和 60% 奖励分
reduce = 101 - scoreline # 理论值与给定完成率的差,以百分比计 reduce = 101 - score # 理论值与给定完成率的差,以百分比计
if reduce <= 0 or reduce >= 101: if reduce <= 0 or reduce >= 101:
raise ValueError raise ValueError
tap_great = "{:.2f}".format(total_score * reduce / 10000) # 一个 TAP GREAT 减少 100 分 tap_great = "{:.2f}".format(total_score * reduce / 10000) # 一个 TAP GREAT 减少 100 分
@ -443,9 +443,9 @@ async def _(msg: Bot.MessageSession, diff: str, sid: str, scoreline: float):
b2t_2550_great_prop = "{:.4f}".format(break_2550_reduce / total_score * 100) b2t_2550_great_prop = "{:.4f}".format(break_2550_reduce / total_score * 100)
b2t_2000_great = "{:.3f}".format(break_2000_reduce / 100) # 一个 TAP GREAT 减少 100 分 b2t_2000_great = "{:.3f}".format(break_2000_reduce / 100) # 一个 TAP GREAT 减少 100 分
b2t_2000_great_prop = "{:.4f}".format(break_2000_reduce / total_score * 100) b2t_2000_great_prop = "{:.4f}".format(break_2000_reduce / total_score * 100)
await msg.finish(f'''{music['title']}{' (DX)' if music['type'] == 'DX' else ''} {diff_label[diff_index]} await msg.finish(f'''{music['title']}{msg.locale.t('message.brackets', msg='DX') if music['type'] == 'DX' else ''} {diff_label[diff_index]}
{msg.locale.t('maimai.message.scoreline', {msg.locale.t('maimai.message.scoreline',
scoreline=scoreline, scoreline=score,
tap_great=tap_great, tap_great=tap_great,
tap_great_prop=tap_great_prop, tap_great_prop=tap_great_prop,
brk=brk, brk=brk,
@ -457,6 +457,44 @@ async def _(msg: Bot.MessageSession, diff: str, sid: str, scoreline: float):
await msg.finish(msg.locale.t('maimai.message.scoreline.error', prefix=command_prefix[0])) await msg.finish(msg.locale.t('maimai.message.scoreline.error', prefix=command_prefix[0]))
@mai.command('rating <base> <score> {{maimai.help.rating}}')
async def _(msg: Bot.MessageSession, base: float, score: float):
if score:
await msg.finish([Plain(max(0, computeRa(base, score)))])
def computeRa(base: float, achievement: float) -> int:
if achievement < 50:
baseRa = 7.0
elif achievement < 60:
baseRa = 8.0
elif achievement < 70:
baseRa = 9.6
elif achievement < 75:
baseRa = 11.2
elif achievement < 80:
baseRa = 12.0
elif achievement < 90:
baseRa = 13.6
elif achievement < 94:
baseRa = 15.2
elif achievement < 97:
baseRa = 16.8
elif achievement < 98:
baseRa = 20.0
elif achievement < 99:
baseRa = 20.3
elif achievement < 99.5:
baseRa = 20.8
elif achievement < 100:
baseRa = 21.1
elif achievement < 100.5:
baseRa = 21.6
else:
baseRa = 22.4
return math.floor(base * (min(100.5, achievement) / 100) * baseRa)
@mai.command('update', required_superuser=True) @mai.command('update', required_superuser=True)
async def _(msg: Bot.MessageSession): async def _(msg: Bot.MessageSession):
if await update_alias() and await update_covers(): if await update_alias() and await update_covers():
@ -465,7 +503,7 @@ async def _(msg: Bot.MessageSession):
await msg.finish(msg.locale.t("failed")) await msg.finish(msg.locale.t("failed"))
@mai.schedule(CronTrigger.from_crontab('0 */12 * * *')) @mai.schedule(CronTrigger.from_crontab('0 0 * * *'))
async def _(): async def _():
Logger.info('Updating maimai alias...') Logger.info('Updating maimai alias...')
try: try:

View file

@ -362,7 +362,6 @@ class DrawBest(object):
def computeRa(ds: float, achievement: float) -> int: def computeRa(ds: float, achievement: float) -> int:
baseRa = 22.4
if achievement < 50: if achievement < 50:
baseRa = 7.0 baseRa = 7.0
elif achievement < 60: elif achievement < 60:
@ -389,6 +388,8 @@ def computeRa(ds: float, achievement: float) -> int:
baseRa = 21.1 baseRa = 21.1
elif achievement < 100.5: elif achievement < 100.5:
baseRa = 21.6 baseRa = 21.6
else:
baseRa = 22.4
return math.floor(ds * (min(100.5, achievement) / 100) * baseRa) return math.floor(ds * (min(100.5, achievement) / 100) * baseRa)

View file

@ -1,9 +1,10 @@
import os import os
import shutil import shutil
import traceback
import ujson as json import ujson as json
from core.builtins import Plain, Image from core.builtins import Bot, Plain, Image
from core.logger import Logger from core.logger import Logger
from core.utils.cache import random_cache_path from core.utils.cache import random_cache_path
from core.utils.http import get_url, post_url, download_to_cache from core.utils.http import get_url, post_url, download_to_cache
@ -45,8 +46,8 @@ async def update_covers():
return True return True
async def get_info(music: Music, *details): async def get_info(msg: Bot.MessageSession, music: Music, *details):
info = [Plain(f"{music.id}\u200B. {music.title}{' (DX)' if music['type'] == 'DX' else ''}")] info = [Plain(f"{music.id}\u200B. {music.title}{msg.locale.t('message.brackets', msg='DX') if music['type'] == 'DX' else ''}")]
try: try:
img = f"https://www.diving-fish.com/covers/{get_cover_len5_id(music.id)}.png" img = f"https://www.diving-fish.com/covers/{get_cover_len5_id(music.id)}.png"
await get_url(img, 200, attempt=1, fmt='read') await get_url(img, 200, attempt=1, fmt='read')
@ -75,7 +76,7 @@ async def get_alias(msg, sid):
async def search_by_alias(msg, input_): async def search_by_alias(msg, input_):
result = [] result = []
input_ = input_.replace("_", " ").strip() input_ = input_.replace("_", " ").strip().lower()
res = (await total_list.get()).filter(title=input_) res = (await total_list.get()).filter(title=input_)
for s in res: for s in res:
result.append(s['id']) result.append(s['id'])
@ -88,8 +89,9 @@ async def search_by_alias(msg, input_):
with open(file_path, 'r') as file: with open(file_path, 'r') as file:
data = json.load(file) data = json.load(file)
for sid, alias in data.items(): for sid, aliases in data.items():
if input_ in alias: aliases = [alias.lower() for alias in aliases]
if input_ in aliases:
if sid in result: if sid in result:
result.remove(sid) result.remove(sid)
result.append(sid) # 此处的列表是歌曲 ID 列表 result.append(sid) # 此处的列表是歌曲 ID 列表
@ -104,7 +106,7 @@ async def get_record(msg, payload):
data=json.dumps(payload), data=json.dumps(payload),
status_code=200, status_code=200,
headers={'Content-Type': 'application/json', 'accept': '*/*'}, fmt='json') headers={'Content-Type': 'application/json', 'accept': '*/*'}, fmt='json')
except Exception as e: except ValueError as e:
if str(e).startswith('400'): if str(e).startswith('400'):
if "qq" in payload: if "qq" in payload:
await msg.finish(msg.locale.t("maimai.message.user_unbound")) await msg.finish(msg.locale.t("maimai.message.user_unbound"))
@ -113,7 +115,8 @@ async def get_record(msg, payload):
elif str(e).startswith('403'): elif str(e).startswith('403'):
await msg.finish(msg.locale.t("maimai.message.forbidden")) await msg.finish(msg.locale.t("maimai.message.forbidden"))
else: else:
raise traceback.print_exc()
return data return data
@ -124,7 +127,7 @@ async def get_plate(msg, payload):
data=json.dumps(payload), data=json.dumps(payload),
status_code=200, status_code=200,
headers={'Content-Type': 'application/json', 'accept': '*/*'}, fmt='json') headers={'Content-Type': 'application/json', 'accept': '*/*'}, fmt='json')
except Exception as e: except ValueError as e:
if str(e).startswith('400'): if str(e).startswith('400'):
if "qq" in payload: if "qq" in payload:
await msg.finish(msg.locale.t("maimai.message.user_unbound")) await msg.finish(msg.locale.t("maimai.message.user_unbound"))
@ -133,5 +136,6 @@ async def get_plate(msg, payload):
elif str(e).startswith('403'): elif str(e).startswith('403'):
await msg.finish(msg.locale.t("maimai.message.forbidden")) await msg.finish(msg.locale.t("maimai.message.forbidden"))
else: else:
raise traceback.print_exc()
return data return data

View file

@ -89,19 +89,21 @@ sync_rank = list(sync_conversion.keys()) # Sync字典的键API内显示
async def get_rank(msg, payload): async def get_rank(msg, payload):
player_data = await get_record(msg, payload) time = msg.ts2strftime(datetime.now().timestamp(), timezone=False)
username = player_data['username']
url = f"https://www.diving-fish.com/api/maimaidxprober/rating_ranking" url = f"https://www.diving-fish.com/api/maimaidxprober/rating_ranking"
rank_data = await get_url(url, 200, fmt='json') rank_data = await get_url(url, 200, fmt='json')
sorted_data = sorted(rank_data, key=lambda x: x['ra'], reverse=True) # 根据rating排名并倒序 rank_data = sorted(rank_data, key=lambda x: x['ra'], reverse=True) # 根据rating排名并倒序
player_data = await get_record(msg, payload)
username = player_data['username']
rating = 0 rating = 0
rank = None rank = None
total_rating = 0 total_rating = 0
total_rank = len(sorted_data) total_rank = len(rank_data)
for i, scoreboard in enumerate(sorted_data): for i, scoreboard in enumerate(rank_data):
if scoreboard['username'] == username: if scoreboard['username'] == username:
rank = i + 1 rank = i + 1
rating = scoreboard['ra'] rating = scoreboard['ra']
@ -112,10 +114,6 @@ async def get_rank(msg, payload):
average_rating = total_rating / total_rank average_rating = total_rating / total_rank
surpassing_rate = (total_rank - rank) / total_rank * 100 surpassing_rate = (total_rank - rank) / total_rank * 100
time = msg.ts2strftime(datetime.now().timestamp(), timezone=False)
formatted_average_rating = "{:.4f}".format(average_rating)
formatted_surpassing_rate = "{:.2f}".format(surpassing_rate)
await msg.finish(msg.locale.t('maimai.message.rank', await msg.finish(msg.locale.t('maimai.message.rank',
time=time, time=time,
@ -123,8 +121,8 @@ async def get_rank(msg, payload):
user=username, user=username,
rating=rating, rating=rating,
rank=rank, rank=rank,
average_rating=formatted_average_rating, average_rating="{:.4f}".format(average_rating),
surpassing_rate=formatted_surpassing_rate)) surpassing_rate="{:.2f}".format(surpassing_rate)))
async def get_player_score(msg, payload, input_id): async def get_player_score(msg, payload, input_id):
@ -233,7 +231,7 @@ async def get_level_process(msg, payload, process, goal):
elif goal in syncRank: elif goal in syncRank:
if verlist[record_index]['fs']: if verlist[record_index]['fs']:
self_record = syncRank[sync_rank.index(verlist[record_index]['fs'])] self_record = syncRank[sync_rank.index(verlist[record_index]['fs'])]
output += f"{s[0]}\u200B. {s[1]}{' (DX)' if s[5] == 'DX' else ''} {s[2]} {s[3]} {self_record}\n" output += f"{s[0]}\u200B. {s[1]}{msg.locale.t('message.brackets', msg='DX') if s[5] == 'DX' else ''} {s[2]} {s[3]} {self_record}\n"
if len(song_remain) > 10: # 若剩余歌曲大于10个则使用图片形式 if len(song_remain) > 10: # 若剩余歌曲大于10个则使用图片形式
get_img = True get_img = True
else: else:
@ -260,7 +258,7 @@ async def get_score_list(msg, payload, level):
output_lines = [] output_lines = []
for s in enumerate(sorted(song_list, key=lambda i: i['achievements'], reverse=True)): # 根据成绩排序 for s in enumerate(sorted(song_list, key=lambda i: i['achievements'], reverse=True)): # 根据成绩排序
music = (await total_list.get()).by_id(str(s[1]['id'])) music = (await total_list.get()).by_id(str(s[1]['id']))
output = f"{music.id}\u200B. {music.title}{' (DX)' if music.type == 'DX' else ''} {diffs[s[1]['level_index']]} {music.ds[s[1]['level_index']]} {s[1]['achievements']}%" output = f"{music.id}\u200B. {music.title}{msg.locale.t('message.brackets', msg='DX') if music.type == 'DX' else ''} {diffs[s[1]['level_index']]} {music.ds[s[1]['level_index']]} {s[1]['achievements']}%"
if s[1]["fc"] and s[1]["fs"]: if s[1]["fc"] and s[1]["fs"]:
output += f" {combo_conversion.get(s[1]['fc'], '')} {sync_conversion.get(s[1]['fs'], '')}" output += f" {combo_conversion.get(s[1]['fc'], '')} {sync_conversion.get(s[1]['fs'], '')}"
elif s[1]["fc"] or s[1]["fs"]: elif s[1]["fc"] or s[1]["fs"]:
@ -425,7 +423,7 @@ async def get_plate_process(msg, payload, plate):
elif goal == '舞舞': elif goal == '舞舞':
if verlist[record_index]['fs']: if verlist[record_index]['fs']:
self_record = syncRank[sync_rank.index(verlist[record_index]['fs'])] self_record = syncRank[sync_rank.index(verlist[record_index]['fs'])]
output += f"{s[0]}\u200B. {s[1]}{' (DX)' if s[5] == 'DX' else ''} {s[2]} {s[3]} {self_record}".strip() + '\n' output += f"{s[0]}\u200B. {s[1]}{msg.locale.t('message.brackets', msg='DX') if s[5] == 'DX' else ''} {s[2]} {s[3]} {self_record}".strip() + '\n'
if len(song_remain_difficult) > 10: # 若剩余歌曲大于10个则使用图片形式 if len(song_remain_difficult) > 10: # 若剩余歌曲大于10个则使用图片形式
get_img = True get_img = True
else: else:
@ -450,7 +448,7 @@ async def get_plate_process(msg, payload, plate):
elif goal == '舞舞': elif goal == '舞舞':
if verlist[record_index]['fs']: if verlist[record_index]['fs']:
self_record = syncRank[sync_rank.index(verlist[record_index]['fs'])] self_record = syncRank[sync_rank.index(verlist[record_index]['fs'])]
output += f"{m.id}\u200B. {m.title}{' (DX)' if m.type == 'DX' else ''} {diffs[s[1]]} {m.ds[s[1]]} {self_record}".strip( output += f"{m.id}\u200B. {m.title}{msg.locale.t('message.brackets', msg='DX') if m.type == 'DX' else ''} {diffs[s[1]]} {m.ds[s[1]]} {self_record}".strip(
) + '\n' ) + '\n'
if len(song_remain) > 10: # 若剩余歌曲大于10个则使用图片形式 if len(song_remain) > 10: # 若剩余歌曲大于10个则使用图片形式
get_img = True get_img = True

View file

@ -30,8 +30,10 @@
"maimai.message.chart_not_found": "未找到符合要求的谱面。", "maimai.message.chart_not_found": "未找到符合要求的谱面。",
"maimai.message.error.non_digital": "发生错误:歌曲 ID 必须为数字!", "maimai.message.error.non_digital": "发生错误:歌曲 ID 必须为数字!",
"maimai.message.forbidden": "此用户禁止了其他人获取数据。", "maimai.message.forbidden": "此用户禁止了其他人获取数据。",
"maimai.message.goal_invalid": "无效的目标评级,请检查输入。",
"maimai.message.info.no_record": "未游玩过此谱面", "maimai.message.info.no_record": "未游玩过此谱面",
"maimai.message.level": "以下为 ${level} 级的曲目列表:", "maimai.message.level": "以下为 ${level} 级的曲目列表:",
"maimai.message.level_invalid": "无效的等级,请检查输入。",
"maimai.message.music_not_found": "未找到符合要求的歌曲。", "maimai.message.music_not_found": "未找到符合要求的歌曲。",
"maimai.message.no_username": "请提供用户名!", "maimai.message.no_username": "请提供用户名!",
"maimai.message.plate": "您的${plate}剩余进度如下:\nBasic 剩余 ${song_remain_basic} 首,\nAdvanced 剩余 ${song_remain_advanced} 首,\nExpert 剩余 ${song_remain_expert} 首,\nMaster 剩余 ${song_remain_master} 首", "maimai.message.plate": "您的${plate}剩余进度如下:\nBasic 剩余 ${song_remain_basic} 首,\nAdvanced 剩余 ${song_remain_advanced} 首,\nExpert 剩余 ${song_remain_expert} 首,\nMaster 剩余 ${song_remain_master} 首",
@ -44,8 +46,6 @@
"maimai.message.plate.remaster": "\nRe:MASTER 剩余 ${song_remain_remaster} 首", "maimai.message.plate.remaster": "\nRe:MASTER 剩余 ${song_remain_remaster} 首",
"maimai.message.process": "您还有 ${song_remain} 首 ${process} 级曲目没有达成 ${goal}。", "maimai.message.process": "您还有 ${song_remain} 首 ${process} 级曲目没有达成 ${goal}。",
"maimai.message.process.completed": "您已达成 ${process} 级曲目全谱面 ${goal}。", "maimai.message.process.completed": "您已达成 ${process} 级曲目全谱面 ${goal}。",
"maimai.message.process.error.goal_invalid": "发生错误:无效的目标评级,请检查输入。",
"maimai.message.process.error.level_invalid": "发生错误:无效的等级,请检查输入。",
"maimai.message.process.last": "您的 ${process} 级歌曲全谱面 ${goal} 剩余曲目如下:", "maimai.message.process.last": "您的 ${process} 级歌曲全谱面 ${goal} 剩余曲目如下:",
"maimai.message.process.less_than_8": "歌曲等级必须大于 8 级。", "maimai.message.process.less_than_8": "歌曲等级必须大于 8 级。",
"maimai.message.random.error": "发生错误:随机歌曲失败,请检查输入。", "maimai.message.random.error": "发生错误:随机歌曲失败,请检查输入。",

View file

@ -18,6 +18,7 @@
"maimai.help.random": "随机一首歌曲。", "maimai.help.random": "随机一首歌曲。",
"maimai.help.random.filter": "随机一首指定条件的歌曲,输入为“*”则表示无条件。", "maimai.help.random.filter": "随机一首指定条件的歌曲,输入为“*”则表示无条件。",
"maimai.help.rank": "查看用户在查分器上的分数排行。", "maimai.help.rank": "查看用户在查分器上的分数排行。",
"maimai.help.rating": "根据定数计算 Rating。",
"maimai.help.scoreline": "查询歌曲的分数线。", "maimai.help.scoreline": "查询歌曲的分数线。",
"maimai.help.scorelist": "查看用户在对应等级的分数列表。", "maimai.help.scorelist": "查看用户在对应等级的分数列表。",
"maimai.help.search": "根据歌名(或一部分)搜索歌曲。", "maimai.help.search": "根据歌名(或一部分)搜索歌曲。",
@ -30,8 +31,10 @@
"maimai.message.chart_not_found": "未找到符合要求的谱面。", "maimai.message.chart_not_found": "未找到符合要求的谱面。",
"maimai.message.error.non_digital": "发生错误:歌曲 ID 必须为数字!", "maimai.message.error.non_digital": "发生错误:歌曲 ID 必须为数字!",
"maimai.message.forbidden": "此用户禁止了其他人获取数据。", "maimai.message.forbidden": "此用户禁止了其他人获取数据。",
"maimai.message.goal_invalid": "无效的目标评级,请检查输入。",
"maimai.message.info.no_record": "未游玩过此谱面", "maimai.message.info.no_record": "未游玩过此谱面",
"maimai.message.level": "以下为 ${level} 级的曲目列表:", "maimai.message.level": "以下为 ${level} 级的曲目列表:",
"maimai.message.level_invalid": "无效的等级,请检查输入。",
"maimai.message.music_not_found": "未找到符合要求的歌曲。", "maimai.message.music_not_found": "未找到符合要求的歌曲。",
"maimai.message.no_username": "请提供用户名!", "maimai.message.no_username": "请提供用户名!",
"maimai.message.plate": "您的${plate}剩余进度如下:\nBasic 剩余 ${song_remain_basic} 首,\nAdvanced 剩余 ${song_remain_advanced} 首,\nExpert 剩余 ${song_remain_expert} 首,\nMaster 剩余 ${song_remain_master} 首", "maimai.message.plate": "您的${plate}剩余进度如下:\nBasic 剩余 ${song_remain_basic} 首,\nAdvanced 剩余 ${song_remain_advanced} 首,\nExpert 剩余 ${song_remain_expert} 首,\nMaster 剩余 ${song_remain_master} 首",
@ -44,15 +47,13 @@
"maimai.message.plate.remaster": "\nRe:MASTER 剩余 ${song_remain_remaster} 首", "maimai.message.plate.remaster": "\nRe:MASTER 剩余 ${song_remain_remaster} 首",
"maimai.message.process": "您还有 ${song_remain} 首 ${process} 级曲目没有达成 ${goal}。", "maimai.message.process": "您还有 ${song_remain} 首 ${process} 级曲目没有达成 ${goal}。",
"maimai.message.process.completed": "您已达成 ${process} 级曲目全谱面 ${goal}。", "maimai.message.process.completed": "您已达成 ${process} 级曲目全谱面 ${goal}。",
"maimai.message.process.error.goal_invalid": "发生错误:无效的目标评级,请检查输入。",
"maimai.message.process.error.level_invalid": "发生错误:无效的等级,请检查输入。",
"maimai.message.process.last": "您的 ${process} 级歌曲全谱面 ${goal} 剩余曲目如下:", "maimai.message.process.last": "您的 ${process} 级歌曲全谱面 ${goal} 剩余曲目如下:",
"maimai.message.process.less_than_8": "歌曲等级必须大于 8 级。", "maimai.message.process.less_than_8": "歌曲等级必须大于 8 级。",
"maimai.message.random.error": "发生错误:随机歌曲失败,请检查输入。", "maimai.message.random.error": "发生错误:随机歌曲失败,请检查输入。",
"maimai.message.rank": "截至 ${time}\n查分器共有 ${total_rank} 名用户,平均分数为 ${average_rating}。\n${user} 的分数为 ${rating},排名为 #${rank}\n已经超越了 ${surpassing_rate}% 的玩家。", "maimai.message.rank": "截至 ${time}\n查分器共有 ${total_rank} 名用户,平均分数为 ${average_rating}。\n${user} 的分数为 ${rating},排名为 #${rank}\n已经超越了 ${surpassing_rate}% 的玩家。",
"maimai.message.scoreline": "分数线 ${scoreline}% 允许的最多 TAP GREAT 数量为 ${tap_great}(每个-${tap_great_prop}%\nBREAK 2550一共 ${brk} 个)等价于 ${b2t_2550_great} 个 TAP GREAT-${b2t_2550_great_prop}%\nBREAK 2000一共 ${brk} 个)等价于 ${b2t_2000_great} 个 TAP GREAT-${b2t_2000_great_prop}%", "maimai.message.scoreline": "分数线 ${scoreline}% 允许的最多 TAP GREAT 数量为 ${tap_great}(每个-${tap_great_prop}%\nBREAK 2550一共 ${brk} 个)等价于 ${b2t_2550_great} 个 TAP GREAT-${b2t_2550_great_prop}%\nBREAK 2000一共 ${brk} 个)等价于 ${b2t_2000_great} 个 TAP GREAT-${b2t_2000_great_prop}%",
"maimai.message.scoreline.error": "发生错误:计算结果失败,请检查输入。", "maimai.message.scoreline.error": "发生错误:计算结果失败,请检查输入。",
"maimai.message.scorelist": "以下为 ${user} 的 ${level} 级分数列表:", "maimai.message.scorelist": "以下为 ${user} 的 ${level} 级成绩列表:",
"maimai.message.search": "“${keyword}”的搜索结果:", "maimai.message.search": "“${keyword}”的搜索结果:",
"maimai.message.song": "艺术家:${artist}\n分类${genre}\nBPM${bpm}\n版本${version}\n难度${level}", "maimai.message.song": "艺术家:${artist}\n分类${genre}\nBPM${bpm}\n版本${version}\n难度${level}",
"maimai.message.song.dx": "${diff} ${level} (${ds})\nTAP${tap}\nHOLD${hold}\nSLIDE${slide}\nTOUCH${touch}\nBREAK${brk}\n谱师${charter}", "maimai.message.song.dx": "${diff} ${level} (${ds})\nTAP${tap}\nHOLD${hold}\nSLIDE${slide}\nTOUCH${touch}\nBREAK${brk}\n谱师${charter}",

View file

@ -18,6 +18,7 @@
"maimai.help.random": "隨機一首歌曲。", "maimai.help.random": "隨機一首歌曲。",
"maimai.help.random.filter": "隨機一首指定條件的歌曲,輸入「*」則表示無條件。", "maimai.help.random.filter": "隨機一首指定條件的歌曲,輸入「*」則表示無條件。",
"maimai.help.rank": "查看使用者在查分器上的分數排行。", "maimai.help.rank": "查看使用者在查分器上的分數排行。",
"maimai.help.rating": "依據定數計算 Rating。",
"maimai.help.scoreline": "查詢歌曲的分數線。", "maimai.help.scoreline": "查詢歌曲的分數線。",
"maimai.help.scorelist": "查看使用者在對應等級的分數列表。", "maimai.help.scorelist": "查看使用者在對應等級的分數列表。",
"maimai.help.search": "依據歌名(或一部分)搜尋歌曲。", "maimai.help.search": "依據歌名(或一部分)搜尋歌曲。",
@ -30,8 +31,10 @@
"maimai.message.chart_not_found": "未找到符合要求的譜面。", "maimai.message.chart_not_found": "未找到符合要求的譜面。",
"maimai.message.error.non_digital": "發生錯誤:歌曲 ID 必須為數字!", "maimai.message.error.non_digital": "發生錯誤:歌曲 ID 必須為數字!",
"maimai.message.forbidden": "此使用者禁止了其他人取得資料。", "maimai.message.forbidden": "此使用者禁止了其他人取得資料。",
"maimai.message.goal_invalid": "無效的目標評級,請校對輸入。",
"maimai.message.info.no_record": "未遊玩過此譜面", "maimai.message.info.no_record": "未遊玩過此譜面",
"maimai.message.level": "以下為難度 ${level} 的曲目列表:", "maimai.message.level": "以下為難度 ${level} 的曲目列表:",
"maimai.message.level_invalid": "無效的等級,請校對輸入。",
"maimai.message.music_not_found": "未找到符合要求的歌曲。", "maimai.message.music_not_found": "未找到符合要求的歌曲。",
"maimai.message.no_username": "請提供使用者名稱!", "maimai.message.no_username": "請提供使用者名稱!",
"maimai.message.plate": "您的${plate}剩餘進度如下:\nBasic 剩餘 ${song_remain_basic} 首,\nAdvanced 剩餘 ${song_remain_advanced} 首,\nExpert 剩餘 ${song_remain_expert} 首,\nMaster 剩餘 ${song_remain_master} 首", "maimai.message.plate": "您的${plate}剩餘進度如下:\nBasic 剩餘 ${song_remain_basic} 首,\nAdvanced 剩餘 ${song_remain_advanced} 首,\nExpert 剩餘 ${song_remain_expert} 首,\nMaster 剩餘 ${song_remain_master} 首",
@ -44,15 +47,13 @@
"maimai.message.plate.remaster": "Re:MASTER 剩餘 ${song_remain_remaster} 首", "maimai.message.plate.remaster": "Re:MASTER 剩餘 ${song_remain_remaster} 首",
"maimai.message.process": "您還有 ${song_remain} 首 ${process} 級曲目沒有達成 ${goal}。", "maimai.message.process": "您還有 ${song_remain} 首 ${process} 級曲目沒有達成 ${goal}。",
"maimai.message.process.completed": "您已達成 ${process} 級曲目全譜面 ${goal}。", "maimai.message.process.completed": "您已達成 ${process} 級曲目全譜面 ${goal}。",
"maimai.message.process.error.goal_invalid": "發生錯誤:無效的目標評級,請校對輸入。",
"maimai.message.process.error.level_invalid": "發生錯誤:無效的等級,請校對輸入。",
"maimai.message.process.last": "您的 ${process} 級歌曲全譜面 ${goal} 剩餘曲目如下:", "maimai.message.process.last": "您的 ${process} 級歌曲全譜面 ${goal} 剩餘曲目如下:",
"maimai.message.process.less_than_8": "歌曲等級必須大於 8 級。", "maimai.message.process.less_than_8": "歌曲等級必須大於 8 級。",
"maimai.message.random.error": "發生錯誤:無法隨機歌曲,請校對輸入。", "maimai.message.random.error": "發生錯誤:無法隨機歌曲,請校對輸入。",
"maimai.message.rank": "截至 ${time}\n查分器共有 ${total_rank} 名使用者,平均分數為 ${average_rating}\n${user} 的分數為 ${rating},排名為 #${rank}\n已經超越了 ${surpassing_rate}% 的玩家。", "maimai.message.rank": "截至 ${time}\n查分器共有 ${total_rank} 名使用者,平均分數為 ${average_rating}\n${user} 的分數為 ${rating},排名為 #${rank}\n已經超越了 ${surpassing_rate}% 的玩家。",
"maimai.message.scoreline": "分數線 ${scoreline}% 允許的最多 TAP GREAT 數量為 ${tap_great}(每個-${tap_great_prop}%)。\nBREAK 2550一共 ${brk} 個)相當於 ${b2t_2550_great} 個 TAP GREAT-${b2t_2550_great_prop}%\nBREAK 2000一共 ${brk} 個)相當於 ${b2t_2000_great} 個 TAP GREAT-${b2t_2000_great_prop}%", "maimai.message.scoreline": "分數線 ${scoreline}% 允許的最多 TAP GREAT 數量為 ${tap_great}(每個-${tap_great_prop}%)。\nBREAK 2550一共 ${brk} 個)相當於 ${b2t_2550_great} 個 TAP GREAT-${b2t_2550_great_prop}%\nBREAK 2000一共 ${brk} 個)相當於 ${b2t_2000_great} 個 TAP GREAT-${b2t_2000_great_prop}%",
"maimai.message.scoreline.error": "發生錯誤:無法計算結果,請校對輸入。", "maimai.message.scoreline.error": "發生錯誤:無法計算結果,請校對輸入。",
"maimai.message.scorelist": "以下為 ${user} 的 ${level} 級分數列表:", "maimai.message.scorelist": "以下為 ${user} 的 ${level} 級成績列表:",
"maimai.message.search": "「${keyword}」的搜尋結果:", "maimai.message.search": "「${keyword}」的搜尋結果:",
"maimai.message.song": "藝術家:${artist}\n分類${genre}\nBPM${bpm}\n版本${version}\n難度${level}", "maimai.message.song": "藝術家:${artist}\n分類${genre}\nBPM${bpm}\n版本${version}\n難度${level}",
"maimai.message.song.dx": "${diff} ${level} (${ds})\nTAP${tap}\nHOLD${hold}\nSLIDE${slide}\nTOUCH${touch}\nBREAK${brk}\n譜師${charter}", "maimai.message.song.dx": "${diff} ${level} (${ds})\nTAP${tap}\nHOLD${hold}\nSLIDE${slide}\nTOUCH${touch}\nBREAK${brk}\n譜師${charter}",

View file

@ -57,14 +57,14 @@ async def _(msg: Bot.MessageSession):
res = msg.locale.t("maimai.message.song.prompt") + "\n" res = msg.locale.t("maimai.message.song.prompt") + "\n"
for sid in sorted(sid_list, key=int): for sid in sorted(sid_list, key=int):
s = (await total_list.get()).by_id(sid) s = (await total_list.get()).by_id(sid)
res += f"{s['id']}\u200B. {s['title']}{' (DX)' if s['type'] == 'DX' else ''}\n" res += f"{s['id']}\u200B. {s['title']}{msg.locale.t('message.brackets', msg='DX') if s['type'] == 'DX' else ''}\n"
await msg.finish(res.strip()) await msg.finish(res.strip())
else: else:
music = (await total_list.get()).by_id(str(sid_list[0])) music = (await total_list.get()).by_id(str(sid_list[0]))
if not music: if not music:
await msg.finish(msg.locale.t("maimai.message.music_not_found")) await msg.finish(msg.locale.t("maimai.message.music_not_found"))
await msg.finish(await get_info(music, Plain(msg.locale.t("maimai.message.song", await msg.finish(await get_info(msg, music, Plain(msg.locale.t("maimai.message.song",
artist=music['basic_info']['artist'], artist=music['basic_info']['artist'],
genre=music['basic_info']['genre'], genre=music['basic_info']['genre'],
bpm=music['basic_info']['bpm'], bpm=music['basic_info']['bpm'],
@ -86,7 +86,7 @@ async def _(msg: Bot.MessageSession):
res = msg.locale.t("maimai.message.song.prompt") + "\n" res = msg.locale.t("maimai.message.song.prompt") + "\n"
for sid in sorted(sid_list, key=int): for sid in sorted(sid_list, key=int):
s = (await total_list.get()).by_id(sid) s = (await total_list.get()).by_id(sid)
res += f"{s['id']}\u200B. {s['title']}{' (DX)' if s['type'] == 'DX' else ''}\n" res += f"{s['id']}\u200B. {s['title']}{msg.locale.t('message.brackets', msg='DX') if s['type'] == 'DX' else ''}\n"
await msg.finish(res.strip()) await msg.finish(res.strip())
else: else:
sid = str(sid_list[0]) sid = str(sid_list[0])
@ -104,7 +104,7 @@ async def _(msg: Bot.MessageSession):
output = await get_player_score(msg, payload, sid) output = await get_player_score(msg, payload, sid)
await msg.finish(await get_info(music, Plain(output))) await msg.finish(await get_info(msg, music, Plain(output)))
@mai_regex.regex(re.compile(r"(?:id)?(\d+)\s?有什(?:么别|麼別)名", flags=re.I), desc='{maimai.help.maimai_regex.alias}') @mai_regex.regex(re.compile(r"(?:id)?(\d+)\s?有什(?:么别|麼別)名", flags=re.I), desc='{maimai.help.maimai_regex.alias}')
@ -113,7 +113,7 @@ async def _(msg: Bot.MessageSession):
music = (await total_list.get()).by_id(sid) music = (await total_list.get()).by_id(sid)
if not music: if not music:
await msg.finish(msg.locale.t("maimai.message.music_not_found")) await msg.finish(msg.locale.t("maimai.message.music_not_found"))
title = f"{music['id']}\u200B. {music['title']}{' (DX)' if music['type'] == 'DX' else ''}" title = f"{music['id']}\u200B. {music['title']}{msg.locale.t('message.brackets', msg='DX') if music['type'] == 'DX' else ''}"
alias = await get_alias(msg, sid) alias = await get_alias(msg, sid)
if len(alias) == 0: if len(alias) == 0:
await msg.finish(msg.locale.t("maimai.message.alias.alias_not_found")) await msg.finish(msg.locale.t("maimai.message.alias.alias_not_found"))
@ -145,7 +145,7 @@ async def _(msg: Bot.MessageSession):
await msg.finish(msg.locale.t("maimai.message.music_not_found")) await msg.finish(msg.locale.t("maimai.message.music_not_found"))
else: else:
music = music_data.random() music = music_data.random()
await msg.finish(await get_info(music, Plain(f"\n{'/'.join(str(ds) for ds in music.ds)}"))) await msg.finish(await get_info(msg, music, Plain(f"\n{'/'.join(str(ds) for ds in music.ds)}")))
except ValueError: except ValueError:
await msg.finish(msg.locale.t("maimai.message.random.error")) await msg.finish(msg.locale.t("maimai.message.random.error"))
@ -213,7 +213,7 @@ async def _(msg: Bot.MessageSession):
return return
if goal.upper() not in goal_list: if goal.upper() not in goal_list:
await msg.finish(msg.locale.t("maimai.message.process.error.goal_invalid")) await msg.finish(msg.locale.t("maimai.message.goal_invalid"))
output, get_img = await get_level_process(msg, payload, level, goal) output, get_img = await get_level_process(msg, payload, level, goal)

View file

@ -15,7 +15,7 @@ async def news(msg):
if web_render: if web_render:
use_local = True if web_render_local else False use_local = True if web_render_local else False
api = (web_render_local if use_local else web_render) + 'source?url=' + api api = (web_render_local if use_local else web_render) + 'source?url=' + api
html = await get_url(api, 200) html = await get_url(api, 200, request_private_ip=True)
Logger.debug(html) Logger.debug(html)
bs = BeautifulSoup(html, 'html.parser') bs = BeautifulSoup(html, 'html.parser')
results = bs.select('#threadlisttableid > tbody[id^="normalthread_"]') results = bs.select('#threadlisttableid > tbody[id^="normalthread_"]')

View file

@ -9,13 +9,13 @@ from .server import server
s = module('server', alias='s', developers=['_LittleC_', 'OasisAkari']) s = module('server', alias='s', developers=['_LittleC_', 'OasisAkari'])
@s.command('<ServerIP:Port> [-r] [-p] {{server.help}}', @s.command('<address:port> [-r] [-p] {{server.help}}',
options_desc={'-r': '{server.help.option.r}', '-p': '{server.help.option.p}'}) options_desc={'-r': '{server.help.option.r}', '-p': '{server.help.option.p}'})
async def main(msg: Bot.MessageSession): async def main(msg: Bot.MessageSession):
gather_list = [] gather_list = []
match_object = re.match(r'(.*)[\s:](.*)', msg.parsed_msg["<ServerIP:Port>"], re.M | re.I) match_object = re.match(r'(.*)[\s:](.*)', msg.parsed_msg["<address:port>"], re.M | re.I)
is_local_ip = False is_local_ip = False
server_address = msg.parsed_msg["<ServerIP:Port>"] server_address = msg.parsed_msg["<address:port>"]
if match_object: if match_object:
server_address = match_object.group(1) server_address = match_object.group(1)