✨ v0.3.5 支持原神猜语音小游戏
This commit is contained in:
parent
bf1ff94f00
commit
cbc3897bbd
198
assets/voice/character.json
Normal file
198
assets/voice/character.json
Normal file
@ -0,0 +1,198 @@
|
||||
{
|
||||
"神里绫华": [
|
||||
"神里",
|
||||
"758"
|
||||
],
|
||||
"迪卢克": [
|
||||
"计量单位",
|
||||
"迪卢克",
|
||||
"卢老爷",
|
||||
"卢姥爷",
|
||||
"卢锅巴",
|
||||
"正义人",
|
||||
"暗夜英雄"
|
||||
],
|
||||
"七七": [
|
||||
"77",
|
||||
"肚饿真君",
|
||||
"度厄真君",
|
||||
"四十九",
|
||||
"49"
|
||||
],
|
||||
"丽莎": [
|
||||
"图书管理员"
|
||||
],
|
||||
"凝光": [
|
||||
"富婆",
|
||||
"天权星"
|
||||
],
|
||||
"刻晴": [
|
||||
"刻师傅",
|
||||
"玉衡星",
|
||||
"屁斜剑法",
|
||||
"啊晴"
|
||||
],
|
||||
"可莉": [
|
||||
"kelee",
|
||||
"蹦蹦八个蛋",
|
||||
"火花骑士",
|
||||
"炸鱼禁闭真君",
|
||||
"哒哒哒"
|
||||
],
|
||||
"旅行者": [
|
||||
"爷",
|
||||
"卑鄙的外乡人",
|
||||
"荣誉骑士"
|
||||
],
|
||||
"枫原万叶": [
|
||||
"万叶",
|
||||
"风男"
|
||||
],
|
||||
"温迪": [
|
||||
"诶嘿",
|
||||
"卖唱的",
|
||||
"巴巴托斯",
|
||||
"风神"
|
||||
],
|
||||
"烟绯": [
|
||||
"璃月罗翔"
|
||||
],
|
||||
"班尼特": [
|
||||
"点赞",
|
||||
"六星战神",
|
||||
"点赞哥"
|
||||
],
|
||||
"琴": [
|
||||
"代理团长",
|
||||
"蒙德砍王",
|
||||
"琴团长"
|
||||
],
|
||||
"砂糖": [
|
||||
"雷莹术士"
|
||||
],
|
||||
"胡桃": [
|
||||
"往生堂堂主",
|
||||
"堂主",
|
||||
"核桃",
|
||||
"胡堂主"
|
||||
],
|
||||
"芭芭拉": [
|
||||
"内鬼",
|
||||
"加湿器",
|
||||
"偶像"
|
||||
],
|
||||
"莫娜": [
|
||||
"半部讨龙真君"
|
||||
],
|
||||
"菲谢尔": [
|
||||
"艾咪",
|
||||
"小艾咪",
|
||||
"皇女",
|
||||
"奥兹发射器"
|
||||
],
|
||||
"行秋": [
|
||||
"秋妹妹"
|
||||
],
|
||||
"达达利亚": [
|
||||
"钱包",
|
||||
"ATM机",
|
||||
"达达鸭",
|
||||
"公子",
|
||||
"达达利鸭"
|
||||
],
|
||||
"迪奥娜": [
|
||||
"猫猫",
|
||||
"猫娘",
|
||||
"DIO娜",
|
||||
"dio"
|
||||
],
|
||||
"重云": [
|
||||
"冰元素附魔器"
|
||||
],
|
||||
"钟离": [
|
||||
"帝君",
|
||||
"未来可期真君",
|
||||
"社会废人",
|
||||
"契约之神",
|
||||
"七天神像的噩梦",
|
||||
"岩王帝君",
|
||||
"岩王爷"
|
||||
],
|
||||
"雷泽": [
|
||||
"狼崽"
|
||||
],
|
||||
"香菱": [
|
||||
"锅巴发射器",
|
||||
"香师傅"
|
||||
],
|
||||
"魈": [
|
||||
"快乐风男",
|
||||
"打桩机",
|
||||
"降魔大圣",
|
||||
"护法夜叉大将",
|
||||
"魈大人"
|
||||
],
|
||||
"阿贝多": [
|
||||
"电梯人",
|
||||
"白垩之子",
|
||||
"abd"
|
||||
],
|
||||
"甘雨": [
|
||||
"王小美",
|
||||
"椰羊"
|
||||
],
|
||||
"优菈": [
|
||||
"游击小队队长",
|
||||
"尤拉"
|
||||
],
|
||||
"北斗": [
|
||||
"大姐头"
|
||||
],
|
||||
"安柏": [
|
||||
"打火姬",
|
||||
"侦察骑士"
|
||||
],
|
||||
"凯亚": [
|
||||
"凯子",
|
||||
"凯子哥",
|
||||
"矿工头子"
|
||||
],
|
||||
"诺艾尔": [
|
||||
"冰莹术士",
|
||||
"女仆"
|
||||
],
|
||||
"辛焱": [
|
||||
"黑妹"
|
||||
],
|
||||
"罗莎莉亚": [
|
||||
"修女"
|
||||
],
|
||||
"留云借风真君": [
|
||||
"傲娇真君"
|
||||
],
|
||||
"雷电将军": [
|
||||
"雷神",
|
||||
"将军"
|
||||
],
|
||||
"珊瑚宫心海": [
|
||||
"心海"
|
||||
],
|
||||
"戴因斯雷布": [
|
||||
"大派蒙"
|
||||
],
|
||||
"丘丘人":[
|
||||
"qq人"
|
||||
],
|
||||
"???": [
|
||||
"???"
|
||||
],
|
||||
"「愚人众」守卫": [
|
||||
"愚人众守卫"
|
||||
],
|
||||
"「怪鸟」": [
|
||||
"怪鸟"
|
||||
],
|
||||
"观察「大盗宝家」":[
|
||||
"大盗宝家"
|
||||
]
|
||||
}
|
1
ci.py
1
ci.py
@ -9,6 +9,7 @@ bot_token: str = ""
|
||||
admin_id: int = 0
|
||||
bot_token = config.get("basic", "bot_token", fallback=bot_token)
|
||||
admin_id = config.getint("basic", "admin", fallback=admin_id)
|
||||
guess_time = 30 # 猜语音游戏持续时间
|
||||
""" Init httpx client """
|
||||
# 使用自定义 UA
|
||||
headers = {
|
||||
|
192
defs/guess_voice.py
Normal file
192
defs/guess_voice.py
Normal file
@ -0,0 +1,192 @@
|
||||
import os
|
||||
import random
|
||||
import datetime
|
||||
import json
|
||||
import traceback
|
||||
from os.path import exists
|
||||
|
||||
from apscheduler.triggers.date import DateTrigger
|
||||
from pyrogram import Client
|
||||
from pyrogram.types import Message
|
||||
from sqlitedict import SqliteDict
|
||||
|
||||
from ci import scheduler, app
|
||||
|
||||
data_path = os.path.join("assets", "voice")
|
||||
|
||||
|
||||
def init_db(db_dir, db_name) -> SqliteDict:
|
||||
return SqliteDict(os.path.join(db_dir, db_name),
|
||||
encode=json.dumps,
|
||||
decode=json.loads,
|
||||
autocommit=True)
|
||||
|
||||
|
||||
def get_chars(data: list) -> list:
|
||||
data_ = []
|
||||
for i in data:
|
||||
char_name = i.split(" ")[0]
|
||||
if char_name not in data_:
|
||||
data_.append(i.split(" ")[0])
|
||||
return data_
|
||||
|
||||
|
||||
def get_key_list(data: list, key: str) -> list:
|
||||
# 获取包含key的数据
|
||||
data_ = []
|
||||
for i in data:
|
||||
if key in i:
|
||||
data_.append(i)
|
||||
return data_
|
||||
|
||||
|
||||
def choice_voice(data: list) -> str:
|
||||
long_key = ['感兴趣的见闻', '关于神之眼', '生日', '爱好', '讨厌的食物', '想要了解', '有什么想要分享',
|
||||
'突破的感觉', '喜欢的食物', '烦恼', '角色待机', '角色死亡']
|
||||
data_ = []
|
||||
for i in data:
|
||||
for k in long_key:
|
||||
if k in i:
|
||||
data_.append(i)
|
||||
if not data_:
|
||||
return ""
|
||||
return random.choice(data_)
|
||||
|
||||
|
||||
user_db = init_db('temp', 'guess_voice.sqlite')
|
||||
process = {}
|
||||
|
||||
|
||||
with open(os.path.join(data_path, 'character.json'), 'r', encoding="utf-8") as f:
|
||||
character_json: dict = json.loads(f.read())
|
||||
|
||||
|
||||
def char_name_by_name(name):
|
||||
names = character_json.keys()
|
||||
# 是否就是正确的名字
|
||||
if name in names:
|
||||
return name
|
||||
#
|
||||
for item in names:
|
||||
nickname = character_json[item]
|
||||
if name in nickname:
|
||||
return item
|
||||
return name
|
||||
|
||||
|
||||
class Guess:
|
||||
time: int
|
||||
group_id: int
|
||||
group = {}
|
||||
retry_count = 0
|
||||
|
||||
def __init__(self, group_id: int, time=30):
|
||||
self.time = time
|
||||
self.group_id = group_id
|
||||
self.group = process.get(self.group_id)
|
||||
|
||||
def is_start(self):
|
||||
if not self.group:
|
||||
return False
|
||||
return self.group['start']
|
||||
|
||||
def set_start(self):
|
||||
process[self.group_id] = {'start': True}
|
||||
|
||||
def set_end(self):
|
||||
process[self.group_id] = {}
|
||||
|
||||
async def start(self):
|
||||
if exists(f"assets{os.sep}voice{os.sep}voice.json"):
|
||||
with open(f"assets{os.sep}voice{os.sep}voice.json", "r", encoding='utf-8') as f:
|
||||
mys_list_raw = json.load(f)
|
||||
else:
|
||||
return "没有找到声音数据"
|
||||
mys_list = list(mys_list_raw.keys())
|
||||
if not mys_list:
|
||||
return "没有找到声音数据"
|
||||
chars = get_chars(mys_list)
|
||||
answer = random.choice(chars)
|
||||
file_id = get_key_list(mys_list, answer)
|
||||
file_id = choice_voice(file_id)
|
||||
if not file_id:
|
||||
return "没有找到声音数据"
|
||||
|
||||
# 记录答案
|
||||
process[self.group_id] = {
|
||||
'start': True,
|
||||
'answer': answer,
|
||||
'ok': set()
|
||||
}
|
||||
|
||||
job_id = str(self.group_id) + '_guess_voice'
|
||||
if scheduler.get_job(job_id, 'default'):
|
||||
scheduler.remove_job(job_id, 'default')
|
||||
|
||||
now = datetime.datetime.now()
|
||||
notify_time = now + datetime.timedelta(seconds=self.time)
|
||||
scheduler.add_job(self.end_game, trigger=DateTrigger(notify_time),
|
||||
id=job_id,
|
||||
misfire_grace_time=60,
|
||||
coalesce=True,
|
||||
jobstore='default',
|
||||
max_instances=1)
|
||||
|
||||
print('答案: ' + answer)
|
||||
return mys_list_raw[file_id]
|
||||
|
||||
async def end_game(self):
|
||||
self.group = process.get(self.group_id)
|
||||
|
||||
ok_list = list(process[self.group_id]['ok'])
|
||||
if len(ok_list) > 1: # 只允许1个人猜对
|
||||
return
|
||||
if not ok_list:
|
||||
msg = '还没有人猜中呢'
|
||||
else:
|
||||
msg = '回答正确的人: ' + ' '.join([f"[{qq}](tg://user?id={qq})" for qq in ok_list])
|
||||
msg = '正确答案是 %s\n%s' % (self.group['answer'], msg)
|
||||
try:
|
||||
await app.send_message(self.group_id, msg)
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
|
||||
# 清理记录
|
||||
process[self.group_id] = {}
|
||||
|
||||
# 记录到数据库给之后奖励做处理
|
||||
user_group = user_db.get(self.group_id, {})
|
||||
if not user_group:
|
||||
user_db[self.group_id] = {}
|
||||
|
||||
for user in ok_list:
|
||||
info = user_group.get(str(user), {'count': 0})
|
||||
info['count'] += 1
|
||||
user_group[user] = info
|
||||
user_db[self.group_id] = user_group
|
||||
|
||||
# 只添加正确的答案
|
||||
async def add_answer(self, qq: int, msg: str):
|
||||
if self.group.get('answer') and char_name_by_name(msg) == self.group['answer']:
|
||||
process[self.group_id]['ok'].add(qq)
|
||||
job_id = str(self.group_id)
|
||||
if scheduler.get_job(job_id + '_guess_voice', 'default'):
|
||||
scheduler.remove_job(job_id + '_guess_voice', 'default')
|
||||
await self.end_game()
|
||||
|
||||
# 获取排行榜
|
||||
async def get_rank(self, client: Client, message: Message):
|
||||
user_list = user_db.get(self.group_id, {})
|
||||
|
||||
user_list = sorted(user_list.items(), key=lambda v: v[1]['count'])
|
||||
user_list.reverse()
|
||||
num = 0
|
||||
msg = '本群猜语音排行榜:'
|
||||
for user, data in user_list[:10]:
|
||||
try:
|
||||
user = (await client.get_users(int(user))).first_name
|
||||
except:
|
||||
user = str(user)
|
||||
num += 1
|
||||
msg += f"\n第{num}名: {user}, 猜对{data['count']}次"
|
||||
return msg
|
32
plugins/guess_voice.py
Normal file
32
plugins/guess_voice.py
Normal file
@ -0,0 +1,32 @@
|
||||
from pyrogram import Client
|
||||
from pyrogram.types import Message
|
||||
|
||||
from ci import guess_time
|
||||
from defs.guess_voice import Guess
|
||||
|
||||
|
||||
async def guess_voice(client: Client, message: Message):
|
||||
text = message.text.replace("原神猜语音", "")
|
||||
guess = Guess(message.chat.id, time=guess_time)
|
||||
if text == "排行榜":
|
||||
return await message.reply(await guess.get_rank(client, message))
|
||||
if guess.is_start():
|
||||
return await message.reply('游戏正在进行中哦')
|
||||
guess.set_start()
|
||||
await message.reply(f'即将发送一段原神语音,将在 <b>{guess_time}秒</b> 后公布答案')
|
||||
try:
|
||||
msg = await guess.start()
|
||||
if msg == "没有找到声音数据":
|
||||
await message.reply(msg)
|
||||
else:
|
||||
await client.send_voice(message.chat.id, msg)
|
||||
except Exception as e:
|
||||
guess.set_end()
|
||||
await message.reply("出现未知错误,请联系管理员")
|
||||
|
||||
|
||||
async def process_guess(client: Client, message: Message):
|
||||
msg = message.text
|
||||
guess = Guess(message.chat.id, time=guess_time)
|
||||
if guess.is_start():
|
||||
await guess.add_answer(message.from_user.id, msg)
|
@ -7,7 +7,9 @@ from pyrogram.types import Message, InlineQuery, CallbackQuery
|
||||
from pyrogram import filters as Filters
|
||||
|
||||
from ci import me
|
||||
from defs.guess_voice import get_chars
|
||||
from plugins.enemies import enemies_msg
|
||||
from plugins.guess_voice import guess_voice, process_guess
|
||||
from plugins.mys2 import mys2_msg, mys2_qun_msg
|
||||
from plugins.mihoyo import mihoyo_msg, mihoyo_qun_msg
|
||||
from plugins.start import welcome_command, ping_command, help_command, leave_command, help_callback
|
||||
@ -192,6 +194,10 @@ async def process_group_msg(client: Client, message: Message):
|
||||
await mys2_qun_msg(client, message)
|
||||
if text.startswith('mihoyo'):
|
||||
await mihoyo_qun_msg(client, message)
|
||||
if text.startswith("原神猜语音"):
|
||||
await guess_voice(client, message)
|
||||
# 处理猜语音游戏
|
||||
await process_guess(client, message)
|
||||
|
||||
|
||||
@Client.on_message(Filters.photo)
|
||||
@ -247,6 +253,7 @@ voice_data = None
|
||||
if exists(f"assets{sep}voice{sep}voice.json"):
|
||||
with open(f"assets{sep}voice{sep}voice.json", "r", encoding='utf-8') as f:
|
||||
voice_data = json.load(f)
|
||||
chara_count = len(get_chars(voice_data))
|
||||
|
||||
|
||||
@Client.on_inline_query()
|
||||
@ -257,10 +264,15 @@ async def inline_process(client: Client, query: InlineQuery):
|
||||
if not voice_data:
|
||||
return
|
||||
data_ = voice_data
|
||||
data__ = []
|
||||
for index, value in enumerate(data_):
|
||||
if len(text) == 0:
|
||||
chara_name = value.split(" ")[0]
|
||||
if chara_name in data__:
|
||||
continue
|
||||
data.append(InlineQueryResultCachedDocument(value, file_id=data_[value], caption=value))
|
||||
nums += 1
|
||||
data__.append(chara_name)
|
||||
else:
|
||||
skip = False
|
||||
for i in text:
|
||||
@ -269,12 +281,14 @@ async def inline_process(client: Client, query: InlineQuery):
|
||||
if not skip:
|
||||
data.append(InlineQueryResultCachedDocument(value, file_id=data_[value], caption=value))
|
||||
nums += 1
|
||||
if nums >= 25:
|
||||
if nums >= 30:
|
||||
break
|
||||
if nums == 0:
|
||||
return await query.answer(
|
||||
results=[],
|
||||
switch_pm_text=f'{emoji.CROSS_MARK} 字符串 "{" ".join(text)}" 没有搜索到任何结果',
|
||||
switch_pm_parameter="start",
|
||||
switch_pm_parameter="help",
|
||||
)
|
||||
await query.answer(data)
|
||||
await query.answer(data,
|
||||
switch_pm_text=f'{emoji.KEY} 目前已经索引了 {chara_count} 个角色',
|
||||
switch_pm_parameter="help",)
|
||||
|
@ -2,7 +2,7 @@ from ci import admin_id
|
||||
from pyrogram import Client
|
||||
from pyrogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
|
||||
HELP_MSG_PRE = '<a href="https://git.io/JcbTD">PaimonBot</a> 0.3.4beta By Xtao-Labs\n\n' \
|
||||
HELP_MSG_PRE = '<a href="https://git.io/JcbTD">PaimonBot</a> 0.3.5beta By Xtao-Labs\n\n' \
|
||||
'🔅 以下是小派蒙我学会了的功能(部分):\n'
|
||||
HELP_MSG = """① [武器/今日武器] 查看今日武器材料和武器
|
||||
② [天赋/今日天赋] 查看今日天赋材料和角色
|
||||
@ -16,11 +16,11 @@ HELP_MSG = """① [武器/今日武器] 查看今日武器材料和武器
|
||||
💠 <code>命座 重云一命</code>
|
||||
⑦ [武器查询 武器名] 查看武器资料
|
||||
💠 <code>武器查询 沐浴龙血的剑</code>
|
||||
⑧ [原魔查询] 查看原魔资料
|
||||
⑧ [原魔查询 原魔名] 查看原魔资料
|
||||
💠 <code>原魔查询 丘丘人</code>
|
||||
⑨ [食物查询] 查看食物资料
|
||||
⑨ [食物查询 食物/食材名] 查看食物资料
|
||||
💠 <code>食物查询 甜甜花/甜甜花酿鸡</code>
|
||||
⑩ [圣遗物查询 武器名] 查看武器资料
|
||||
⑩ [圣遗物查询 圣遗物套装名] 查看圣遗物套装资料
|
||||
💠 <code>圣遗物查询 逆飞的流星</code>
|
||||
======
|
||||
(11) [原神黄历] 查看随机生成的原神黄历
|
||||
@ -28,7 +28,8 @@ HELP_MSG = """① [武器/今日武器] 查看今日武器材料和武器
|
||||
(13) [圣遗物评分] 我也想拥有这种分数的圣遗物(切实)
|
||||
(14) [哪里有 (资源名)] 查看资源的位置
|
||||
(15) [资源列表] 查看原神所有资源(私聊)
|
||||
(16) [米游社/mihoyo] 米游社/mihoyo相关功能(替换)
|
||||
(16) [原神猜语音] 和群友一起玩猜语音小游戏吧!(群聊)
|
||||
(17) [米游社/mihoyo] 米游社/mihoyo相关功能(替换)
|
||||
💠 <code>米游社添加(私聊)</code>
|
||||
💠 <code>米游社推送开启/关闭</code>
|
||||
💠 <code>米游社自动签到开启/关闭</code>
|
||||
|
@ -11,4 +11,5 @@ pyyaml>=6.0
|
||||
httpx>=0.18.1
|
||||
apscheduler>=3.8.1
|
||||
wordcloud>=1.8.1
|
||||
numpy
|
||||
numpy
|
||||
sqlitedict
|
||||
|
Loading…
Reference in New Issue
Block a user