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.slash_parser import slash_parser
arcaea = client.create_group("arcaea", "查询arcaea的相关信息")
arcaea = client.create_group("arcaea", "Queries about Arcaea.")
@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安卓版链接")
@arcaea.command(description="Get the latest version of game apk.")
async def download(ctx: discord.ApplicationContext):
await slash_parser(ctx, "download")
@arcaea.command(description="随机一首歌曲")
@arcaea.command(description="Random a song.")
async def random(ctx: discord.ApplicationContext):
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):
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):
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):
if ctx.options["mojiraid"] == '':
return ['MC-', 'MCPE-', 'MCD-', 'MCL-', 'REALMS-', 'WEB-', 'MCCE-']
return ['BDS-', 'MCPE-', 'MCD-', 'MCL-', 'MCLG-', 'REALMS-', 'MC-', 'WEB-']
@client.command(description="查询一个已记录在Mojira上的bug信息")
@client.command(description="Query the corresponding ticket on Mojira.")
@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)

View file

@ -3,30 +3,30 @@ import discord
from bots.discord.client import client
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):
await slash_parser(ctx, "b30")
@cytoid.command(description="查询Recent30列表")
@cytoid.command(description="Query the Recent 30 list.")
async def r30(ctx: discord.ApplicationContext):
await slash_parser(ctx, "r30")
@cytoid.command(description="查询个人信息")
@cytoid.command(description="Query user profile.")
async def profile(ctx: discord.ApplicationContext):
await slash_parser(ctx, "profile")
@cytoid.command(description="绑定用户")
@discord.option(name="username", description="用户名")
@cytoid.command(description="Bind user.")
@discord.option(name="username", description="Your Cytoid username.")
async def bind(ctx: discord.ApplicationContext, username: str):
await slash_parser(ctx, f"bind {username}")
@cytoid.command(description="取消绑定用户")
@cytoid.command(description="Unbind user.")
async def unbind(ctx: discord.ApplicationContext):
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
@client.slash_command(description="获取一个Minecraft玩家的信息")
@discord.option(name="player", description="玩家名")
async def mcplayer(ctx: discord.ApplicationContext, player: str):
await slash_parser(ctx, player)
@client.slash_command(description="Get Minecraft player information.")
@discord.option(name="username_or_uuid", description="The name or UUID of Minecraft player.")
async def mcplayer(ctx: discord.ApplicationContext, username_or_uuid: str):
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
@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):
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):
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):
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):
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"]]
@client.slash_command(description="获取一个Minecraft服务器的信息")
@discord.option(name="address", description="服务器地址", autocomplete=auto_search)
@client.slash_command(description="Get Minecraft: Java/Bedrock Edition server motd.")
@discord.option(name="address", description="The server address.", autocomplete=auto_search)
async def server(ctx: discord.ApplicationContext, address: str):
await slash_parser(ctx, address)

View file

@ -3,10 +3,10 @@ import discord
from bots.discord.client import client
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()
@discord.option(name="tweetid", description="推文ID")
async def get(ctx: discord.ApplicationContext, tweetid: str):
await slash_parser(ctx, tweetid)
@discord.option(name="tweet", description="The tweet ID or tweet link.")
async def get(ctx: discord.ApplicationContext, tweet: str):
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.desc": "Queries about Arcaea.",
"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.paid": "View the current rank of the paid packs.",
"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.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.remove": "Remove bot administrator from member.",
"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.reset": "Reset custom command alias.",
"core.help.leave": "Let the bot leave the group.",
"core.help.locale": "View bot running language.",
"core.help.locale.set": "Set bot running language.",
"core.help.locale.desc": "Control bot language.",
"core.help.locale.set": "Set the bot running languages.",
"core.help.module.disable": "Disable single/multiple module(s).",
"core.help.module.disable_all": "Disable all modules.",
"core.help.module.enable": "Enable single/multiple module(s).",
@ -30,9 +30,10 @@
"core.help.prefix.list": "View custom command prefixes.",
"core.help.prefix.remove": "Remove custom command prefix.",
"core.help.prefix.reset": "Reset custom command prefix.",
"core.help.toggle.check": "Toggles whether to display command check prompts.",
"core.help.toggle.typing": "Toggle whether to display input prompts.",
"core.help.toggle.timeoffset": "Set the time offset.",
"core.help.setup.check": "setups whether to display command check prompts.",
"core.help.setup.desc": "Set up bot actions.",
"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.whoami": "Get the ID of the user account that sent the command inside the bot.",
"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.invalid": "Invalid ID format.",
"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.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.version": "Current bot version: ${commit}",
"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.ban": "限制某人在本群使用机器人。",
"core.help.admin.desc": "一些群组管理员可使用的命令。",
"core.help.admin.list": "查看所有机器人管理员。",
"core.help.admin.remove": "取消成员的机器人管理员。",
"core.help.admin.unban": "解除对某人在本群使用机器人的限制。",
@ -11,7 +11,7 @@
"core.help.alias.remove": "移除自定义命令别名。",
"core.help.alias.reset": "重置自定义命令别名。",
"core.help.leave": "使机器人离开群组。",
"core.help.locale": "查看机器人运行语言。",
"core.help.locale.desc": "控制机器人语言。",
"core.help.locale.set": "设置机器人运行语言。",
"core.help.module.disable": "关闭一个/多个模块。",
"core.help.module.disable_all": "关闭所有模块。",
@ -30,9 +30,10 @@
"core.help.prefix.list": "查看自定义命令前缀列表。",
"core.help.prefix.remove": "移除自定义命令前缀。",
"core.help.prefix.reset": "重置自定义命令前缀。",
"core.help.toggle.check": "切换是否展示命令错字检查提示。",
"core.help.toggle.typing": "切换是否展示输入提示。",
"core.help.toggle.timeoffset": "设置时间偏移量。",
"core.help.setup.check": "切换是否展示命令错字检查提示。",
"core.help.setup.desc": "设置机器人行为。",
"core.help.setup.timeoffset": "设置时间偏移量。",
"core.help.setup.typing": "切换是否展示输入提示。",
"core.help.version": "查看机器人的版本号。",
"core.help.whoami": "获取发送命令的账号在机器人内部的 ID。",
"core.message.abuse.ban.success": "成功封禁 ${user}。",
@ -153,13 +154,13 @@
"core.message.set.help.option.success": "成功为对象设置了以下参数:${k} -> ${v}",
"core.message.set.invalid": "ID 格式错误。",
"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.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.version": "当前机器人版本号:${commit}",
"core.message.version.unknown": "无法获取版本号。此实例可能没有使用 Git 进行部署。",

View file

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

View file

@ -15,10 +15,10 @@ from database import BotDBUtil
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):
if Info.version:
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'))
ping = module('ping', base=True, desc='{core.help.ping}')
ping = module('ping', base=True)
started_time = datetime.now()
@ping.command()
@ping.command('{{core.help.ping}}')
async def _(msg: Bot.MessageSession):
checkpermisson = msg.check_super_user()
result = "Pong!"
@ -70,7 +70,7 @@ async def _(msg: Bot.MessageSession):
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([
@ -125,10 +125,10 @@ async def config_ban(msg: Bot.MessageSession):
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):
avaliable_lang = msg.locale.t("message.delimiter").join(get_available_locales())
await msg.finish(
@ -171,33 +171,33 @@ async def _(msg: Bot.MessageSession):
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):
target = BotDBUtil.SenderInfo(msg.target.sender_id)
state = target.query.disable_typing
if not state:
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:
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):
state = msg.options.get('typo_check')
if state:
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:
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):
try:
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:
raise 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)
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):
state = msg.data.switch_mute()
if state:
@ -228,16 +228,10 @@ async def _(msg: Bot.MessageSession):
await msg.finish(msg.locale.t('core.message.mute.disable'))
leave = module(
'leave',
base=True,
required_admin=True,
available_for='QQ|Group',
alias='dismiss',
desc='{core.help.leave}')
leave = module('leave', base=True, required_admin=True, available_for='QQ|Group', alias='dismiss')
@leave.command()
@leave.command('{{core.help.leave}}')
async def _(msg: Bot.MessageSession):
confirm = await msg.wait_confirm(msg.locale.t('core.message.confirm'))
if confirm:
@ -245,10 +239,10 @@ async def _(msg: Bot.MessageSession):
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):
await msg.finish(jwt.encode({
'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.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.r30": "Query the Recent 30 list of Cytoid 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.utils.http import get_url
from .dbutils import CytoidBindInfoManager

View file

@ -210,7 +210,7 @@ async def get_rating(msg: Bot.MessageSession, uid, query_type):
# shutil.rmtree(workdir)
return {'status': True, 'path': savefilename}
except Exception as e:
if str(e).startswith('404'):
if e.args == (404,):
await msg.finish(msg.locale.t("cytoid.message.user_not_found"))
traceback.print_exc()
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 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}}')
@ -18,7 +18,7 @@ async def _(msg: Bot.MessageSession):
await repo.repo(msg)
@github.handle(('user <name> {{github.help.user}}'))
@github.handle('user <name> {{github.help.user}}')
async def _(msg: Bot.MessageSession):
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.repo": "Getting GitHub repository information.",
"github.help.search": "Searching repositories on GitHub.",
"github.help.user": "Getting GitHub user or organization information.",
"github.message.repo.not_found": "The repository does not exist, please check your input.",
"github.help.repo": "Get GitHub repository information.",
"github.help.search": "Search repositories on GitHub.",
"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.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.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.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."
}

View file

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

View file

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

View file

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

View file

@ -1,4 +1,4 @@
from core.builtins import command_prefix
import math
import traceback
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)
s = msg.locale.t("maimai.message.base", constant=round(constant, 1)) + "\n"
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:
await msg.finish(msg.locale.t("maimai.message.music_not_found"))
elif len(result_set) > 200:
@ -94,7 +94,7 @@ async def _(msg: Bot.MessageSession, level: str):
result_set = await diff_level_q(level)
s = msg.locale.t("maimai.message.level", level=level) + "\n"
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:
await msg.finish(msg.locale.t("maimai.message.music_not_found"))
elif len(result_set) <= 10:
@ -130,7 +130,7 @@ async def _(msg: Bot.MessageSession, keyword: str):
else:
search_result = msg.locale.t("maimai.message.search", keyword=name) + "\n"
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:
await msg.finish([Plain(search_result.strip())])
else:
@ -150,7 +150,7 @@ async def _(msg: Bot.MessageSession, sid: str):
if not music:
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)
if len(alias) == 0:
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}}')
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}
else:
if username is None:
if not username:
await msg.finish(msg.locale.t("maimai.message.no_username"))
payload = {'username': username, 'b50': True}
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"
for sid in sorted(sid_list, key=int):
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())
else:
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],
brk=chart['notes'][4],
charter=chart['charter'])
await msg.finish(await get_info(music, Plain(message)))
await msg.finish(await get_info(msg, music, Plain(message)))
else:
message = msg.locale.t(
"maimai.message.song",
@ -234,7 +234,7 @@ async def _(msg: Bot.MessageSession, id_or_alias: str, diff: str = None):
bpm=music['basic_info']['bpm'],
version=music['basic_info']['from'],
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}}')
@ -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"
for sid in sorted(sid_list, key=int):
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())
else:
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)
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}}')
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}
else:
if username is None:
if not username:
await msg.finish(msg.locale.t("maimai.message.no_username"))
payload = {'username': username}
@ -313,10 +313,10 @@ async def _(msg: Bot.MessageSession, level: str, goal: str, username: str = None
"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}
else:
if username is None:
if not username:
await msg.finish(msg.locale.t("maimai.message.no_username"))
payload = {'username': username}
@ -325,10 +325,10 @@ async def _(msg: Bot.MessageSession, level: str, goal: str, username: str = None
if level_num < 8:
await msg.finish(msg.locale.t("maimai.message.process.less_than_8"))
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:
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)
@ -341,10 +341,10 @@ async def _(msg: Bot.MessageSession, level: str, goal: str, username: str = None
@mai.command('rank [<username>] {{maimai.help.rank}}')
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}
else:
if username is None:
if not username:
await msg.finish(msg.locale.t("maimai.message.no_username"))
payload = {'username': username}
@ -353,10 +353,10 @@ async def _(msg: Bot.MessageSession, username: str = None):
@mai.command('scorelist <level> [<username>] {{maimai.help.scorelist}}')
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}
else:
if username is None:
if not username:
await msg.finish(msg.locale.t("maimai.message.no_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"))
else:
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:
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}}')
async def _(msg: Bot.MessageSession):
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}}')
async def _(msg: Bot.MessageSession, diff: str, sid: str, scoreline: float):
@mai.command('scoreline <sid> <diff> <score> {{maimai.help.scoreline}}')
async def _(msg: Bot.MessageSession, diff: str, sid: str, score: float):
try:
if not sid.isdigit():
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 # 奖励分
break_2550_reduce = bonus_score * 0.25 # 一个 BREAK 2550 减少 25% 奖励分
break_2000_reduce = bonus_score * 0.6 + 500 # 一个 BREAK 2000 减少 500 基础分和 60% 奖励分
reduce = 101 - scoreline # 理论值与给定完成率的差,以百分比计
reduce = 101 - score # 理论值与给定完成率的差,以百分比计
if reduce <= 0 or reduce >= 101:
raise ValueError
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_2000_great = "{:.3f}".format(break_2000_reduce / 100) # 一个 TAP GREAT 减少 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',
scoreline=scoreline,
scoreline=score,
tap_great=tap_great,
tap_great_prop=tap_great_prop,
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]))
@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)
async def _(msg: Bot.MessageSession):
if await update_alias() and await update_covers():
@ -465,7 +503,7 @@ async def _(msg: Bot.MessageSession):
await msg.finish(msg.locale.t("failed"))
@mai.schedule(CronTrigger.from_crontab('0 */12 * * *'))
@mai.schedule(CronTrigger.from_crontab('0 0 * * *'))
async def _():
Logger.info('Updating maimai alias...')
try:

View file

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

View file

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

View file

@ -89,19 +89,21 @@ sync_rank = list(sync_conversion.keys()) # Sync字典的键API内显示
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"
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
rank = None
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:
rank = i + 1
rating = scoreboard['ra']
@ -112,10 +114,6 @@ async def get_rank(msg, payload):
average_rating = total_rating / total_rank
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',
time=time,
@ -123,8 +121,8 @@ async def get_rank(msg, payload):
user=username,
rating=rating,
rank=rank,
average_rating=formatted_average_rating,
surpassing_rate=formatted_surpassing_rate))
average_rating="{:.4f}".format(average_rating),
surpassing_rate="{:.2f}".format(surpassing_rate)))
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:
if 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个则使用图片形式
get_img = True
else:
@ -260,7 +258,7 @@ async def get_score_list(msg, payload, level):
output_lines = []
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']))
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"]:
output += f" {combo_conversion.get(s[1]['fc'], '')} {sync_conversion.get(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 == '舞舞':
if 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个则使用图片形式
get_img = True
else:
@ -450,7 +448,7 @@ async def get_plate_process(msg, payload, plate):
elif goal == '舞舞':
if 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'
if len(song_remain) > 10: # 若剩余歌曲大于10个则使用图片形式
get_img = True

View file

@ -30,8 +30,10 @@
"maimai.message.chart_not_found": "未找到符合要求的谱面。",
"maimai.message.error.non_digital": "发生错误:歌曲 ID 必须为数字!",
"maimai.message.forbidden": "此用户禁止了其他人获取数据。",
"maimai.message.goal_invalid": "无效的目标评级,请检查输入。",
"maimai.message.info.no_record": "未游玩过此谱面",
"maimai.message.level": "以下为 ${level} 级的曲目列表:",
"maimai.message.level_invalid": "无效的等级,请检查输入。",
"maimai.message.music_not_found": "未找到符合要求的歌曲。",
"maimai.message.no_username": "请提供用户名!",
"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.process": "您还有 ${song_remain} 首 ${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.less_than_8": "歌曲等级必须大于 8 级。",
"maimai.message.random.error": "发生错误:随机歌曲失败,请检查输入。",

View file

@ -18,6 +18,7 @@
"maimai.help.random": "随机一首歌曲。",
"maimai.help.random.filter": "随机一首指定条件的歌曲,输入为“*”则表示无条件。",
"maimai.help.rank": "查看用户在查分器上的分数排行。",
"maimai.help.rating": "根据定数计算 Rating。",
"maimai.help.scoreline": "查询歌曲的分数线。",
"maimai.help.scorelist": "查看用户在对应等级的分数列表。",
"maimai.help.search": "根据歌名(或一部分)搜索歌曲。",
@ -30,8 +31,10 @@
"maimai.message.chart_not_found": "未找到符合要求的谱面。",
"maimai.message.error.non_digital": "发生错误:歌曲 ID 必须为数字!",
"maimai.message.forbidden": "此用户禁止了其他人获取数据。",
"maimai.message.goal_invalid": "无效的目标评级,请检查输入。",
"maimai.message.info.no_record": "未游玩过此谱面",
"maimai.message.level": "以下为 ${level} 级的曲目列表:",
"maimai.message.level_invalid": "无效的等级,请检查输入。",
"maimai.message.music_not_found": "未找到符合要求的歌曲。",
"maimai.message.no_username": "请提供用户名!",
"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.process": "您还有 ${song_remain} 首 ${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.less_than_8": "歌曲等级必须大于 8 级。",
"maimai.message.random.error": "发生错误:随机歌曲失败,请检查输入。",
"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.error": "发生错误:计算结果失败,请检查输入。",
"maimai.message.scorelist": "以下为 ${user} 的 ${level} 级分数列表:",
"maimai.message.scorelist": "以下为 ${user} 的 ${level} 级成绩列表:",
"maimai.message.search": "“${keyword}”的搜索结果:",
"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}",

View file

@ -18,6 +18,7 @@
"maimai.help.random": "隨機一首歌曲。",
"maimai.help.random.filter": "隨機一首指定條件的歌曲,輸入「*」則表示無條件。",
"maimai.help.rank": "查看使用者在查分器上的分數排行。",
"maimai.help.rating": "依據定數計算 Rating。",
"maimai.help.scoreline": "查詢歌曲的分數線。",
"maimai.help.scorelist": "查看使用者在對應等級的分數列表。",
"maimai.help.search": "依據歌名(或一部分)搜尋歌曲。",
@ -30,8 +31,10 @@
"maimai.message.chart_not_found": "未找到符合要求的譜面。",
"maimai.message.error.non_digital": "發生錯誤:歌曲 ID 必須為數字!",
"maimai.message.forbidden": "此使用者禁止了其他人取得資料。",
"maimai.message.goal_invalid": "無效的目標評級,請校對輸入。",
"maimai.message.info.no_record": "未遊玩過此譜面",
"maimai.message.level": "以下為難度 ${level} 的曲目列表:",
"maimai.message.level_invalid": "無效的等級,請校對輸入。",
"maimai.message.music_not_found": "未找到符合要求的歌曲。",
"maimai.message.no_username": "請提供使用者名稱!",
"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.process": "您還有 ${song_remain} 首 ${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.less_than_8": "歌曲等級必須大於 8 級。",
"maimai.message.random.error": "發生錯誤:無法隨機歌曲,請校對輸入。",
"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.error": "發生錯誤:無法計算結果,請校對輸入。",
"maimai.message.scorelist": "以下為 ${user} 的 ${level} 級分數列表:",
"maimai.message.scorelist": "以下為 ${user} 的 ${level} 級成績列表:",
"maimai.message.search": "「${keyword}」的搜尋結果:",
"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}",

View file

@ -57,14 +57,14 @@ async def _(msg: Bot.MessageSession):
res = msg.locale.t("maimai.message.song.prompt") + "\n"
for sid in sorted(sid_list, key=int):
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())
else:
music = (await total_list.get()).by_id(str(sid_list[0]))
if not music:
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'],
genre=music['basic_info']['genre'],
bpm=music['basic_info']['bpm'],
@ -86,7 +86,7 @@ async def _(msg: Bot.MessageSession):
res = msg.locale.t("maimai.message.song.prompt") + "\n"
for sid in sorted(sid_list, key=int):
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())
else:
sid = str(sid_list[0])
@ -104,7 +104,7 @@ async def _(msg: Bot.MessageSession):
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}')
@ -113,7 +113,7 @@ async def _(msg: Bot.MessageSession):
music = (await total_list.get()).by_id(sid)
if not music:
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)
if len(alias) == 0:
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"))
else:
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:
await msg.finish(msg.locale.t("maimai.message.random.error"))
@ -213,7 +213,7 @@ async def _(msg: Bot.MessageSession):
return
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)

View file

@ -15,7 +15,7 @@ async def news(msg):
if web_render:
use_local = True if web_render_local else False
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)
bs = BeautifulSoup(html, 'html.parser')
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.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}'})
async def main(msg: Bot.MessageSession):
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
server_address = msg.parsed_msg["<ServerIP:Port>"]
server_address = msg.parsed_msg["<address:port>"]
if match_object:
server_address = match_object.group(1)