Archived
1
0
Fork 0
This repository has been archived on 2024-04-26. You can view files and clone it, but cannot push or open issues or pull requests.
akari-bot/modules/maimai/__init__.py

277 lines
11 KiB
Python
Raw Normal View History

2021-10-12 15:02:36 +00:00
import re
2023-02-05 14:33:33 +00:00
from core.builtins import Bot, Plain, Image as BImage
2023-03-04 08:51:56 +00:00
from core.component import module
2022-08-04 07:52:42 +00:00
from core.logger import Logger
2021-10-12 15:02:36 +00:00
from modules.maimai.libraries.image import *
from modules.maimai.libraries.maimai_best_40 import generate
2022-07-12 17:27:34 +00:00
from modules.maimai.libraries.maimai_best_50 import generate50
2021-11-12 14:25:53 +00:00
from modules.maimai.libraries.maimaidx_music import *
2023-03-04 08:51:56 +00:00
from modules.maimai.libraries.tool import hash_
2021-10-12 15:02:36 +00:00
2022-05-13 13:54:12 +00:00
total_list = TotalList()
2023-05-21 06:41:50 +00:00
wm_list = ['拼机', '推分', '越级', '下埋', '夜勤', '练底力', '练手法', '打旧框', '干饭', '抓绝赞', '收歌']
2022-05-13 13:54:12 +00:00
2021-10-12 15:02:36 +00:00
def song_txt(music: Music):
return [Plain(f"{music.id}. {music.title}\n"),
2022-07-12 17:27:34 +00:00
BImage(f"https://www.diving-fish.com/covers/{get_cover_len4_id(music.id)}.png", ),
2021-10-12 15:02:36 +00:00
Plain(f"\n{'/'.join(music.level)}")]
2022-05-13 13:54:12 +00:00
async def inner_level_q(ds1, ds2=None):
2021-10-12 15:02:36 +00:00
result_set = []
diff_label = ['Bas', 'Adv', 'Exp', 'Mst', 'ReM']
if ds2 is not None:
2022-05-13 13:54:12 +00:00
music_data = (await total_list.get()).filter(ds=(ds1, ds2))
2021-10-12 15:02:36 +00:00
else:
2022-05-13 13:54:12 +00:00
music_data = (await total_list.get()).filter(ds=ds1)
2021-10-24 10:55:45 +00:00
for music in sorted(music_data, key=lambda i: int(i['id'])):
2021-10-12 15:02:36 +00:00
for i in music.diff:
result_set.append((music['id'], music['title'], music['ds'][i], diff_label[i], music['level'][i]))
return result_set
2023-03-04 08:51:56 +00:00
mai = module('maimai', developers=['mai-bot', 'OasisAkari'], alias=['mai'],
2023-05-21 06:41:50 +00:00
desc='{maimai.help.desc}')
2021-10-24 10:55:45 +00:00
2023-05-27 09:19:33 +00:00
@mai.handle('inner <rating> [<rating_max>] {{maimai.help.inner}}')
2023-02-05 14:33:33 +00:00
async def _(msg: Bot.MessageSession):
2023-05-27 09:19:33 +00:00
rating = msg.parsed_msg['<rating>']
rating_max = msg.parsed_msg['<rating_max>']
2023-05-27 09:26:34 +00:00
if '<rating_max>' not in msg.parsed_msg:
2023-05-27 09:27:33 +00:00
result_set = [msg.finish(msg.locale.t('maimai.message.inline', rating=rating))]
2023-05-27 09:19:33 +00:00
result_set += await inner_level_q(float(rating))
2021-10-12 15:02:36 +00:00
else:
2023-05-27 09:26:34 +00:00
result_set = [msg.finish(msg.locale.t('maimai.message.inline.range', rating=rating, rating_max=rating_max))]
2023-05-27 09:19:33 +00:00
result_set += await inner_level_q(float(rating), float(rating_max))
2021-10-12 15:02:36 +00:00
s = ""
for elem in result_set:
s += f"{elem[0]}. {elem[1]} {elem[3]} {elem[4]}({elem[2]})\n"
2023-05-27 03:33:49 +00:00
if len(result_set) > 150:
return await msg.finish(msg.locale.t("maimai.message.too_much", length=len(result_set)))
elif len(result_set) > 50:
img = text_to_image(s)
if img:
await msg.finish([BImage(img)])
else:
await msg.finish(s.strip())
2021-10-12 15:02:36 +00:00
2023-05-27 03:20:04 +00:00
# @mai.handle('today {{maimai.help.today}}')
# async def _(msg: Bot.MessageSession):
# if msg.target.senderFrom == "Discord|Client":
# qq = msg.session.sender.id
# else:
# qq = msg.session.sender
# h = hash_(qq)
# rp = h % 100
# wm_value = []
# for i in range(11):
# wm_value.append(h & 3)
# h >>= 2
# s = f"今日人品值:{rp}\n"
# for i in range(11):
# if wm_value[i] == 3:
# s += f'宜 {wm_list[i]}\n'
# elif wm_value[i] == 0:
# s += f'忌 {wm_list[i]}\n'
# s += "刘大鸽提醒您:打机时不要大力拍打或滑动哦\n今日推荐歌曲"
# music = (await total_list.get())[h % len((await total_list.get()))]
# await msg.finish([Plain(s)] + song_txt(music))
2021-10-12 15:02:36 +00:00
2022-05-13 13:54:12 +00:00
@mai.handle(['scoreline <difficulty+sid> <scoreline> {查找某首歌的分数线}',
'scoreline help {查看分数线帮助}'])
2023-02-05 14:33:33 +00:00
async def _(msg: Bot.MessageSession):
2021-10-12 15:02:36 +00:00
r = "([绿黄红紫白])(id)?([0-9]+)"
2022-08-12 08:36:55 +00:00
arg1 = msg.parsed_msg.get('<difficulty+sid>')
args2 = msg.parsed_msg.get('<scoreline>')
argh = msg.parsed_msg.get('help', False)
2021-10-12 15:02:36 +00:00
if argh:
s = '''此功能为查找某首歌分数线设计。
2022-05-13 13:54:12 +00:00
命令格式maimai scoreline <difficulty+sid> <scoreline>
2021-10-12 15:02:36 +00:00
例如分数线 紫799 100
命令将返回分数线允许的 TAP GREAT 容错以及 BREAK 50落等价的 TAP GREAT
以下为 TAP GREAT 的对应表
GREAT/GOOD/MISS
TAP\t1/2.5/5
HOLD\t2/5/10
SLIDE\t3/7.5/15
TOUCH\t1/2.5/5
BREAK\t5/12.5/25(外加200落)'''
2022-05-22 15:10:24 +00:00
img = text_to_image(s)
if img:
await msg.finish([BImage(img)])
2021-10-12 15:02:36 +00:00
elif args2 is not None:
try:
grp = re.match(r, arg1).groups()
level_labels = ['绿', '', '', '', '']
level_labels2 = ['Basic', 'Advanced', 'Expert', 'Master', 'Re:MASTER']
level_index = level_labels.index(grp[0])
chart_id = grp[2]
line = float(arg1)
2022-05-13 13:54:12 +00:00
music = (await total_list.get()).by_id(chart_id)
2021-10-12 15:02:36 +00:00
chart: Dict[Any] = music['charts'][level_index]
tap = int(chart['notes'][0])
slide = int(chart['notes'][2])
hold = int(chart['notes'][1])
touch = int(chart['notes'][3]) if len(chart['notes']) == 5 else 0
brk = int(chart['notes'][-1])
total_score = 500 * tap + slide * 1500 + hold * 1000 + touch * 500 + brk * 2500
break_bonus = 0.01 / brk
break_50_reduce = total_score * break_bonus / 4
reduce = 101 - line
if reduce <= 0 or reduce >= 101:
raise ValueError
2022-05-21 16:04:29 +00:00
await msg.finish(f'''{music['title']} {level_labels2[level_index]}
2021-10-12 15:02:36 +00:00
分数线 {line}% 允许的最多 TAP GREAT 数量为 {(total_score * reduce / 10000):.2f}(每个-{10000 / total_score:.4f}%),
BREAK 50(一共{brk})等价于 {(break_50_reduce / 100):.3f} TAP GREAT(-{break_50_reduce / total_score * 100:.4f}%)''')
except Exception:
2022-05-21 16:04:29 +00:00
await msg.finish("格式错误,输入“~maimai scoreline help”以查看帮助信息")
2021-10-12 15:02:36 +00:00
2023-05-21 06:41:50 +00:00
@mai.handle('b40 [<username>] {{maimai.help.b40}}')
2023-02-05 14:33:33 +00:00
async def _(msg: Bot.MessageSession):
2023-05-19 14:56:46 +00:00
username = msg.parsed_msg.get('<username>', None)
2023-05-19 15:00:36 +00:00
if username is None and msg.target.senderFrom == "QQ":
2021-10-12 15:02:36 +00:00
payload = {'qq': msg.session.sender}
else:
2023-05-19 15:00:36 +00:00
if username is None:
2023-05-21 06:41:50 +00:00
await msg.finish(msg.locale.t("maimai.message.no_username"))
2021-10-12 15:02:36 +00:00
payload = {'username': username}
img, success = await generate(payload)
if success == 400:
2023-05-21 06:41:50 +00:00
await msg.finish(msg.locale.t("maimai.message.not_found"))
2021-10-12 15:02:36 +00:00
elif success == 403:
2023-05-21 06:41:50 +00:00
await msg.finish(msg.locale.t("maimai.message.forbidden"))
2021-10-12 15:02:36 +00:00
else:
2022-05-22 14:12:30 +00:00
if img:
await msg.finish([BImage(img)])
2022-07-12 17:27:34 +00:00
2023-05-21 06:41:50 +00:00
@mai.handle('b50 [<username>] {{maimai.help.b50}}')
2023-02-05 14:33:33 +00:00
async def _(msg: Bot.MessageSession):
2023-05-19 14:56:46 +00:00
username = msg.parsed_msg.get('<username>', None)
2023-05-19 15:00:36 +00:00
if username is None and msg.target.senderFrom == "QQ":
2023-01-28 05:53:11 +00:00
payload = {'qq': msg.session.sender, 'b50': True}
2022-07-12 17:27:34 +00:00
else:
2023-05-19 15:00:36 +00:00
if username is None:
2023-05-21 06:41:50 +00:00
await msg.finish(msg.locale.t("maimai.message.no_username"))
2023-01-28 05:53:11 +00:00
payload = {'username': username, 'b50': True}
2023-05-24 14:40:58 +00:00
await msg.sendMessage(msg.locale.t("maimai.message.b50.waiting"))
2022-07-12 17:27:34 +00:00
img, success = await generate50(payload)
if success == 400:
2023-05-21 06:41:50 +00:00
await msg.finish(msg.locale.t("maimai.message.not_found"))
2022-07-12 17:27:34 +00:00
elif success == 403:
2023-05-21 06:41:50 +00:00
await msg.finish(msg.locale.t("maimai.message.forbidden"))
2022-07-12 17:27:34 +00:00
else:
if img:
await msg.finish([BImage(img)])
2023-05-21 06:41:50 +00:00
2023-05-27 03:20:04 +00:00
@mai.handle('random {{maimai.help.random}}')
2023-05-27 03:33:49 +00:00
@mai.handle(re.compile(r".*\s?(M|m)aimai\s?.*什么"), desc='{maimai.help.random}')
2023-05-27 03:20:04 +00:00
async def _(msg: Bot.MessageSession):
await msg.finish(song_txt((await total_list.get()).random()))
2023-05-21 06:41:50 +00:00
@mai.handle(re.compile(r"随个((?:dx|sd|标准))?([绿黄红紫白]?)([0-9]+\+?)"),
desc="随个[dx/标准][绿黄红紫白]<难度> 随机一首指定条件的乐曲")
async def _(msg: Bot.MessageSession):
res = msg.matched_msg
if res:
try:
if res.groups()[0] == "dx":
tp = ["DX"]
elif res.groups()[0] == "sd" or res.groups()[0] == "标准":
tp = ["SD"]
else:
tp = ["SD", "DX"]
level = res.groups()[2]
if res.groups()[1] == "":
music_data = (await total_list.get()).filter(level=level, type=tp)
else:
music_data = (await total_list.get()).filter(level=level, diff=['绿黄红紫白'.index(res.groups()[1])],
type=tp)
if len(music_data) == 0:
rand_result = "没有这样的乐曲哦。"
else:
rand_result = song_txt(music_data.random())
await msg.finish(rand_result)
except Exception as e:
Logger.error(e)
await msg.finish("随机命令错误,请检查语法")
@mai.handle(re.compile(r"查歌(.+)"), desc='查歌<乐曲标题的一部分> 查询符合条件的乐曲')
async def _(msg: Bot.MessageSession):
name = msg.matched_msg.groups()[0].strip()
if name == "":
return
res = (await total_list.get()).filter(title_search=name)
if len(res) == 0:
await msg.finish("没有找到这样的乐曲。")
elif len(res) < 50:
search_result = ""
for music in sorted(res, key=lambda i: int(i['id'])):
search_result += f"{music['id']}. {music['title']}\n"
await msg.finish([Plain(search_result.strip())])
else:
await msg.finish(f"结果过多({len(res)} 条),请缩小查询范围。")
@mai.handle(re.compile(r"([绿黄红紫白]?)id([0-9]+)"), desc='[绿黄红紫白]id<歌曲编号> 查询乐曲信息或谱面信息')
async def _(message: Bot.MessageSession):
groups = message.matched_msg.groups()
level_labels = ['绿', '', '', '', '']
if groups[0] != "":
try:
level_index = level_labels.index(groups[0])
level_name = ['Basic', 'Advanced', 'Expert', 'Master', 'Re: MASTER']
name = groups[1]
music = (await total_list.get()).by_id(name)
chart = music['charts'][level_index]
ds = music['ds'][level_index]
level = music['level'][level_index]
file = f"https://www.diving-fish.com/covers/{get_cover_len4_id(music['id'])}.png"
if len(chart['notes']) == 4:
msg = f'''{level_name[level_index]} {level}({ds})
TAP: {chart['notes'][0]}
HOLD: {chart['notes'][1]}
SLIDE: {chart['notes'][2]}
BREAK: {chart['notes'][3]}
谱师: {chart['charter']}'''
else:
msg = f'''{level_name[level_index]} {level}({ds})
TAP: {chart['notes'][0]}
HOLD: {chart['notes'][1]}
SLIDE: {chart['notes'][2]}
TOUCH: {chart['notes'][3]}
BREAK: {chart['notes'][4]}
谱师: {chart['charter']}'''
await message.finish([Plain(f"{music['id']}. {music['title']}\n"), BImage(f"{file}"), Plain(msg)])
except Exception:
await message.finish("未找到该谱面")
else:
name = groups[1]
music = (await total_list.get()).by_id(name)
try:
file = f"https://www.diving-fish.com/covers/{get_cover_len4_id(music['id'])}.png"
await message.finish([Plain(f"{music['id']}. {music['title']}\n"),
BImage(f"{file}"),
Plain(f"艺术家: {music['basic_info']['artist']}\n"
f"分类: {music['basic_info']['genre']}\n"
f"BPM: {music['basic_info']['bpm']}\n"
f"版本: {music['basic_info']['from']}\n"
f"难度: {'/'.join(music['level'])}")])
except Exception:
await message.finish("未找到该乐曲")