Archived
1
0
Fork 0

Merge branch 'Teahouse-Studios:master' into master

This commit is contained in:
ZoruaFox 2023-12-03 20:31:39 +08:00 committed by GitHub
commit 61b3f95ad9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 358 additions and 311 deletions

View file

@ -20,7 +20,7 @@
"error.message.report": "The following error occurred while executing \"${module}\": ",
"error.message.timeout": "An error occurred: Message sending timed out. Please retry the command later or wait for the result to be returned.",
"error.module.helpdoc.invalid": "\"${module}\" module provided invalid help information. Please contact the developers to solve this issue.",
"error.module.unbound": "\"${module}\" module is unbound with any commands and doesn't have the description. Pease contact the developers to solve this issue.",
"error.module.unbound": "\"${module}\" module is unbound with any commands and doesn't have the description. Please contact the developers to solve this issue.",
"error.module.unloaded": "\"${module}\" module failed to load. Please contact the developers to resolve this issue.",
"error.prompt": "An error occurred: ${error_msg}\nReport this issue: ",
"error.prompt.noreport": "An error occurred while executing the command:\n${err_msg}\nThis error is not caused by the bot (e.g. the API request went wrong) and thus should not be reported to developers.",

View file

@ -1,13 +1,16 @@
import os
from PIL import Image, ImageDraw, ImageFont
import urllib.parse
from config import CFG
from core.builtins import Bot, Image, Plain
from core.builtins import Bot, Image as Img, Plain
from core.component import module
from core.logger import Logger
from core.utils.cache import random_cache_path
from core.utils.http import get_url
assets_path = os.path.abspath('./assets/arcaea')
web_render = CFG.get_url('web_render')
web_render_local = CFG.get_url('web_render_local')
@ -23,7 +26,7 @@ class WithErrCode(Exception):
@arc.command('b30')
async def _(msg: Bot.MessageSession):
await msg.send_message([Plain(msg.locale.t("arcaea.message.sb616")),
Image(os.path.abspath('./assets/arcaea/noc.jpg'))])
Img(os.path.abspath('./assets/arcaea/noc.jpg'))])
@arc.command('download {{arcaea.help.download}}')
@ -58,7 +61,7 @@ async def _(msg: Bot.MessageSession, use_local=True):
image = f'{assets_path}/jacket/{value["song_id"]}.jpg'
result = [Plain(value["title"]["en"])]
if os.path.exists(image):
result.append(Image(path=image))
result.append(Img(path=image))
await msg.finish(result)
else:
await msg.finish(msg.locale.t("arcaea.message.get_failed"))
@ -87,3 +90,81 @@ async def _(msg: Bot.MessageSession, use_local=True):
await msg.finish('\n'.join(r))
else:
await msg.finish(msg.locale.t("arcaea.message.get_failed"))
p = module('ptt',
developers=['OasisAkari'])
@p.handle('<potential> {{ptt.help}}')
async def pttimg(msg: Bot.MessageSession):
ptt = msg.parsed_msg['<potential>']
# ptt
if ptt == '--':
ptt = -1
else:
try:
ptt = float(ptt)
except ValueError:
await msg.finish(msg.locale.t('ptt.message.error.invalid'))
if ptt >= 13.00:
pttimg = 7
elif ptt >= 12.50:
pttimg = 6
elif ptt >= 12.00:
pttimg = 5
elif ptt >= 11.00:
pttimg = 4
elif ptt >= 10.00:
pttimg = 3
elif ptt >= 7.00:
pttimg = 2
elif ptt >= 3.50:
pttimg = 1
elif ptt >= 0:
pttimg = 0
else:
pttimg = 'off'
pttimgr = Image.open(f'{assets_path}/ptt/rating_{str(pttimg)}.png')
ptttext = Image.new("RGBA", (119, 119))
font1 = ImageFont.truetype(os.path.abspath(f'{assets_path}/Fonts/Exo-SemiBold.ttf'), 49)
font2 = ImageFont.truetype(os.path.abspath(f'{assets_path}/Fonts/Exo-SemiBold.ttf'), 33)
if ptt >= 0 and ptt <= 99.99:
rawptt = str(ptt).split('.')
if len(rawptt) < 2:
ptt1 = rawptt[0]
ptt2 = '00'
else:
ptt1 = rawptt[0]
ptt2 = rawptt[1][:2]
if len(ptt2) < 2:
ptt2 += '0'
ptttext_width, ptttext_height = ptttext.size
font1_width, font1_height = font1.getsize(ptt1 + '.')
font2_width, font2_height = font2.getsize(ptt2)
pttimg = Image.new("RGBA", (font1_width + font2_width + 6, font1_height + 6))
drawptt = ImageDraw.Draw(pttimg)
stroke_color = '#52495d'
if int(ptt1) >= 13:
stroke_color = '#81122F'
drawptt.text((0, 0), ptt1 + '.', 'white', font=font1, stroke_width=3, stroke_fill=stroke_color)
drawptt.text((font1_width, int(int(font1_height) - int(font2_height))), ptt2, 'white', font=font2,
stroke_width=3, stroke_fill=stroke_color)
elif ptt == -1:
ptt = '--'
ptttext_width, ptttext_height = ptttext.size
font1_width, font1_height = font1.getsize(ptt)
pttimg = Image.new("RGBA", (font1_width + 6, font1_height + 6))
drawptt = ImageDraw.Draw(pttimg)
drawptt.text((0, 0), ptt, 'white', font=font1, stroke_width=3, stroke_fill='#52495d')
else:
return await msg.finish(msg.locale.t('ptt.message.error.invalid'))
pttimg_width, pttimg_height = pttimg.size
ptttext.alpha_composite(pttimg,
(int((ptttext_width - pttimg_width) / 2), int((ptttext_height - pttimg_height) / 2) - 11))
ptttext = ptttext.resize(pttimgr.size)
pttimgr.alpha_composite(ptttext, (0, 0))
savepath = random_cache_path() + '.png'
pttimgr.save(savepath)
await msg.finish([Img(path=savepath)])

View file

@ -5,6 +5,8 @@
"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}",
"arcaea.message.get_failed": "Failed to fetch.",
"arcaea.message.sb616": "According to Arcaea TOS 3.2.6, this command cannot be used.\nYou also agree not to do any of the following:\n... 6. collect any information through “harvesting” or “scraping” about the service or regarding any user, including yourself, who uses the Services;\nhttps://arcaea.lowiro.com/en/terms_of_service",
"arcaea.message.get_failed": "Failed to fetch."
"ptt.help": "Generate a Potential image of Arcaea.",
"ptt.message.error.invalid": "An error occurred: Potential must be a number greater than 0.00 and less than 99.99."
}

View file

@ -5,6 +5,8 @@
"arcaea.help.rank.free": "查看当前免费包游玩排行。",
"arcaea.help.rank.paid": "查看当前付费包游玩排行。",
"arcaea.message.download": "目前的最新版本为 ${version}。\n下载地址${url}",
"arcaea.message.get_failed": "获取失败。",
"arcaea.message.sb616": "根据 Arcaea TOS 3.2.6 规定,无法使用该命令。\nYou also agree not to do any of the following:\n... 6. collect any information through “harvesting” or “scraping” about the service or regarding any user, including yourself, who uses the Services;\nhttps://arcaea.lowiro.com/zh/terms_of_service",
"arcaea.message.get_failed": "获取失败。"
"ptt.help": "生成一张 Arcaea 潜力值图片。",
"ptt.message.error.invalid": "发生错误:潜力值必须为 ≥0.00 且 ≤99.99 的数字。"
}

View file

@ -5,6 +5,8 @@
"arcaea.help.rank.free": "檢視目前免費包遊玩排行。",
"arcaea.help.rank.paid": "檢視目前付費包遊玩排行。",
"arcaea.message.download": "目前的最新版本為 ${version}。\n下載網址${url}",
"arcaea.message.get_failed": "取得失敗。",
"arcaea.message.sb616": "依據 Arcaea TOS 3.2.6 規定,無法使用此指令。\nYou also agree not to do any of the following:\n... 6. collect any information through “harvesting” or “scraping” about the service or regarding any user, including yourself, who uses the Services;\nhttps://arcaea.lowiro.com/zh/terms_of_service",
"arcaea.message.get_failed": "取得失敗。"
"ptt.help": "產生一張 Arcaea 潛力值圖片。",
"ptt.message.error.invalid": "發生錯誤:潛力值必須為 ≥0.00 且 ≤99.99 的數字。"
}

View file

@ -17,94 +17,92 @@ if Config('enable_langsmith'):
os.environ['LANGCHAIN_PROJECT'] = Config('langsmith_project')
os.environ['LANGCHAIN_API_KEY'] = Config('langsmith_api_key')
from langchain.callbacks import get_openai_callback # noqa: E402
from .agent import agent_executor # noqa: E402
from .formatting import generate_latex, generate_code_snippet # noqa: E402
from langchain.callbacks import get_openai_callback # noqa: E402
from .agent import agent_executor # noqa: E402
from .formatting import generate_latex, generate_code_snippet # noqa: E402
a = module('ask', developers=['Dianliang233'], desc='{ask.help.desc}')
a = module('ask', developers=['Dianliang233'], desc='{ask.help.desc}')
@a.command('[--verbose] <question> {{ask.help}}')
@a.regex(r'^(?:question||问|問)[\:]\s?(.+?)[?]$', flags=re.I, desc='{ask.help.regex}')
async def _(msg: Bot.MessageSession):
is_superuser = msg.check_super_user()
if not Config('openai_api_key'):
raise ConfigError(msg.locale.t('error.config.secret.not_found'))
if not is_superuser and msg.data.petal <= 0: # refuse
await msg.finish(msg.locale.t('core.message.petal.no_petals') + Config('issue_url'))
@a.command('[--verbose] <question> {{ask.help}}')
@a.regex(r'^(?:question||问|問)[\:]\s?(.+?)[?]$', flags=re.I, desc='{ask.help.regex}')
async def _(msg: Bot.MessageSession):
is_superuser = msg.check_super_user()
if not Config('openai_api_key'):
raise ConfigError(msg.locale.t('error.config.secret.not_found'))
if not is_superuser and msg.data.petal <= 0: # refuse
await msg.finish(msg.locale.t('core.message.petal.no_petals') + Config('issue_url'))
qc = CoolDown('call_openai', msg)
c = qc.check(60)
if c == 0 or msg.target.target_from == 'TEST|Console' or is_superuser:
if hasattr(msg, 'parsed_msg'):
question = msg.parsed_msg['<question>']
else:
question = msg.matched_msg[0]
if await check_bool(question):
rickroll(msg)
with get_openai_callback() as cb:
res = await agent_executor.arun(question)
tokens = cb.total_tokens
if not is_superuser:
petal = await count_petal(tokens)
msg.data.modify_petal(-petal)
else:
petal = 0
qc = CoolDown('call_openai', msg)
c = qc.check(60)
if c == 0 or msg.target.target_from == 'TEST|Console' or is_superuser:
if hasattr(msg, 'parsed_msg'):
question = msg.parsed_msg['<question>']
else:
question = msg.matched_msg[0]
if await check_bool(question):
rickroll(msg)
with get_openai_callback() as cb:
res = await agent_executor.arun(question)
tokens = cb.total_tokens
if not is_superuser:
petal = await count_petal(tokens)
msg.data.modify_petal(-petal)
else:
petal = 0
blocks = parse_markdown(res)
blocks = parse_markdown(res)
chain = []
for block in blocks:
if block['type'] == 'text':
chain.append(Plain(block['content']))
elif block['type'] == 'latex':
content = await generate_latex(block['content'])
try:
img = PILImage.open(io.BytesIO(content))
chain.append(Image(img))
except Exception as e:
chain.append(Plain(msg.locale.t('ask.message.text2img.error', text=content)))
elif block['type'] == 'code':
content = block['content']['code']
try:
chain.append(Image(PILImage.open(io.BytesIO(await generate_code_snippet(content,
block['content']['language'])))))
except Exception as e:
chain.append(Plain(msg.locale.t('ask.message.text2img.error', text=content)))
chain = []
for block in blocks:
if block['type'] == 'text':
chain.append(Plain(block['content']))
elif block['type'] == 'latex':
content = await generate_latex(block['content'])
try:
img = PILImage.open(io.BytesIO(content))
chain.append(Image(img))
except Exception as e:
chain.append(Plain(msg.locale.t('ask.message.text2img.error', text=content)))
elif block['type'] == 'code':
content = block['content']['code']
try:
chain.append(Image(PILImage.open(io.BytesIO(await generate_code_snippet(content,
block['content']['language'])))))
except Exception as e:
chain.append(Plain(msg.locale.t('ask.message.text2img.error', text=content)))
if await check_bool(res):
if await check_bool(res):
if petal != 0:
await msg.send_message(msg.locale.t('petal.message.cost', count=petal))
rickroll(msg)
if petal != 0:
await msg.send_message(msg.locale.t('petal.message.cost', count=petal))
rickroll(msg)
if petal != 0:
chain.append(Plain(msg.locale.t('petal.message.cost', count=petal)))
await msg.send_message(chain)
chain.append(Plain(msg.locale.t('petal.message.cost', count=petal)))
await msg.send_message(chain)
if msg.target.target_from != 'TEST|Console' and not is_superuser:
qc.reset()
else:
await msg.finish(msg.locale.t('message.cooldown', time=int(c), cd_time='60'))
def parse_markdown(md: str):
regex = r'(```[\s\S]*?\n```|\$[\s\S]*?\$|[^\n]+)'
blocks = []
for match in re.finditer(regex, md):
content = match.group(1)
print(content)
if content.startswith('```'):
block = 'code'
try:
language, code = re.match(r'```(.*)\n([\s\S]*?)\n```', content).groups()
except AttributeError:
raise ValueError('Code block is missing language or code')
content = {'language': language, 'code': code}
elif content.startswith('$'):
block = 'latex'
content = content[1:-1].strip()
if msg.target.target_from != 'TEST|Console' and not is_superuser:
qc.reset()
else:
block = 'text'
blocks.append({'type': block, 'content': content})
await msg.finish(msg.locale.t('message.cooldown', time=int(c), cd_time='60'))
return blocks
def parse_markdown(md: str):
regex = r'(```[\s\S]*?\n```|\$[\s\S]*?\$|[^\n]+)'
blocks = []
for match in re.finditer(regex, md):
content = match.group(1)
print(content)
if content.startswith('```'):
block = 'code'
try:
language, code = re.match(r'```(.*)\n([\s\S]*?)\n```', content).groups()
except AttributeError:
raise ValueError('Code block is missing language or code')
content = {'language': language, 'code': code}
elif content.startswith('$'):
block = 'latex'
content = content[1:-1].strip()
else:
block = 'text'
blocks.append({'type': block, 'content': content})
return blocks

View file

@ -19,6 +19,7 @@
"core.help.module.help.detail": "View details of a module.",
"core.help.module.help.legacy": "View help list. (Legacy)",
"core.help.module.list": "View all available modules.",
"core.help.module.list.legacy": "View all available modules. (Legacy)",
"core.help.mute": "Make the bot stop sending message.",
"core.help.option.module.g": "Perform global operations of the channels.",
"core.help.petal": "Get the number of petals in the current group.",
@ -43,7 +44,7 @@
"core.message.admin.ban.already": "This member has been banned from using bot.",
"core.message.admin.ban.not_yet": "This member has not been banned from using bot.",
"core.message.admin.ban.self": "You cannot do this for yourself!",
"core.message.superuser.invalid": "Invalid ID format. The format should be \"${target}|<User ID>\".",
"core.message.admin.invalid": "Invalid ID format. The format should be \"${target}|<User ID>\". Use \"${prefix}whoami\" to view user ID.",
"core.message.admin.list": "Bot administrators manually set in the current group: ",
"core.message.admin.list.none": "There are currently no manual bot administrators.",
"core.message.admin.remove.success": "Success: Removed ${user} from bot administrator.",
@ -147,7 +148,7 @@
"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.admin.invalid": "Invalid ID format. Use \"${prefix}whoami\" to view 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.typing.disable": "Input prompt disabled.",

View file

@ -19,6 +19,7 @@
"core.help.module.help.detail": "查看一个模块的详细信息。",
"core.help.module.help.legacy": "查看帮助列表。(旧版)",
"core.help.module.list": "查看所有可用模块。",
"core.help.module.list.legacy": "查看所有可用模块。(旧版)",
"core.help.mute": "使机器人停止发言。",
"core.help.option.module.g": "对频道进行全局操作。",
"core.help.petal": "获取当前群组的花瓣数。",
@ -43,7 +44,7 @@
"core.message.admin.ban.already": "此成员已被设置禁止使用机器人。",
"core.message.admin.ban.not_yet": "此成员没有被设置禁止使用机器人。",
"core.message.admin.ban.self": "你不可以对自己进行此操作!",
"core.message.superuser.invalid": "ID 格式错误,格式应为“${target}|<用户 ID>”。",
"core.message.admin.invalid": "ID 格式错误,格式应为“${target}|<用户 ID>”,请使用“${prefix}whoami”查看用户 ID。",
"core.message.admin.list": "当前在群内手动设置的机器人管理员:\n",
"core.message.admin.list.none": "当前没有手动设置的机器人管理员。",
"core.message.admin.remove.success": "成功:已将 ${user} 移出机器人管理员。",
@ -147,7 +148,7 @@
"core.message.set.help.option.success": "成功为对象设置了以下参数:${k} -> ${v}",
"core.message.set.invalid": "ID 格式错误。",
"core.message.set.module.success": "成功为对象配置了以下模块:",
"core.message.admin.invalid": "ID 格式错误,请使用“${prefix}whoami”查看用户 ID。",
"core.message.superuser.invalid": "ID 格式错误,格式应为“${target}|<用户 ID>”。",
"core.message.toggle.check.disable": "已关闭错字检查提示。",
"core.message.toggle.check.enable": "已开启错字检查提示。",
"core.message.toggle.typing.disable": "已关闭输入提示。",

View file

@ -19,6 +19,7 @@
"core.help.module.help.detail": "檢視一個模組的詳細資訊。",
"core.help.module.help.legacy": "檢視說明列表。(舊版)",
"core.help.module.list": "檢視所有可用模組。",
"core.help.module.list.legacy": "檢視所有可用模組。(舊版)",
"core.help.mute": "使機器人停止發言。",
"core.help.option.module.g": "對頻道進行全域操作。",
"core.help.petal": "取得目前群組的花瓣數。",
@ -43,7 +44,7 @@
"core.message.admin.ban.already": "此成員已被禁止使用機器人。",
"core.message.admin.ban.not_yet": "此成員沒有被禁止使用機器人。",
"core.message.admin.ban.self": "你不可以對自己進行此操作!",
"core.message.superuser.invalid": "ID 格式錯誤,格式應為「${target}|<使用者 ID>」。",
"core.message.admin.invalid": "ID 格式錯誤,格式應為「${target}|<使用者 ID>」,請使用「${prefix}whoami」指令檢視使用者 ID。",
"core.message.admin.list": "目前在群組內手動設定的機器人管理員:\n",
"core.message.admin.list.none": "目前沒有手動設定的機器人管理員。",
"core.message.admin.remove.success": "成功:已將 ${user} 移出機器人管理員。",
@ -147,7 +148,7 @@
"core.message.set.help.option.success": "成功為物件設定了以下參數:${k} -> ${v}",
"core.message.set.invalid": "ID 格式錯誤。",
"core.message.set.module.success": "成功為物件配置了以下模組:",
"core.message.admin.invalid": "ID 格式錯誤,請使用「${prefix}whoami」指令檢視使用者 ID。",
"core.message.superuser.invalid": "ID 格式錯誤,格式應為「${target}|<使用者 ID>」",
"core.message.toggle.check.disable": "已停用指令錯誤檢查提醒。",
"core.message.toggle.check.enable": "已啟用指令錯誤檢查提醒。",
"core.message.toggle.typing.disable": "已停用輸入提醒。",

View file

@ -36,7 +36,7 @@ m = module('module',
async def _(msg: Bot.MessageSession):
if msg.parsed_msg.get('list', False):
legacy = False
if 'legacy' in msg.parsed_msg:
if msg.parsed_msg.get('legacy', False):
legacy = True
await modules_help(msg, legacy)
await config_modules(msg)
@ -55,7 +55,7 @@ async def _(msg: Bot.MessageSession):
async def _(msg: Bot.MessageSession):
if msg.parsed_msg.get('list', False):
legacy = False
if 'legacy' in msg.parsed_msg:
if msg.parsed_msg.get('legacy', False):
legacy = True
await modules_help(msg, legacy)
await config_modules(msg)
@ -281,7 +281,7 @@ async def config_modules(msg: Bot.MessageSession):
if recommend_modules_help_doc_list and ('-g' not in msg.parsed_msg or not msg.parsed_msg['-g']):
confirm = await msg.wait_confirm(msg.locale.t("core.message.module.recommends",
msgs='\n'.join(recommend_modules_list) + '\n\n' +
'\n'.join(recommend_modules_help_doc_list)), append_instruction=False)
'\n'.join(recommend_modules_help_doc_list)))
if confirm:
if msg.data.enable(recommend_modules_list):
msglist = []
@ -369,13 +369,13 @@ async def bot_help(msg: Bot.MessageSession):
@hlp.command(['{{core.help.module.help}}',
'legacy {{core.help.module.help.legacy}}')
'legacy {{core.help.module.help.legacy}}'])
async def _(msg: Bot.MessageSession):
module_list = ModulesManager.return_modules_list(
target_from=msg.target.target_from)
target_enabled_list = msg.enabled_modules
legacy_help = True
if 'legacy' not in msg.parsed_msg and msg.Feature.image:
if not msg.parsed_msg and msg.Feature.image:
try:
tables = []
essential = []

View file

@ -296,37 +296,36 @@ if Info.subprocess:
restart()
if Info.version:
upd = module('update', developers=['OasisAkari'], required_superuser=True, base=True)
upd = module('update', developers=['OasisAkari'], required_superuser=True, base=True)
def pull_repo():
return os.popen('git pull', 'r').read()[:-1]
def pull_repo():
return os.popen('git pull', 'r').read()[:-1]
def update_dependencies():
poetry_install = os.popen('poetry install').read()[:-1]
if poetry_install != '':
return poetry_install
pip_install = os.popen('pip install -r requirements.txt').read()[:-1]
if len(pip_install) > 500:
return '...' + pip_install[-500:]
return
def update_dependencies():
poetry_install = os.popen('poetry install').read()[:-1]
if poetry_install != '':
return poetry_install
pip_install = os.popen('pip install -r requirements.txt').read()[:-1]
if len(pip_install) > 500:
return '...' + pip_install[-500:]
return
@upd.handle()
async def update_bot(msg: Bot.MessageSession):
confirm = await msg.wait_confirm(msg.locale.t("core.message.confirm"), append_instruction=False)
if confirm:
pull_repo_result = pull_repo()
if pull_repo_result != '':
await msg.send_message(pull_repo_result)
await msg.send_message(update_dependencies())
else:
await msg.finish(msg.locale.t("core.message.update.failed"))
@upd.handle()
async def update_bot(msg: Bot.MessageSession):
confirm = await msg.wait_confirm(msg.locale.t("core.message.confirm"), append_instruction=False)
if confirm:
pull_repo_result = pull_repo()
if pull_repo_result != '':
await msg.send_message(pull_repo_result)
await msg.send_message(update_dependencies())
else:
await msg.finish(msg.locale.t("core.message.update.failed"))
if Info.version and Info.subprocess:
if Info.subprocess:
upds = module('update&restart', developers=['OasisAkari'], required_superuser=True, alias='u&r', base=True)
@upds.handle()

View file

@ -90,7 +90,7 @@ async def config_gu(msg: Bot.MessageSession):
await msg.finish(msg.locale.t("core.message.admin.list.none"))
user = msg.parsed_msg['<UserID>']
if not user.startswith(f'{msg.target.sender_from}|'):
await msg.finish(msg.locale.t('core.message.admin.invalid', prefix=msg.prefixes[0]))
await msg.finish(msg.locale.t('core.message.admin.invalid', target=msg.target.sender_from, prefix=msg.prefixes[0]))
if 'add' in msg.parsed_msg:
if user and user not in msg.custom_admins:
if msg.data.add_custom_admin(user):

View file

@ -1,6 +1,5 @@
from core.builtins import command_prefix
from core.utils.image import msgchain2image
from modules.maimai.libraries.maimai_best_50 import generate
from modules.maimai.libraries.maimaidx_api_data import get_alias, search_by_alias, update_assets
from modules.maimai.libraries.maimaidx_music import get_cover_len5_id, Music, TotalList
@ -42,8 +41,9 @@ def get_diff(diff):
return level
mai = module('maimai', developers=['mai-bot', 'OasisAkari', 'DoroWolf'], alias='mai',
desc='{maimai.help.desc}')
mai = module('maimai',
recommend_modules='maimai_regex', developers=['mai-bot', 'OasisAkari', 'DoroWolf'],
alias='mai', desc='{maimai.help.desc}')
@mai.handle('base <constant> [<constant_max>] {{maimai.help.base}}')

View file

@ -51,7 +51,7 @@
"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.scoreline.error": "發生錯誤:無法計算結果,請校對輸入。",
"maimai.message.scorelist": "以下為 ${user} 的 ${level} 級分數列表:",
"maimai.message.search": "「${keyword}」的搜尋結果:",
"maimai.message.song": "藝術家:${artist}\n分類${genre}\nBPM${bpm}\n版本${version}\n難度${level}",

View file

@ -180,7 +180,7 @@ async def _(msg: Bot.MessageSession):
payload = {'username': username}
if plate == '真将' or (plate[1] == '' and plate[0] != ''):
await msg.finish(msg.locale.t('maimai.message.plate.plate_not_found'))
return
output, get_img = await get_plate_process(msg, payload, plate)
@ -226,9 +226,9 @@ async def _(msg: Bot.MessageSession):
if level in level_list:
level_num = int(level.split('+')[0])
if level_num < 8:
await msg.finish(msg.locale.t("maimai.message.process.less_than_8"))
return
else:
await msg.finish(msg.locale.t("maimai.message.process.error.goal_invalid"))
return
if goal.upper() not in goal_list:
await msg.finish(msg.locale.t("maimai.message.process.error.goal_invalid"))

View file

@ -1,6 +1,6 @@
from core.builtins import Bot
from core.component import module
from .mcv import mcv, mcbv, mcdv, mcev
from .mcv import mcv, mcbv, mcdv, mcev, mclgv
m = module(
bind_prefix='mcv',
@ -42,3 +42,13 @@ me = module(
@me.handle('{{mcv.help.mcev}}')
async def mcev_loader(msg: Bot.MessageSession):
await msg.finish(await mcev(msg))
mlg = module(
bind_prefix='mclgv',
developers=['OasisAkari', 'Dianliang233'])
@mlg.handle('{{mcv.help.mclgv}}')
async def mclgv_loader(msg: Bot.MessageSession):
await msg.finish(await mclgv(msg))

View file

@ -2,16 +2,18 @@
"mcv.help.mcbv": "Get the latest version of Minecraft: Bedrock Edition on Mojira.",
"mcv.help.mcdv": "Get the latest version of Minecraft Dungeons on Mojira.",
"mcv.help.mcev": "Get the latest version of Minecraft: Education Edition in Windows Edition.",
"mcv.help.mclgv": "Get the latest version of Minecraft Legends on Mojira.",
"mcv.help.mcv": "Get the latest version of Minecraft: Java Edition in the launcher.",
"mcv.message.error.server": "Server error.",
"mcv.message.mcbv": "The latest version recorded on Mojira is:\n${msg2}\n(The latest version in the stores shall prevail, Mojira is only for previewing the version)",
"mcv.message.mcbv": "The latest version recorded on Mojira is:\n${jira_ver}\n(The latest version in the stores shall prevail, Mojira is only for previewing the version)",
"mcv.message.mcbv.get_failed": "Failed to fetch.",
"mcv.message.mcbv.ms_store": "Currently the latest version in Microsoft Store is: ",
"mcv.message.mcbv.play_store": "Currently the latest version in Google Play Store is: ",
"mcv.message.mcdv": "The latest version: ${mcdversion}\n(The data from Mojira may be earlier than the official release. Information is for reference purposes only).",
"mcv.message.mcev": "The latest version: ",
"mcv.message.mcv": "The latest version in the launcher is: \n${message1}\nThe latest version recorded on Mojira is: \n${message2}\n(The latest version in the launcher shall prevail, Mojira is only for previewing the version)",
"mcv.message.mcv.message1": "The latest release: ${release}, the latest snapshot: ${snapshot},",
"mcv.message.mcv.message1.failed": "Failed to get manifest.json.",
"mcv.message.mcv.message2.failed": "Failed to get Mojira information.",
"mcv.message.mcbv.get_failed": "Failed to fetch."
"mcv.message.mcdv": "The latest version: ${version}\n(The data from Mojira may be earlier than the official release. Information is for reference purposes only).",
"mcv.message.mcev": "The latest version: ${version}",
"mcv.message.mclgv": "The latest version: ${version}\n(The data from Mojira may be earlier than the official release. Information is for reference purposes only).",
"mcv.message.mcv": "The latest version in the launcher is: \n${launcher_ver}\nThe latest version recorded on Mojira is: \n${jira_ver}\n(The latest version in the launcher shall prevail, Mojira is only for previewing the version)",
"mcv.message.mcv.jira.failed": "Failed to get Mojira information.",
"mcv.message.mcv.launcher": "The latest release: ${release}, the latest snapshot: ${snapshot},",
"mcv.message.mcv.launcher.failed": "Failed to get manifest.json."
}

View file

@ -2,16 +2,18 @@
"mcv.help.mcbv": "查询当前 Minecraft 基岩版在 Mojira 内记录的最新版本。",
"mcv.help.mcdv": "查询当前 Minecraft Dungeons 在 Mojira 内记录的最新版本。",
"mcv.help.mcev": "查询当前 Minecraft教育版在 Windows 版记录的最新版本。",
"mcv.help.mclgv": "查询当前 Minecraft Legends 在 Mojira 内记录的最新版本。",
"mcv.help.mcv": "查询当前 MinecraftJava 版在启动器内最新版本。",
"mcv.message.error.server": "服务器错误。",
"mcv.message.mcbv": "Mojira 上所记录最新版本为:\n${msg2}\n以商店内最新版本为准Mojira 仅作版本号预览用)",
"mcv.message.mcbv": "Mojira 上所记录最新版本为:\n${jira_ver}\n以商店内最新版本为准Mojira 仅作版本号预览用)",
"mcv.message.mcbv.get_failed": "获取失败。",
"mcv.message.mcbv.ms_store": "目前 Microsoft Store 内最新正式版为:",
"mcv.message.mcbv.play_store": "目前 Google Play 商店内最新正式版为:",
"mcv.message.mcdv": "最新版:${mcdversion}\n数据来源于 Mojira可能会比官方发布要早一段时间。信息仅供参考。",
"mcv.message.mcev": "最新版:",
"mcv.message.mcv": "目前启动器内最新版本为:\n${message1}\nMojira 上所记录最新版本为:\n${message2}\n以启动器内最新版本为准Mojira 仅作版本号预览用",
"mcv.message.mcv.message1": "最新版:${release},最新快照:${snapshot}",
"mcv.message.mcv.message1.failed": "获取 manifest.json 失败。",
"mcv.message.mcv.message2.failed": "获取 Mojira 信息失败。",
"mcv.message.mcbv.get_failed": "获取失败。"
"mcv.message.mcdv": "最新版:${version}\n数据来源于 Mojira可能会比官方发布要早一段时间。信息仅供参考。",
"mcv.message.mcev": "最新版:${version}",
"mcv.message.mclgv": "最新版:${version}\n数据来源于 Mojira可能会比官方发布要早一段时间。信息仅供参考。",
"mcv.message.mcv": "目前启动器内最新版本为:\n${launcher_ver}\nMojira 上所记录最新版本为:\n${jira_ver}\n以启动器内最新版本为准Mojira 仅作版本号预览用)",
"mcv.message.mcv.jira.failed": "获取 Mojira 信息失败。",
"mcv.message.mcv.launcher": "最新版:${release},最新快照:${snapshot}",
"mcv.message.mcv.launcher.failed": "获取 manifest.json 失败。"
}

View file

@ -2,16 +2,18 @@
"mcv.help.mcbv": "查詢目前 Minecraft 基岩版在 Mojira 內記錄的最新版本。",
"mcv.help.mcdv": "查詢目前 Minecraft Dungeons 在 Mojira 內記錄的最新版本。",
"mcv.help.mcev": "查詢目前 Minecraft教育版在 Windows 版記錄的最新版本。",
"mcv.help.mclgv": "查詢目前 Minecraft Legends 在 Mojira 內記錄的最新版本。",
"mcv.help.mcv": "查詢目前 MinecraftJava 版在啟動器內最新版本。",
"mcv.message.error.server": "伺服器錯誤。",
"mcv.message.mcbv": "Mojira 上所記錄最新版本為:\n${msg2}\n以商店內最新版本為準Mojira 僅作版本號預覽用)",
"mcv.message.mcbv": "Mojira 上所記錄最新版本為:\n${jira_ver}\n以商店內最新版本為準Mojira 僅作版本號預覽用)",
"mcv.message.mcbv.get_failed": "取得失敗。",
"mcv.message.mcbv.ms_store": "目前 Microsoft Store 內最新正式版為:",
"mcv.message.mcbv.play_store": "目前 Google Play 商店內最新正式版為:",
"mcv.message.mcdv": "最新版:${mcdversion}\n資訊來源於 Mojira可能會比官方發布要早一段時間。資訊僅供參考。",
"mcv.message.mcev": "最新版:",
"mcv.message.mcv": "目前啟動器內最新版本為:\n${message1}\nMojira 上所記錄最新版本為:\n${message2}\n以啟動器內最新版本為準Mojira 僅作版本號預覽用",
"mcv.message.mcv.message1": "最新版:${release},最新快照:${snapshot}",
"mcv.message.mcv.message1.failed": "取得 manifest.json 失敗。",
"mcv.message.mcv.message2.failed": "取得 Mojira 資訊失敗。",
"mcv.message.mcbv.get_failed": "取得失敗。"
"mcv.message.mcdv": "最新版:${version}\n資訊來源於 Mojira可能會比官方發布要早一段時間。資訊僅供參考。",
"mcv.message.mcev": "最新版:${version}",
"mcv.message.mclgv": "最新版:${version}\n資訊來源於 Mojira可能會比官方發布要早一段時間。資訊僅供參考。",
"mcv.message.mcv": "目前啟動器內最新版本為:\n${launcher_ver}\nMojira 上所記錄最新版本為:\n${jira_ver}\n以啟動器內最新版本為準Mojira 僅作版本號預覽用)",
"mcv.message.mcv.jira.failed": "取得 Mojira 資訊失敗。",
"mcv.message.mcv.launcher": "最新版:${release},最新快照:${snapshot}",
"mcv.message.mcv.launcher.failed": "取得 manifest.json 失敗。"
}

View file

@ -13,11 +13,11 @@ async def mcv(msg):
try:
data = json.loads(await get_url('https://piston-meta.mojang.com/mc/game/version_manifest.json', 200))
message1 = msg.locale.t(
"mcv.message.mcv.message1",
"mcv.message.mcv.launcher",
release=data['latest']['release'],
snapshot=data['latest']['snapshot'])
except (ConnectionError, OSError): # Probably...
message1 = msg.locale.t("mcv.message.mcv.message1.failed")
message1 = msg.locale.t("mcv.message.mcv.launcher.failed")
try:
mojira = json.loads(await get_url('https://bugs.mojang.com/rest/api/2/project/10400/versions', 200))
release = []
@ -27,8 +27,8 @@ async def mcv(msg):
release.append(v['name'])
message2 = prefix.join(release)
except Exception:
message2 = msg.locale.t("mcv.message.mcv.message2.failed")
return msg.locale.t("mcv.message.mcv", message1=message1, message2=message2)
message2 = msg.locale.t("mcv.message.mcv.jira.failed")
return msg.locale.t("mcv.message.mcv", launcher_ver=message1, jira_ver=message2)
async def mcbv(msg):
@ -74,7 +74,7 @@ async def mcbv(msg):
f"""{msg.locale.t("mcv.message.mcbv.ms_store")}
{ms_store_version if ms_store_version is not None else msg.locale.t('mcv.message.mcbv.get_failed')}
""" + \
msg.locale.t("mcv.message.mcbv", msg2=msg2)
msg.locale.t("mcv.message.mcbv", jira_ver=msg2)
async def mcdv(msg):
@ -86,7 +86,7 @@ async def mcdv(msg):
for v in data:
if not v['archived']:
release.append(v["name"])
return msg.locale.t('mcv.message.mcdv', mcdversion=" | ".join(release))
return msg.locale.t('mcv.message.mcdv', version=" | ".join(release))
async def mcev(msg):
@ -97,4 +97,16 @@ async def mcev(msg):
Logger.debug(version)
except (ConnectionError, OSError): # Probably...
return ErrorMessage(msg.locale.t('mcv.message.error.server'))
return f'{msg.locale.t("mcv.message.mcev")}{version}'
return msg.locale.t("mcv.message.mcev", version=version)
async def mclgv(msg):
try:
data = json.loads(await get_url('https://bugs.mojang.com/rest/api/2/project/12200/versions', 200))
except (ConnectionError, OSError): # Probably...
return ErrorMessage(msg.locale.t('mcv.message.error.server'))
release = []
for v in data:
if not v['archived']:
release.append(v["name"])
return msg.locale.t('mcv.message.mclgv', version=" | ".join(release))

View file

@ -3,7 +3,7 @@ from core.component import module
mcv_rss = module('mcv_rss',
developers=['OasisAkari', 'Dianliang233'],
recommend_modules=['mcv_jira_rss', 'mcbv_jira_rss', 'mcdv_jira_rss'],
recommend_modules=['mcv_jira_rss', 'mcbv_jira_rss', 'mcdv_jira_rss', 'mclgv_jira_rss'],
desc='{mcv_rss.help.mcv_rss.desc}', alias='mcvrss')
@ -23,7 +23,7 @@ async def mcbv_rss(fetch: Bot.FetchTarget, ctx: Bot.ModuleHookContext):
mcv_jira_rss = module('mcv_jira_rss', developers=['OasisAkari', 'Dianliang233'],
recommend_modules=['mcv_rss', 'mcbv_jira_rss', 'mcdv_jira_rss'],
recommend_modules=['mcv_rss', 'mcbv_jira_rss', 'mcdv_jira_rss', 'mclgv_jira_rss'],
desc='{mcv_rss.help.mcv_jira_rss.desc}', alias='mcvjirarss')
@ -34,7 +34,7 @@ async def mcv_jira_rss(fetch: Bot.FetchTarget, ctx: Bot.ModuleHookContext):
mcbv_jira_rss = module('mcbv_jira_rss',
developers=['OasisAkari', 'Dianliang233'],
recommend_modules=['mcv_rss', 'mcv_jira_rss', 'mcdv_jira_rss'],
recommend_modules=['mcv_rss', 'mcv_jira_rss', 'mcdv_jira_rss', 'mclgv_jira_rss'],
desc='{mcv_rss.help.mcbv_jira_rss.desc}', alias='mcbvjirarss')
@ -45,10 +45,21 @@ async def mcbv_jira_rss(fetch: Bot.FetchTarget, ctx: Bot.ModuleHookContext):
mcdv_jira_rss = module('mcdv_jira_rss',
developers=['OasisAkari', 'Dianliang233'],
recommend_modules=['mcv_rss', 'mcbv_jira_rss', 'mcv_jira_rss'],
recommend_modules=['mcv_rss', 'mcbv_jira_rss', 'mcv_jira_rss', 'mclgv_jira_rss'],
desc='{mcv_rss.help.mcdv_jira_rss.desc}', alias='mcdvjirarss')
@mcdv_jira_rss.hook()
async def mcdv_jira_rss(fetch: Bot.FetchTarget, ctx: Bot.ModuleHookContext):
await fetch.post_message('mcdv_rss', **ctx.args)
mclgv_jira_rss = module('mclgv_jira_rss',
developers=['OasisAkari', 'Dianliang233'],
recommend_modules=['mcv_rss', 'mcbv_jira_rss', 'mcv_jira_rss', 'mcdv_jira_rss'],
desc='{mcv_rss.help.mclgv_jira_rss.desc}', alias='mclgvjirarss')
@mclgv_jira_rss.hook()
async def mclgv_jira_rss(fetch: Bot.FetchTarget, ctx: Bot.ModuleHookContext):
await fetch.post_message('mclgv_rss', **ctx.args)

View file

@ -2,11 +2,13 @@
"mcv_rss.help.mcbv_jira_rss.desc": "开启后 Mojira 更新基岩版时会自动推送消息。",
"mcv_rss.help.mcbv_rss.desc": "开启后商店更新 Minecraft 基岩版时会自动推送消息。",
"mcv_rss.help.mcdv_jira_rss.desc": "开启后 Mojira 更新 Minecraft Dungeons 时会自动推送消息。",
"mcv_rss.help.mclgv_jira_rss.desc": "开启后 Mojira 更新 Minecraft Legends 时会自动推送消息。",
"mcv_rss.help.mcv_jira_rss.desc": "开启后 Mojira 更新 Java 版时会自动推送消息。",
"mcv_rss.help.mcv_rss.desc": "开启后 Minecraft 启动器更新 MinecraftJava 版时会自动推送消息。",
"mcv_rss.message.mcbv_jira_rss": "Mojira 已更新基岩版 ${version}。\nMojira 上的信息仅作版本号预览用,不代表商店已更新此版本)",
"mcv_rss.message.mcbv_rss": "Google Play 商店已更新基岩版 ${version} 正式版。",
"mcv_rss.message.mcdv_jira_rss": "Mojira 已更新 Minecraft Dungeons ${version}。\nMojira 上的信息仅作版本号预览用,不代表启动器/商店已更新此版本)",
"mcv_rss.message.mclgv_jira_rss": "Mojira 已更新 Minecraft Legends ${version}。\nMojira 上的信息仅作版本号预览用,不代表启动器/商店已更新此版本)",
"mcv_rss.message.mcv_jira_rss": "Java Edition ${version} is marked as archived (released) on Mojira.\n(This does not mean you can get to play it right away; you will have to wait for Mojang to release it in the Launcher.)",
"mcv_rss.message.mcv_jira_rss.future": "Java Edition ${version} is added to Mojira.\n(“Future Version” only indicates that a new version is planned; you will have to wait for Mojang to release it in the Launcher.)",
"mcv_rss.message.mcv_rss.release": "${version} is now released in Minecraft Launcher.",

View file

@ -2,11 +2,13 @@
"mcv_rss.help.mcbv_jira_rss.desc": "开启后 Mojira 更新基岩版时会自动推送消息。",
"mcv_rss.help.mcbv_rss.desc": "开启后商店更新 Minecraft 基岩版时会自动推送消息。",
"mcv_rss.help.mcdv_jira_rss.desc": "开启后 Mojira 更新 Minecraft Dungeons 时会自动推送消息。",
"mcv_rss.help.mclgv_jira_rss.desc": "开启后 Mojira 更新 Minecraft Legends 时会自动推送消息。",
"mcv_rss.help.mcv_jira_rss.desc": "开启后 Mojira 更新 Java 版时会自动推送消息。",
"mcv_rss.help.mcv_rss.desc": "开启后 Minecraft 启动器更新 MinecraftJava 版时会自动推送消息。",
"mcv_rss.message.mcbv_jira_rss": "Mojira 已更新基岩版 ${version}。\nMojira 上的信息仅作版本号预览用,不代表商店已更新此版本)",
"mcv_rss.message.mcbv_rss": "Google Play 商店已更新基岩版 ${version} 正式版。",
"mcv_rss.message.mcdv_jira_rss": "Mojira 已更新 Minecraft Dungeons ${version}。\nMojira 上的信息仅作版本号预览用,不代表启动器/商店已更新此版本)",
"mcv_rss.message.mclgv_jira_rss": "Mojira 已更新 Minecraft Legends ${version}。\nMojira 上的信息仅作版本号预览用,不代表启动器/商店已更新此版本)",
"mcv_rss.message.mcv_jira_rss": "Mojira 已更新 Java 版 ${version}。\nMojira 上的信息仅作版本号预览用,不代表启动器已更新此版本)",
"mcv_rss.message.mcv_jira_rss.future": "Mojira 已新增 Java 版 ${version}。\nFuture Version 仅代表与此相关的版本正在规划中,不代表启动器已更新此版本)",
"mcv_rss.message.mcv_rss.release": "启动器已更新 ${version} 正式版。",

View file

@ -2,11 +2,13 @@
"mcv_rss.help.mcbv_jira_rss.desc": "啟用後 Mojira 更新基岩版時會自動推播訊息。",
"mcv_rss.help.mcbv_rss.desc": "啟用後商店更新 Minecraft 基岩版時會自動推播訊息。",
"mcv_rss.help.mcdv_jira_rss.desc": "啟用後 Mojira 更新 Minecraft Dungeons 時會自動推播訊息。",
"mcv_rss.help.mclgv_jira_rss.desc": "开启后 Mojira 更新 Minecraft Legends 时会自动推送消息。",
"mcv_rss.help.mcv_jira_rss.desc": "啟用後 Mojira 更新 Java 版時會自動推播訊息。",
"mcv_rss.help.mcv_rss.desc": "啟用後 Minecraft 啟動器更新 MinecraftJava 版時會自動推播訊息。",
"mcv_rss.message.mcbv_jira_rss": "Mojira 已更新基岩版 ${version}。 \nMojira 上的資訊僅作版本號預覽用,不代表啟動器已更新此版本)",
"mcv_rss.message.mcbv_rss": "Google Play 商店已更新基岩版 ${version} 正式版。",
"mcv_rss.message.mcdv_jira_rss": "Mojira 已更新 Minecraft Dungeons ${version}。 \nMojira 上的資訊僅作版本號預覽用,不代表啟動器/商店已更新此版本)",
"mcv_rss.message.mclgv_jira_rss": "Mojira 已更新 Minecraft Legends ${version}。 \nMojira 上的資訊僅作版本號預覽用,不代表啟動器/商店已更新此版本)",
"mcv_rss.message.mcv_jira_rss": "Mojira 已更新 Java 版 ${version}。 \nMojira 上的資訊僅作版本號預覽用,不代表啟動器已更新此版本)",
"mcv_rss.message.mcv_jira_rss.future": "Mojira 已新增 Java 版 ${version}。 \nFuture Version 僅代表與此相關的版本正在規劃中,不代表啟動器已更新此版本)",
"mcv_rss.message.mcv_rss.release": "啟動器已更新 ${version} 正式版。",

View file

@ -21,7 +21,7 @@ async def search(msg: Bot.MessageSession, keyword: str):
songs = result['result']['songs'][:10]
if 'legacy' not in msg.parsed_msg and msg.Feature.image:
if not msg.parsed_msg.get('legacy', False) and msg.Feature.image:
send_msg = [Plain(msg.locale.t('ncmusic.message.search.result') + '\n')]
data = [[

View file

@ -1,5 +1,6 @@
{
"ncmusic.help.search": "搜索网易云音乐。",
"ncmusic.help.search.legacy": "搜索网易云音乐。(旧版)",
"ncmusic.help.info": "获取音乐详细信息。",
"ncmusic.message.info": "歌名:${name}${id}\n专辑名${album}${album_id}\n歌手${artists}\n歌曲详情页${detail}",
"ncmusic.message.search.collapse": "…仅显示前 10 条内容。",

View file

@ -5,7 +5,6 @@
"phigros.help.unbind": "解绑用户。",
"phigros.message.bind.success": "绑定成功。",
"phigros.message.bind.warning": "警告:您正在群组中绑定用户,这有可能会使您的云存档数据被他人篡改。请尽可能私聊绑定用户以避免这种情况。\n您可以通过重新登录来重置 SessionToken。此次命令产生的消息将在 15 秒后撤回。",
"phigros.message.bind.revoke_failed": "自动撤回失败,请手动撤回消息。",
"phigros.message.unbind.success": "解绑成功。",
"phigros.message.user_unbound": "未绑定用户,请使用“${prefix}phigros bind”绑定一个用户。",
"phigros.message.b19.get_failed": "获取失败,请尝试重新绑定 SessionToken 或报告开发者:\n${err}"

View file

@ -5,7 +5,6 @@
"phigros.help.unbind": "解绑用户。",
"phigros.message.bind.success": "绑定成功:${username}",
"phigros.message.bind.warning": "警告:您正在群组中绑定用户,这有可能会使您的云存档数据被他人篡改。请尽可能私聊绑定用户以避免这种情况。\n您可以通过重新登录来重置 SessionToken。此次命令产生的消息将在 15 秒后撤回。",
"phigros.message.bind.revoke_failed": "自动撤回失败,请手动撤回消息。",
"phigros.message.unbind.success": "解绑成功。",
"phigros.message.user_unbound": "未绑定用户,请使用“${prefix}phigros bind”绑定一个用户。",
"phigros.message.b19.get_failed": "获取失败,请尝试重新绑定 SessionToken 或报告开发者:\n${err}"

View file

@ -5,7 +5,6 @@
"phigros.help.unbind": "解除綁定使用者。",
"phigros.message.bind.success": "綁定成功:${usernane}",
"phigros.message.bind.warning": "警告:您正在群組中綁定使用者,這有可能會使您的雲端存檔資料被他人竄改。請盡可能在私訊中綁定使用者以避免這種情況。\n您可以透過重新登入來重設 SessionToken。此次指令產生的訊息將在 15 秒後回收。",
"phigros.message.bind.revoke_failed": "自动撤回失败,请手动撤回消息。",
"phigros.message.unbind.success": "解除綁定成功。",
"phigros.message.user_unbound": "未綁定使用者,請使用「${prefix}phigros bind」綁定一個使用者。",
"phigros.message.b19.get_failed": "取得失敗,請嘗試重新綁定 SessionToken 或回報開發人員:\n${err}"

View file

@ -1,86 +0,0 @@
import os
from PIL import Image, ImageDraw, ImageFont
from core.builtins import Bot, Image as Img
from core.component import module
from core.utils.cache import random_cache_path
assets_path = os.path.abspath('./assets/arcaea')
p = module('ptt',
developers=['OasisAkari'])
@p.handle('<potential> {{ptt.help}}')
async def pttimg(msg: Bot.MessageSession):
ptt = msg.parsed_msg['<potential>']
# ptt
if ptt == '--':
ptt = -1
else:
try:
ptt = float(ptt)
except ValueError:
await msg.finish(msg.locale.t('ptt.message.error.invalid'))
if ptt >= 13.00:
pttimg = 7
elif ptt >= 12.50:
pttimg = 6
elif ptt >= 12.00:
pttimg = 5
elif ptt >= 11.00:
pttimg = 4
elif ptt >= 10.00:
pttimg = 3
elif ptt >= 7.00:
pttimg = 2
elif ptt >= 3.50:
pttimg = 1
elif ptt >= 0:
pttimg = 0
else:
pttimg = 'off'
pttimgr = Image.open(f'{assets_path}/ptt/rating_{str(pttimg)}.png')
ptttext = Image.new("RGBA", (119, 119))
font1 = ImageFont.truetype(os.path.abspath(f'{assets_path}/Fonts/Exo-SemiBold.ttf'), 49)
font2 = ImageFont.truetype(os.path.abspath(f'{assets_path}/Fonts/Exo-SemiBold.ttf'), 33)
if ptt >= 0 and ptt <= 99.99:
rawptt = str(ptt).split('.')
if len(rawptt) < 2:
ptt1 = rawptt[0]
ptt2 = '00'
else:
ptt1 = rawptt[0]
ptt2 = rawptt[1][:2]
if len(ptt2) < 2:
ptt2 += '0'
ptttext_width, ptttext_height = ptttext.size
font1_width, font1_height = font1.getsize(ptt1 + '.')
font2_width, font2_height = font2.getsize(ptt2)
pttimg = Image.new("RGBA", (font1_width + font2_width + 6, font1_height + 6))
drawptt = ImageDraw.Draw(pttimg)
stroke_color = '#52495d'
if int(ptt1) >= 13:
stroke_color = '#81122F'
drawptt.text((0, 0), ptt1 + '.', 'white', font=font1, stroke_width=3, stroke_fill=stroke_color)
drawptt.text((font1_width, int(int(font1_height) - int(font2_height))), ptt2, 'white', font=font2,
stroke_width=3, stroke_fill=stroke_color)
elif ptt == -1:
ptt = '--'
ptttext_width, ptttext_height = ptttext.size
font1_width, font1_height = font1.getsize(ptt)
pttimg = Image.new("RGBA", (font1_width + 6, font1_height + 6))
drawptt = ImageDraw.Draw(pttimg)
drawptt.text((0, 0), ptt, 'white', font=font1, stroke_width=3, stroke_fill='#52495d')
else:
return await msg.finish(msg.locale.t('ptt.message.error.invalid'))
pttimg_width, pttimg_height = pttimg.size
ptttext.alpha_composite(pttimg,
(int((ptttext_width - pttimg_width) / 2), int((ptttext_height - pttimg_height) / 2) - 11))
ptttext = ptttext.resize(pttimgr.size)
pttimgr.alpha_composite(ptttext, (0, 0))
savepath = random_cache_path() + '.png'
pttimgr.save(savepath)
await msg.finish([Img(path=savepath)])

View file

@ -1,4 +0,0 @@
{
"ptt.help": "Generate a Potential image of Arcaea.",
"ptt.message.error.invalid": "An error occurred: Potential must be a number greater than 0.00 and less than 99.99."
}

View file

@ -1,4 +0,0 @@
{
"ptt.help": "生成一张 Arcaea 潜力值图片。",
"ptt.message.error.invalid": "发生错误:潜力值必须为 ≥0.00 且 ≤99.99 的数字。"
}

View file

@ -1,4 +0,0 @@
{
"ptt.help": "產生一張 Arcaea 潛力值圖片。",
"ptt.message.error.invalid": "發生錯誤:潛力值必須為 ≥0.00 且 ≤99.99 的數字。"
}

View file

@ -2,7 +2,6 @@
"server.help": "Get Minecraft: Java/Bedrock Edition server motd.",
"server.help.option.p": "Show Players List",
"server.help.option.r": "Show Raw Info",
"server.help.revoke": "Whether to enable automatic revoke (default enable).",
"server.message.error": "An error occurred while querying for the API.",
"server.message.error.local_ip": "An error occurred: Invalid domain name or IP address.",
"server.message.gamemode": "Game mode: ",

View file

@ -2,7 +2,6 @@
"server.help": "获取 MinecraftJava 版/基岩版服务器 motd。",
"server.help.option.p": "显示玩家列表",
"server.help.option.r": "显示原始信息",
"server.help.revoke": "是否开启自动撤回功能(默认为是)。",
"server.message.error": "查询调用 API 时发生错误。",
"server.message.error.local_ip": "发生错误:无效的域名或 IP 地址。",
"server.message.gamemode": "游戏模式:",

View file

@ -2,7 +2,6 @@
"server.help": "取得 MinecraftJava 版/基岩版伺服器 motd。",
"server.help.option.p": "列出玩家列表",
"server.help.option.r": "列出原始資訊",
"server.help.revoke": "是否啟用自動回收功能(預設為是)。",
"server.message.error": "查詢呼叫 API 時發生錯誤。",
"server.message.error.local_ip": "發生錯誤:無效的域名或 IP 位址。",
"server.message.gamemode": "遊戲模式:",

View file

@ -1,7 +1,7 @@
{
"tweet.help": "Get tweet image from tweet ID or link. (P.S. We didn't pay the $200 Elon tax)",
"tweet.help.desc": "Get tweet image from tweet ID or link. ",
"tweet.message.error": "发生错误:无法识别推文 ID请检查输入。",
"tweet.message.error": "An error occurred: Unable to recongnize tweet ID. Please check your input.",
"tweet.message.not_found": "Tweet not found.",
"tweet.message.tombstone": "An error occurred while fetching Tweet: "
}

View file

@ -1,6 +1,6 @@
{
"weekly.help": "Get the weekly page of Chinese Minecraft Wiki.",
"weekly.help.image": "获取中文 Minecraft Wiki 的每周页面(图片版)。",
"weekly.help.image": "Get the weekly page of Chinese Minecraft Wiki (Image version).",
"weekly.help.teahouse": "Get Teahouse Weekly.",
"weekly.message": "Weekly page:${text}",
"weekly.message.error.expired": "An error occurred: The weekly page has expired. Please contact Chinese Minecraft Wiki to update.",

View file

@ -14,7 +14,7 @@ if Config('enable_urlmanager'):
@aud.handle(['trust <apiLink>', 'block <apiLink>'])
async def _(msg: Bot.MessageSession):
date = datetime.now().strftime("%Y-%m-%d")
date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
api = msg.parsed_msg['<apiLink>']
check = await WikiLib(api).check_wiki_available()
if check.available:
@ -49,10 +49,6 @@ if Config('enable_urlmanager'):
await msg.finish(msg.locale.t('wiki.message.wiki_audit.remove.failed', list_name=list_name) + api)
else:
await msg.finish(msg.locale.t('wiki.message.wiki_audit.remove.success', list_name=list_name) + api)
else:
result = msg.locale.t('wiki.message.error.query') + \
('\n' + msg.locale.t('wiki.message.error.info') + check.message if check.message != '' else '')
await msg.finish(result)
@aud.handle('query <apiLink>')
async def _(msg: Bot.MessageSession):
@ -83,7 +79,7 @@ if Config('enable_urlmanager'):
allow_list = Audit.get_allow_list()
block_list = Audit.get_block_list()
legacy = True
if 'legacy' not in msg.parsed_msg and msg.Feature.image:
if not msg.parsed_msg.get('legacy', False) and msg.Feature.image:
send_msgs = []
allow_columns = [[x[0], x[1]] for x in allow_list]
if allow_columns:

View file

@ -1,6 +1,6 @@
{
"tos.reason.too_many_redirects": "Causes the bot to redirect the page too many times.",
"tos.reason.wiki_abuse": "More than 15 pages are queried at one time.",
"tos.reason.wiki_abuse": "Queried more than 15 pages at one time.",
"wiki.help": "Query a wiki page.",
"wiki.help.ab": "Get recent abuse logs for the default wiki.",
"wiki.help.ab.legacy": "Get recent abuse logs for the default wiki. (Legacy)",
@ -19,8 +19,8 @@
"wiki.help.option.l": "Find the corresponding language version of this page, and return the current language if no result.",
"wiki.help.prefix.reset": "Reset custom wiki prefix.",
"wiki.help.prefix.set": "Set custom wiki prefix.",
"wiki.help.rc": "Get a list of recent changes to the default wiki.",
"wiki.help.rc.legacy": "Get a list of recent changes to the default wiki. (Legacy)",
"wiki.help.rc": "Get recent changes for the default wiki.",
"wiki.help.rc.legacy": "Get recent changes for the default wiki. (Legacy)",
"wiki.help.redlink": "Toggle whether to return the edit link when the page does not exist.",
"wiki.help.search": "Search a wiki page.",
"wiki.help.set": "Set up start wiki.",
@ -52,7 +52,7 @@
"wiki.message.iw.list": "Use \"${prefix}wiki iw get <Interwiki>\" to get the corresponding link to Interwiki.",
"wiki.message.iw.list.legacy": "The following Interwiki(s) are currently set up:\n",
"wiki.message.iw.list.prompt": "Here are the custom Interwiki(s) set up for bot. To view the Interwiki for the start wiki, see: ${url}",
"wiki.message.iw.none": "There is currently no Interwiki. Can be added using \"${prefix}wiki iw add\".",
"wiki.message.iw.list.none": "There is currently no Interwiki. Can be added using \"${prefix}wiki iw add\".",
"wiki.message.iw.remove.success": "Custom Interwiki removed: ${iw}",
"wiki.message.magic_word": "Note: The bot does not currently support magic words.",
"wiki.message.not_found": "[${title}] not found.",

View file

@ -52,7 +52,7 @@
"wiki.message.iw.list": "使用“${prefix}wiki iw get <Interwiki>”可以获取 Interwiki 对应的链接。",
"wiki.message.iw.list.legacy": "当前设置了以下 Interwiki",
"wiki.message.iw.list.prompt": "此处展示的是为机器人设置的自定义 Interwiki如需查看起始 Wiki 的 Interwiki请见${url}",
"wiki.message.iw.none": "当前没有设置任何 Interwiki可使用“${prefix}wiki iw add”添加。",
"wiki.message.iw.list.none": "当前没有设置任何 Interwiki可使用“${prefix}wiki iw add”添加。",
"wiki.message.iw.remove.success": "已删除自定义 Interwiki${iw}",
"wiki.message.magic_word": "提示:机器人暂不支持魔术字。",
"wiki.message.not_found": "未找到 [${title}]。",

View file

@ -52,7 +52,7 @@
"wiki.message.iw.list": "使用 「${prefix}wiki iw get <Interwiki>」可以取得 Interwiki 對應的連結。",
"wiki.message.iw.list.legacy": "目前設定了以下 Interwiki",
"wiki.message.iw.list.prompt": "此處展示的是機器人設定的自訂 Interwiki如需查看起始 Wiki 的 Interwiki請見${url}",
"wiki.message.iw.none": "目前沒有設定任何 Interwiki可使用 「${prefix}wiki iw add」新增。",
"wiki.message.iw.list.none": "目前沒有設定任何 Interwiki可使用 「${prefix}wiki iw add」新增。",
"wiki.message.iw.remove.success": "已刪除自訂 Interwiki${iw}",
"wiki.message.magic_word": "提示:機器人暫不支援魔術字。",
"wiki.message.not_found": "未找到 [${title}]。",

View file

@ -74,7 +74,7 @@ async def _(msg: Bot.MessageSession):
if base_interwiki_link_.status:
base_interwiki_link = base_interwiki_link_.link
if query != {}:
if 'legacy' not in msg.parsed_msg and msg.Feature.image:
if not msg.parsed_msg.get('legacy', False) and msg.Feature.image:
columns = [[x, query[x]] for x in query]
img = await image_table_render(ImageTable(columns, ['Interwiki', 'Url']))
else:
@ -87,11 +87,11 @@ async def _(msg: Bot.MessageSession):
else:
result = msg.locale.t("wiki.message.iw.list.legacy") + '\n' + \
'\n'.join([f'{x}: {query[x]}' for x in query])
if base_interwiki_link is not None:
result += '\n' + msg.locale.t("wiki.message.iw.list.prompt", url=str(Url(base_interwiki_link)))
await msg.finish(result)
else:
await msg.finish(msg.locale.t("wiki.message.iw.none", prefix=msg.prefixes[0]))
result = msg.locale.t("wiki.message.iw.list.none", prefix=msg.prefixes[0])
if base_interwiki_link is not None:
result += '\n' + msg.locale.t("wiki.message.iw.list.prompt", url=str(Url(base_interwiki_link)))
await msg.finish(result)
@wiki.handle('iw get <Interwiki> {{wiki.help.iw.get}}')
@ -104,7 +104,7 @@ async def _(msg: Bot.MessageSession):
else:
await msg.finish(msg.locale.t("wiki.message.iw.get.not_found", iw=msg.parsed_msg["<Interwiki>"]))
else:
await msg.finish(msg.locale.t("wiki.message.iw.none", prefix=msg.prefixes[0]))
await msg.finish(msg.locale.t("wiki.message.iw.list.none", prefix=msg.prefixes[0]))
@wiki.handle('headers show {{wiki.help.headers.show}}')
@ -133,8 +133,6 @@ async def _(msg: Bot.MessageSession):
" ".join(msg.trigger_msg.split(" ")[3:]), let_it=False)
if delete:
await msg.finish(msg.locale.t("wiki.message.headers.add.success", headers=json.dumps(target.get_headers())))
else:
await msg.finish(msg.locale.t("wiki.message.headers.add.failed"))
@wiki.handle('headers reset {{wiki.help.headers.reset}}', required_admin=True)

View file

@ -13,14 +13,14 @@ from .rc_qq import rc_qq
rc_ = module('rc', developers=['OasisAkari'])
@rc_.handle('{wiki.help.rc}')
@rc_.handle('legacy {wiki.help.rc.legacy}')
@rc_.handle(['{{wiki.help.rc}}',
'legacy {{wiki.help.rc.legacy}}'])
async def rc_loader(msg: Bot.MessageSession):
start_wiki = WikiTargetInfo(msg).get_start_wiki()
if start_wiki is None:
return await msg.finish(msg.locale.t('wiki.message.not_set'))
legacy = True
if msg.Feature.forward and msg.target.target_from == 'QQ|Group' and 'legacy' not in msg.parsed_msg:
if not msg.parsed_msg and msg.Feature.forward and msg.target.target_from == 'QQ|Group':
try:
nodelist = await rc_qq(start_wiki)
await msg.fake_forward_msg(nodelist)
@ -36,14 +36,14 @@ async def rc_loader(msg: Bot.MessageSession):
a = module('ab', developers=['OasisAkari'])
@a.handle('{wiki.help.ab}')
@rc_.handle('legacy {wiki.help.ab.legacy}')
@a.handle(['{{wiki.help.ab}}',
'legacy {{wiki.help.ab.legacy}}'])
async def ab_loader(msg: Bot.MessageSession):
start_wiki = WikiTargetInfo(msg).get_start_wiki()
if start_wiki is None:
return await msg.finish(msg.locale.t('wiki.message.not_set'))
legacy = True
if msg.Feature.forward and msg.target.target_from == 'QQ|Group' and 'legacy' not in msg.parsed_msg:
if not msg.parsed_msg and msg.Feature.forward and msg.target.target_from == 'QQ|Group':
try:
nodelist = await ab_qq(start_wiki)
await msg.fake_forward_msg(nodelist)

View file

@ -78,7 +78,7 @@ class WikiTargetInfo:
self.query.headers = json.dumps(headers_)
session.commit()
return True
except TypeError:
except:
return False
def get_headers(self):
@ -160,7 +160,7 @@ class Audit:
def add_to_AllowList(self, date) -> bool:
if self.inAllowList:
return False
session.add_all([WikiAllowList(apiLink=self.api_link, addDate=date)])
session.add_all([WikiAllowList(apiLink=self.api_link, operator=date)])
session.commit()
session.expire_all()
return True
@ -182,7 +182,7 @@ class Audit:
def add_to_BlockList(self, date) -> bool:
if self.inBlockList:
return False
session.add_all([WikiBlockList(apiLink=self.api_link, addDate=date)])
session.add_all([WikiBlockList(apiLink=self.api_link, operator=date)])
session.commit()
session.expire_all()
return True
@ -201,10 +201,10 @@ class Audit:
@retry(stop=stop_after_attempt(3), reraise=True)
@auto_rollback_error
def get_allow_list() -> list:
return session.query(WikiAllowList.apiLink, WikiAllowList.addDate)
return session.query(WikiAllowList.apiLink, WikiAllowList.operator)
@staticmethod
@retry(stop=stop_after_attempt(3), reraise=True)
@auto_rollback_error
def get_block_list() -> list:
return session.query(WikiBlockList.apiLink, WikiBlockList.addDate)
return session.query(WikiBlockList.apiLink, WikiBlockList.operator)

View file

@ -32,14 +32,14 @@ class WikiAllowList(Base):
__tablename__ = table_prefix + 'WikiAllowList'
__table_args__ = {'extend_existing': True}
apiLink = Column(String(512), primary_key=True)
addDate = Column(String(512))
operator = Column(String(512))
class WikiBlockList(Base):
__tablename__ = table_prefix + 'WikiBlockList'
__table_args__ = {'extend_existing': True}
apiLink = Column(String(512), primary_key=True)
addDate = Column(String(512))
operator = Column(String(512))
Session.create()

View file

@ -196,3 +196,27 @@ async def mcdv_jira_rss():
update_stored_list('scheduler', 'mcdv_jira_rss', verlist)
except Exception:
traceback.print_exc()
@Scheduler.scheduled_job(IntervalTrigger(seconds=trigger_times))
async def mclgv_jira_rss():
try:
verlist = get_stored_list('scheduler', 'mclgv_jira_rss')
file = json.loads(await get_url('https://bugs.mojang.com/rest/api/2/project/12200/versions', 200, attempt=1))
releases = []
for v in file:
if not v['archived']:
releases.append(v['name'])
else:
if v['name'] not in verlist:
verlist.append(v['name'])
for release in releases:
if release not in verlist:
Logger.info(f'huh, we find {release}.')
await JobQueue.trigger_hook_all('mclgv_jira_rss', message='mcv_rss.message.mclgv_jira_rss',
i18n=True, version=release)
verlist.append(release)
update_stored_list('scheduler', 'mclgv_jira_rss', verlist)
except Exception:
traceback.print_exc()