mirror of
https://github.com/xuthus83/LittlePaimon.git
synced 2025-04-12 23:29:37 +08:00
🐛 修复Web UI
中配置项修改后不生效的问题,优化UID记录逻辑
This commit is contained in:
parent
c8c0ed4b7a
commit
4375a835e1
@ -1,4 +1,2 @@
|
|||||||
from .config.manage import ConfigManager, ConfigModel
|
from .config.manage import ConfigManager, ConfigModel, config
|
||||||
from .plugin.manage import PluginManager, HIDDEN_PLUGINS, MatcherInfo, PluginInfo
|
from .plugin.manage import PluginManager, HIDDEN_PLUGINS, MatcherInfo, PluginInfo
|
||||||
|
|
||||||
config = ConfigManager.config
|
|
||||||
|
@ -25,8 +25,13 @@ class ConfigManager:
|
|||||||
value = value in ['开', 'true', 'on']
|
value = value in ['开', 'true', 'on']
|
||||||
elif config_name != 'CookieWeb地址' and not value.isdigit():
|
elif config_name != 'CookieWeb地址' and not value.isdigit():
|
||||||
return '配置项不合法,必须为数字'
|
return '配置项不合法,必须为数字'
|
||||||
temp = cls.config.dict(by_alias=True)
|
cls.config.update(config_name=value)
|
||||||
temp[config_name] = value
|
cls.save()
|
||||||
cls.config = ConfigModel.parse_obj(temp)
|
|
||||||
save_yaml(cls.config.dict(by_alias=True), PAIMON_CONFIG)
|
|
||||||
return f'成功设置{config_name}为{value}'
|
return f'成功设置{config_name}为{value}'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def save(cls):
|
||||||
|
save_yaml(cls.config.dict(by_alias=True), PAIMON_CONFIG)
|
||||||
|
|
||||||
|
|
||||||
|
config = ConfigManager.config
|
||||||
|
@ -41,3 +41,14 @@ class ConfigModel(BaseModel):
|
|||||||
admin_enable: bool = Field(True, alias='启用Web端')
|
admin_enable: bool = Field(True, alias='启用Web端')
|
||||||
admin_password: str = Field('admin', alias='Web端管理员密码')
|
admin_password: str = Field('admin', alias='Web端管理员密码')
|
||||||
secret_key: str = Field('49c294d32f69b732ef6447c18379451ce1738922a75cd1d4812ef150318a2ed0', alias='Web端token密钥')
|
secret_key: str = Field('49c294d32f69b732ef6447c18379451ce1738922a75cd1d4812ef150318a2ed0', alias='Web端token密钥')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def alias_dict(self):
|
||||||
|
return {v.alias: k for k, v in self.__fields__.items()}
|
||||||
|
|
||||||
|
def update(self, **kwargs):
|
||||||
|
for key, value in kwargs.items():
|
||||||
|
if key in self.__fields__:
|
||||||
|
self.__setattr__(key, value)
|
||||||
|
elif key in self.alias_dict:
|
||||||
|
self.__setattr__(self.alias_dict[key], value)
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
"10000070": ["妮露", "舞女"],
|
"10000070": ["妮露", "舞女"],
|
||||||
"10000071": ["赛诺", "风纪官"],
|
"10000071": ["赛诺", "风纪官"],
|
||||||
"10000072": ["坎蒂丝", "潘森"],
|
"10000072": ["坎蒂丝", "潘森"],
|
||||||
"10000073": ["纳西妲", "草神", "艹神", "小草王", "小吉祥草王", "草萝莉", "艹萝莉"],
|
"10000073": ["纳西妲", "草神", "艹神", "小草王", "小吉祥草王", "草萝莉", "艹萝莉", "羽毛球"],
|
||||||
"10000074": ["莱依拉", "莱伊拉"],
|
"10000074": ["莱依拉", "莱伊拉"],
|
||||||
"10000075": ["散兵", "伞兵", "国崩", "卢本伟", "大炮", "sb", "流浪者"],
|
"10000075": ["散兵", "伞兵", "国崩", "卢本伟", "大炮", "sb", "流浪者"],
|
||||||
"10000103": ["迪希雅"],
|
"10000103": ["迪希雅"],
|
||||||
|
@ -58,6 +58,21 @@ class LastQuery(Model):
|
|||||||
table = 'last_query'
|
table = 'last_query'
|
||||||
table_description = '用户最后查询的uid'
|
table_description = '用户最后查询的uid'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def update_last_query(cls, user_id: str, uid: str):
|
||||||
|
"""
|
||||||
|
更新用户最后查询的uid
|
||||||
|
:param user_id: 用户id
|
||||||
|
:param uid: 原神uid
|
||||||
|
"""
|
||||||
|
if await PrivateCookie.filter(user_id=user_id).exists():
|
||||||
|
if await PrivateCookie.filter(user_id=user_id, uid=uid).exists():
|
||||||
|
await LastQuery.update_or_create(user_id=user_id,
|
||||||
|
defaults={'uid': uid, 'last_time': datetime.datetime.now()})
|
||||||
|
else:
|
||||||
|
await LastQuery.update_or_create(user_id=user_id,
|
||||||
|
defaults={'uid': uid, 'last_time': datetime.datetime.now()})
|
||||||
|
|
||||||
|
|
||||||
class CookieCache(Model):
|
class CookieCache(Model):
|
||||||
"""
|
"""
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import datetime
|
import datetime
|
||||||
from collections import defaultdict
|
from collections import Counter
|
||||||
from typing import Dict, Any, Tuple
|
from typing import Dict, Any, Tuple
|
||||||
|
|
||||||
import pytz
|
import pytz
|
||||||
@ -33,7 +33,6 @@ async def get_group_avatar(group_id: str):
|
|||||||
return PMImage(size=(110, 110), color=(255, 255, 255, 255))
|
return PMImage(size=(110, 110), color=(255, 255, 255, 255))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def get_statistics(group_id: int):
|
async def get_statistics(group_id: int):
|
||||||
if not (info_list := await AbyssInfo.all()):
|
if not (info_list := await AbyssInfo.all()):
|
||||||
return '本群还没有深渊战斗数据哦!'
|
return '本群还没有深渊战斗数据哦!'
|
||||||
@ -99,10 +98,10 @@ async def get_statistics(group_id: int):
|
|||||||
} for info in max_take_damage[:3]
|
} for info in max_take_damage[:3]
|
||||||
]
|
]
|
||||||
# 11、12层阵容
|
# 11、12层阵容
|
||||||
battle_characters_up11 = defaultdict(lambda: 0)
|
battle_characters_up11 = Counter()
|
||||||
battle_characters_down11 = defaultdict(lambda: 0)
|
battle_characters_down11 = Counter()
|
||||||
battle_characters_up12 = defaultdict(lambda: 0)
|
battle_characters_up12 = Counter()
|
||||||
battle_characters_down12 = defaultdict(lambda: 0)
|
battle_characters_down12 = Counter()
|
||||||
for info in info_list:
|
for info in info_list:
|
||||||
if floor11 := info.floors.get(11):
|
if floor11 := info.floors.get(11):
|
||||||
for battles in floor11.battles_up:
|
for battles in floor11.battles_up:
|
||||||
@ -118,10 +117,10 @@ async def get_statistics(group_id: int):
|
|||||||
for battles in floor12.battles_down:
|
for battles in floor12.battles_down:
|
||||||
for character in battles.characters:
|
for character in battles.characters:
|
||||||
battle_characters_down12[f'{character.icon}-{character.rarity}'] += 1
|
battle_characters_down12[f'{character.icon}-{character.rarity}'] += 1
|
||||||
data['11层上半'] = sorted(battle_characters_up11.items(), key=lambda x: x[1], reverse=True)[:4]
|
data['11层上半'] = battle_characters_up11.most_common(4)
|
||||||
data['11层下半'] = sorted(battle_characters_down11.items(), key=lambda x: x[1], reverse=True)[:4]
|
data['11层下半'] = battle_characters_down11.most_common(4)
|
||||||
data['12层上半'] = sorted(battle_characters_up12.items(), key=lambda x: x[1], reverse=True)[:4]
|
data['12层上半'] = battle_characters_up12.most_common(4)
|
||||||
data['12层下半'] = sorted(battle_characters_down12.items(), key=lambda x: x[1], reverse=True)[:4]
|
data['12层下半'] = battle_characters_down12.most_common(4)
|
||||||
return await draw_statistics_img(data)
|
return await draw_statistics_img(data)
|
||||||
|
|
||||||
|
|
||||||
@ -143,26 +142,32 @@ async def draw_statistics_img(data: Dict[str, Any]):
|
|||||||
1033, 195, fm.get('bahnschrift_regular.ttf', 30), '#8c4c2e', 'right')
|
1033, 195, fm.get('bahnschrift_regular.ttf', 30), '#8c4c2e', 'right')
|
||||||
await img.text(str(data['总人数']), (233, 352), 296, fm.get('bahnschrift_regular.ttf', 48), '#040404', 'center')
|
await img.text(str(data['总人数']), (233, 352), 296, fm.get('bahnschrift_regular.ttf', 48), '#040404', 'center')
|
||||||
await img.text(str(data['平均星数']), (492, 586), 296, fm.get('bahnschrift_regular.ttf', 48), '#040404', 'center')
|
await img.text(str(data['平均星数']), (492, 586), 296, fm.get('bahnschrift_regular.ttf', 48), '#040404', 'center')
|
||||||
await img.text(str(data['平均战斗次数']), (698, 840), 296, fm.get('bahnschrift_regular.ttf', 48), '#040404', 'center')
|
await img.text(str(data['平均战斗次数']), (698, 840), 296, fm.get('bahnschrift_regular.ttf', 48), '#040404',
|
||||||
|
'center')
|
||||||
# 满星人数
|
# 满星人数
|
||||||
full_num = [data['满星人数'] / data['总人数'], 1 - data['满星人数'] / data['总人数']]
|
full_num = [data['满星人数'] / data['总人数'], 1 - data['满星人数'] / data['总人数']]
|
||||||
now_used_width = 36
|
now_used_width = 36
|
||||||
if full_num[0] > 0.03:
|
if full_num[0] > 0.03:
|
||||||
await img.draw_rectangle((now_used_width, 402, now_used_width + int(1007 * full_num[0]), 449), '#b6d6f2')
|
await img.draw_rectangle((now_used_width, 402, now_used_width + int(1007 * full_num[0]), 449), '#b6d6f2')
|
||||||
await img.text(str(data['满星人数']), now_used_width + 18, 413, fm.get('bahnschrift_regular.ttf', 30), '#3d6e99')
|
await img.text(str(data['满星人数']), now_used_width + 18, 413, fm.get('bahnschrift_regular.ttf', 30),
|
||||||
|
'#3d6e99')
|
||||||
now_used_width += int(1007 * full_num[0])
|
now_used_width += int(1007 * full_num[0])
|
||||||
if full_num[1] > 0.03:
|
if full_num[1] > 0.03:
|
||||||
await img.draw_rectangle((now_used_width, 402, now_used_width + int(1007 * full_num[1]), 449), '#c8b6f2')
|
await img.draw_rectangle((now_used_width, 402, now_used_width + int(1007 * full_num[1]), 449), '#c8b6f2')
|
||||||
await img.text(str(data['总人数'] - data['满星人数']), now_used_width + 18, 413, fm.get('bahnschrift_regular.ttf', 30), '#593d99')
|
await img.text(str(data['总人数'] - data['满星人数']), now_used_width + 18, 413,
|
||||||
|
fm.get('bahnschrift_regular.ttf', 30), '#593d99')
|
||||||
# 最高伤害
|
# 最高伤害
|
||||||
await img.paste(box[f'{data["最高伤害"][0]["稀有度"]}big'], (39, 512))
|
await img.paste(box[f'{data["最高伤害"][0]["稀有度"]}big'], (39, 512))
|
||||||
await img.paste(box[f'{data["最高伤害"][1]["稀有度"]}small'], (39, 664))
|
await img.paste(box[f'{data["最高伤害"][1]["稀有度"]}small'], (39, 664))
|
||||||
await img.paste(box[f'{data["最高伤害"][2]["稀有度"]}small'], (296, 664))
|
await img.paste(box[f'{data["最高伤害"][2]["稀有度"]}small'], (296, 664))
|
||||||
await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高伤害"][0]["图标"]}.png', size=(124, 124)),
|
await img.paste(
|
||||||
|
await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高伤害"][0]["图标"]}.png', size=(124, 124)),
|
||||||
(44, 525))
|
(44, 525))
|
||||||
await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高伤害"][1]["图标"]}.png', size=(82, 82)),
|
await img.paste(
|
||||||
|
await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高伤害"][1]["图标"]}.png', size=(82, 82)),
|
||||||
(45, 673))
|
(45, 673))
|
||||||
await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高伤害"][2]["图标"]}.png', size=(82, 82)),
|
await img.paste(
|
||||||
|
await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高伤害"][2]["图标"]}.png', size=(82, 82)),
|
||||||
(300, 673))
|
(300, 673))
|
||||||
await img.paste(await get_user_avatar(data['最高伤害'][0]['qq号']), (112, 588))
|
await img.paste(await get_user_avatar(data['最高伤害'][0]['qq号']), (112, 588))
|
||||||
await img.paste(await get_user_avatar(data['最高伤害'][1]['qq号'], (42, 42)), (87, 713))
|
await img.paste(await get_user_avatar(data['最高伤害'][1]['qq号'], (42, 42)), (87, 713))
|
||||||
@ -181,11 +186,14 @@ async def draw_statistics_img(data: Dict[str, Any]):
|
|||||||
await img.paste(box[f'{data["最高承受伤害"][0]["稀有度"]}big'], (554, 512))
|
await img.paste(box[f'{data["最高承受伤害"][0]["稀有度"]}big'], (554, 512))
|
||||||
await img.paste(box[f'{data["最高承受伤害"][1]["稀有度"]}small'], (552, 664))
|
await img.paste(box[f'{data["最高承受伤害"][1]["稀有度"]}small'], (552, 664))
|
||||||
await img.paste(box[f'{data["最高承受伤害"][2]["稀有度"]}small'], (808, 664))
|
await img.paste(box[f'{data["最高承受伤害"][2]["稀有度"]}small'], (808, 664))
|
||||||
await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高承受伤害"][0]["图标"]}.png', size=(124, 124)),
|
await img.paste(
|
||||||
|
await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高承受伤害"][0]["图标"]}.png', size=(124, 124)),
|
||||||
(560, 525))
|
(560, 525))
|
||||||
await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高承受伤害"][1]["图标"]}.png', size=(82, 82)),
|
await img.paste(
|
||||||
|
await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高承受伤害"][1]["图标"]}.png', size=(82, 82)),
|
||||||
(557, 673))
|
(557, 673))
|
||||||
await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高承受伤害"][2]["图标"]}.png', size=(82, 82)),
|
await img.paste(
|
||||||
|
await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{data["最高承受伤害"][2]["图标"]}.png', size=(82, 82)),
|
||||||
(815, 673))
|
(815, 673))
|
||||||
await img.paste(await get_user_avatar(data['最高承受伤害'][0]['qq号']), (623, 588))
|
await img.paste(await get_user_avatar(data['最高承受伤害'][0]['qq号']), (623, 588))
|
||||||
await img.paste(await get_user_avatar(data['最高承受伤害'][1]['qq号'], (42, 42)), (600, 713))
|
await img.paste(await get_user_avatar(data['最高承受伤害'][1]['qq号'], (42, 42)), (600, 713))
|
||||||
@ -204,33 +212,43 @@ async def draw_statistics_img(data: Dict[str, Any]):
|
|||||||
# 角色出场率
|
# 角色出场率
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
try:
|
try:
|
||||||
icon, rarity, count = data['11层上半'][i][0].split('-')[0], data['11层上半'][i][0].split('-')[1], data['11层上半'][i][1]
|
icon, rarity, count = data['11层上半'][i][0].split('-')[0], data['11层上半'][i][0].split('-')[1], \
|
||||||
|
data['11层上半'][i][1]
|
||||||
await img.paste(box[f'{rarity}bg'], (182 + i * 101, 867))
|
await img.paste(box[f'{rarity}bg'], (182 + i * 101, 867))
|
||||||
await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(95, 95)), (182 + i * 101, 867))
|
await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(95, 95)),
|
||||||
|
(182 + i * 101, 867))
|
||||||
await img.paste(tag, (236 + i * 101, 942))
|
await img.paste(tag, (236 + i * 101, 942))
|
||||||
await img.text(str(count), (236 + i * 101, 277 + i * 101), 943, fm.get('bahnschrift_regular.ttf', 19), 'white', 'center')
|
await img.text(str(count), (236 + i * 101, 277 + i * 101), 943, fm.get('bahnschrift_regular.ttf', 19),
|
||||||
|
'white', 'center')
|
||||||
|
|
||||||
icon, rarity, count = data['11层下半'][i][0].split('-')[0], data['11层下半'][i][0].split('-')[1], data['11层下半'][i][1]
|
icon, rarity, count = data['11层下半'][i][0].split('-')[0], data['11层下半'][i][0].split('-')[1], \
|
||||||
|
data['11层下半'][i][1]
|
||||||
await img.paste(box[f'{rarity}bg'], (642 + i * 101, 867))
|
await img.paste(box[f'{rarity}bg'], (642 + i * 101, 867))
|
||||||
await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(95, 95)), (642 + i * 101, 867))
|
await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(95, 95)),
|
||||||
|
(642 + i * 101, 867))
|
||||||
await img.paste(tag, (696 + i * 101, 942))
|
await img.paste(tag, (696 + i * 101, 942))
|
||||||
await img.text(str(count), (696 + i * 101, 737 + i * 101), 943, fm.get('bahnschrift_regular.ttf', 19), 'white', 'center')
|
await img.text(str(count), (696 + i * 101, 737 + i * 101), 943, fm.get('bahnschrift_regular.ttf', 19),
|
||||||
|
'white', 'center')
|
||||||
|
|
||||||
icon, rarity, count = data['12层上半'][i][0].split('-')[0], data['12层上半'][i][0].split('-')[1], data['12层上半'][i][1]
|
icon, rarity, count = data['12层上半'][i][0].split('-')[0], data['12层上半'][i][0].split('-')[1], \
|
||||||
|
data['12层上半'][i][1]
|
||||||
await img.paste(box[f'{rarity}bg'], (182 + i * 101, 983))
|
await img.paste(box[f'{rarity}bg'], (182 + i * 101, 983))
|
||||||
await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(95, 95)), (182 + i * 101, 983))
|
await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(95, 95)),
|
||||||
|
(182 + i * 101, 983))
|
||||||
await img.paste(tag, (236 + i * 101, 1058))
|
await img.paste(tag, (236 + i * 101, 1058))
|
||||||
await img.text(str(count), (236 + i * 101, 278 + i * 101), 1059, fm.get('bahnschrift_regular.ttf', 19), 'white', 'center')
|
await img.text(str(count), (236 + i * 101, 278 + i * 101), 1059, fm.get('bahnschrift_regular.ttf', 19),
|
||||||
|
'white', 'center')
|
||||||
|
|
||||||
icon, rarity, count = data['12层下半'][i][0].split('-')[0], data['12层下半'][i][0].split('-')[1], data['12层下半'][i][1]
|
icon, rarity, count = data['12层下半'][i][0].split('-')[0], data['12层下半'][i][0].split('-')[1], \
|
||||||
|
data['12层下半'][i][1]
|
||||||
await img.paste(box[f'{rarity}bg'], (642 + i * 101, 983))
|
await img.paste(box[f'{rarity}bg'], (642 + i * 101, 983))
|
||||||
await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(95, 95)), (642 + i * 101, 983))
|
await img.paste(await load_image(RESOURCE_BASE_PATH / 'avatar' / f'{icon}.png', size=(95, 95)),
|
||||||
|
(642 + i * 101, 983))
|
||||||
await img.paste(tag, (696 + i * 101, 1058))
|
await img.paste(tag, (696 + i * 101, 1058))
|
||||||
await img.text(str(count), (696 + i * 101, 737 + i * 101), 1059, fm.get('bahnschrift_regular.ttf', 19), 'white', 'center')
|
await img.text(str(count), (696 + i * 101, 737 + i * 101), 1059, fm.get('bahnschrift_regular.ttf', 19),
|
||||||
|
'white', 'center')
|
||||||
i += 1
|
i += 1
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return MessageBuild.Image(img, mode='RGB', quality=80)
|
return MessageBuild.Image(img, mode='RGB', quality=80)
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ from nonebot.adapters.onebot.v11 import Message
|
|||||||
from nonebot.params import CommandArg, Depends
|
from nonebot.params import CommandArg, Depends
|
||||||
|
|
||||||
from LittlePaimon.config import config
|
from LittlePaimon.config import config
|
||||||
from LittlePaimon.database import DailyNoteSub, Player
|
from LittlePaimon.database import DailyNoteSub, Player, LastQuery
|
||||||
from LittlePaimon.utils import logger, scheduler
|
from LittlePaimon.utils import logger, scheduler
|
||||||
from LittlePaimon.utils.api import get_mihoyo_private_data
|
from LittlePaimon.utils.api import get_mihoyo_private_data
|
||||||
from .draw import draw_daily_note_card
|
from .draw import draw_daily_note_card
|
||||||
@ -46,6 +46,7 @@ async def get_subs(**kwargs) -> str:
|
|||||||
|
|
||||||
|
|
||||||
async def handle_ssbq(player: Player):
|
async def handle_ssbq(player: Player):
|
||||||
|
await LastQuery.update_last_query(player.user_id, player.uid)
|
||||||
data = await get_mihoyo_private_data(player.uid, player.user_id, 'daily_note')
|
data = await get_mihoyo_private_data(player.uid, player.user_id, 'daily_note')
|
||||||
if isinstance(data, str):
|
if isinstance(data, str):
|
||||||
logger.info('原神实时便签', '➤', {'用户': player.user_id, 'UID': player.uid}, f'获取数据失败, {data}', False)
|
logger.info('原神实时便签', '➤', {'用户': player.user_id, 'UID': player.uid}, f'获取数据失败, {data}', False)
|
||||||
@ -77,17 +78,12 @@ async def handle_ssbq(player: Player):
|
|||||||
async def check_note():
|
async def check_note():
|
||||||
if not config.ssbq_enable:
|
if not config.ssbq_enable:
|
||||||
return
|
return
|
||||||
# 0点到6点间不做检查
|
# 特定时间段不做检查
|
||||||
if config.ssbq_begin <= datetime.datetime.now().hour <= config.ssbq_end:
|
if config.ssbq_begin <= datetime.datetime.now().hour <= config.ssbq_end:
|
||||||
return
|
return
|
||||||
t = time.time()
|
if not (subs := await DailyNoteSub.all()):
|
||||||
try:
|
|
||||||
subs = await DailyNoteSub.all()
|
|
||||||
except Exception as e:
|
|
||||||
logger.info('原神实时便签', '获取检查列表时<r>出错</r>,结束任务')
|
|
||||||
return
|
|
||||||
if not subs:
|
|
||||||
return
|
return
|
||||||
|
time_now = time.time()
|
||||||
logger.info('原神实时便签', f'开始执行定时检查,共<m>{len(subs)}</m>个任务,预计花费<m>{round(6 * len(subs) / 60, 2)}</m>分钟')
|
logger.info('原神实时便签', f'开始执行定时检查,共<m>{len(subs)}</m>个任务,预计花费<m>{round(6 * len(subs) / 60, 2)}</m>分钟')
|
||||||
for sub in subs:
|
for sub in subs:
|
||||||
limit_num = 5 if sub.resin_num and sub.coin_num else 3
|
limit_num = 5 if sub.resin_num and sub.coin_num else 3
|
||||||
@ -138,4 +134,4 @@ async def check_note():
|
|||||||
logger.info('原神实时便签', '➤➤', {'用户': sub.user_id, 'UID': sub.uid}, f'发送提醒失败,{e}', False)
|
logger.info('原神实时便签', '➤➤', {'用户': sub.user_id, 'UID': sub.uid}, f'发送提醒失败,{e}', False)
|
||||||
# 等待一会再检查下一个,防止检查过快
|
# 等待一会再检查下一个,防止检查过快
|
||||||
await asyncio.sleep(random.randint(4, 8))
|
await asyncio.sleep(random.randint(4, 8))
|
||||||
logger.info('原神实时便签', f'树脂检查完成,共花费<m>{round((time.time() - t) / 60, 2)}</m>分钟')
|
logger.info('原神实时便签', f'树脂检查完成,共花费<m>{round((time.time() - time_now) / 60, 2)}</m>分钟')
|
||||||
|
@ -9,7 +9,7 @@ from nonebot.adapters.onebot.v11 import GroupUploadNoticeEvent, NoticeEvent
|
|||||||
from nonebot.rule import Rule
|
from nonebot.rule import Rule
|
||||||
|
|
||||||
from LittlePaimon import __version__
|
from LittlePaimon import __version__
|
||||||
from LittlePaimon.database import PlayerInfo
|
from LittlePaimon.database import PlayerInfo, LastQuery
|
||||||
from LittlePaimon.utils import logger
|
from LittlePaimon.utils import logger
|
||||||
from LittlePaimon.utils.requests import aiorequests
|
from LittlePaimon.utils.requests import aiorequests
|
||||||
from LittlePaimon.utils.api import get_authkey_by_stoken
|
from LittlePaimon.utils.api import get_authkey_by_stoken
|
||||||
@ -118,6 +118,7 @@ async def get_gacha_log_data(user_id: str, uid: str):
|
|||||||
:param uid: 原神uid
|
:param uid: 原神uid
|
||||||
:return: 更新结果
|
:return: 更新结果
|
||||||
"""
|
"""
|
||||||
|
await LastQuery.update_last_query(user_id, uid)
|
||||||
new_num = 0
|
new_num = 0
|
||||||
server_id = 'cn_qd01' if uid[0] == '5' else 'cn_gf01'
|
server_id = 'cn_qd01' if uid[0] == '5' else 'cn_gf01'
|
||||||
authkey, state, cookie_info = await get_authkey_by_stoken(user_id, uid)
|
authkey, state, cookie_info = await get_authkey_by_stoken(user_id, uid)
|
||||||
@ -166,11 +167,11 @@ async def get_gacha_log_data(user_id: str, uid: str):
|
|||||||
|
|
||||||
|
|
||||||
async def get_gacha_log_img(user_id: str, uid: str, nickname: str):
|
async def get_gacha_log_img(user_id: str, uid: str, nickname: str):
|
||||||
|
await LastQuery.update_last_query(user_id, uid)
|
||||||
data, state = load_history_info(user_id, uid)
|
data, state = load_history_info(user_id, uid)
|
||||||
if not state:
|
if not state:
|
||||||
return f'UID{uid}还没有抽卡记录数据,请先更新'
|
return f'UID{uid}还没有抽卡记录数据,请先更新'
|
||||||
player_info = await PlayerInfo.get_or_none(user_id=user_id, uid=uid)
|
if player_info := await PlayerInfo.get_or_none(user_id=user_id, uid=uid):
|
||||||
if player_info:
|
|
||||||
return await draw_gacha_log(player_info.user_id, player_info.uid, player_info.nickname, player_info.signature,
|
return await draw_gacha_log(player_info.user_id, player_info.uid, player_info.nickname, player_info.signature,
|
||||||
data)
|
data)
|
||||||
else:
|
else:
|
||||||
|
@ -7,7 +7,7 @@ from nonebot.plugin import PluginMetadata
|
|||||||
from nonebot.typing import T_State
|
from nonebot.typing import T_State
|
||||||
|
|
||||||
from LittlePaimon import NICKNAME
|
from LittlePaimon import NICKNAME
|
||||||
from LittlePaimon.database import PlayerAlias
|
from LittlePaimon.database import PlayerAlias, LastQuery
|
||||||
from LittlePaimon.utils import logger
|
from LittlePaimon.utils import logger
|
||||||
from LittlePaimon.utils.path import YSC_TEMP_IMG_PATH
|
from LittlePaimon.utils.path import YSC_TEMP_IMG_PATH
|
||||||
from LittlePaimon.utils.message import CommandPlayer, CommandCharacter, CommandUID
|
from LittlePaimon.utils.message import CommandPlayer, CommandCharacter, CommandUID
|
||||||
@ -156,7 +156,7 @@ async def _(event: MessageEvent, players=CommandPlayer(only_cn=False), character
|
|||||||
if len(players) == 1:
|
if len(players) == 1:
|
||||||
# 当查询对象只有一个时,查询所有角色
|
# 当查询对象只有一个时,查询所有角色
|
||||||
gim = GenshinInfoManager(players[0].user_id, players[0].uid)
|
gim = GenshinInfoManager(players[0].user_id, players[0].uid)
|
||||||
await gim.set_last_query()
|
await LastQuery.update_last_query(players[0].user_id, players[0].uid)
|
||||||
logger.info('原神角色卡片', '➤', {'用户': players[0].user_id, 'UID': players[0].uid})
|
logger.info('原神角色卡片', '➤', {'用户': players[0].user_id, 'UID': players[0].uid})
|
||||||
for character in characters:
|
for character in characters:
|
||||||
character_info = await gim.get_character(name=character)
|
character_info = await gim.get_character(name=character)
|
||||||
@ -171,7 +171,7 @@ async def _(event: MessageEvent, players=CommandPlayer(only_cn=False), character
|
|||||||
# 当查询对象有多个时,只查询第一个角色
|
# 当查询对象有多个时,只查询第一个角色
|
||||||
for player in players:
|
for player in players:
|
||||||
gim = GenshinInfoManager(player.user_id, player.uid)
|
gim = GenshinInfoManager(player.user_id, player.uid)
|
||||||
await gim.set_last_query()
|
await LastQuery.update_last_query(player.user_id, player.uid)
|
||||||
logger.info('原神角色卡片', '➤', {'用户': player.user_id, 'UID': player.uid})
|
logger.info('原神角色卡片', '➤', {'用户': player.user_id, 'UID': player.uid})
|
||||||
character_info = await gim.get_character(name=characters[0])
|
character_info = await gim.get_character(name=characters[0])
|
||||||
if not character_info:
|
if not character_info:
|
||||||
@ -199,7 +199,7 @@ async def _(event: MessageEvent, players=CommandPlayer(only_cn=False), character
|
|||||||
if len(players) == 1:
|
if len(players) == 1:
|
||||||
# 当查询对象只有一个时,查询所有角色
|
# 当查询对象只有一个时,查询所有角色
|
||||||
gim = GenshinInfoManager(players[0].user_id, players[0].uid)
|
gim = GenshinInfoManager(players[0].user_id, players[0].uid)
|
||||||
await gim.set_last_query()
|
await LastQuery.update_last_query(players[0].user_id, players[0].uid)
|
||||||
logger.info('原神角色面板', '➤', {'用户': players[0].user_id, 'UID': players[0].uid})
|
logger.info('原神角色面板', '➤', {'用户': players[0].user_id, 'UID': players[0].uid})
|
||||||
for character in characters:
|
for character in characters:
|
||||||
character_info = await gim.get_character(name=character, data_source='enka')
|
character_info = await gim.get_character(name=character, data_source='enka')
|
||||||
@ -214,7 +214,7 @@ async def _(event: MessageEvent, players=CommandPlayer(only_cn=False), character
|
|||||||
# 当查询对象有多个时,只查询第一个角色
|
# 当查询对象有多个时,只查询第一个角色
|
||||||
for player in players:
|
for player in players:
|
||||||
gim = GenshinInfoManager(player.user_id, player.uid)
|
gim = GenshinInfoManager(player.user_id, player.uid)
|
||||||
await gim.set_last_query()
|
await LastQuery.update_last_query(player.user_id, player.uid)
|
||||||
logger.info('原神角色面板', '➤', {'用户': player.user_id, 'UID': player.uid})
|
logger.info('原神角色面板', '➤', {'用户': player.user_id, 'UID': player.uid})
|
||||||
character_info = await gim.get_character(name=characters[0], data_source='enka')
|
character_info = await gim.get_character(name=characters[0], data_source='enka')
|
||||||
if not character_info:
|
if not character_info:
|
||||||
|
@ -28,10 +28,6 @@ class GenshinInfoManager:
|
|||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
self.uid = uid
|
self.uid = uid
|
||||||
|
|
||||||
async def set_last_query(self):
|
|
||||||
await LastQuery.update_or_create(user_id=self.user_id,
|
|
||||||
defaults={'uid': self.uid, 'last_time': datetime.datetime.now()})
|
|
||||||
|
|
||||||
async def is_bind(self) -> bool:
|
async def is_bind(self) -> bool:
|
||||||
"""
|
"""
|
||||||
检查是否已绑定私人cookie
|
检查是否已绑定私人cookie
|
||||||
@ -44,17 +40,19 @@ class GenshinInfoManager:
|
|||||||
更新所有原神信息
|
更新所有原神信息
|
||||||
"""
|
"""
|
||||||
result = ''
|
result = ''
|
||||||
await self.set_last_query()
|
await LastQuery.update_last_query(self.user_id, self.uid)
|
||||||
mihoyo_result = await self.update_from_mihoyo()
|
mihoyo_result = await self.update_from_mihoyo()
|
||||||
if mihoyo_result != '更新成功':
|
result += f'米游社数据:\n{mihoyo_result}\n'
|
||||||
result += f'{mihoyo_result}\n'
|
|
||||||
enka_result = await self.update_from_enka()
|
if include_talent:
|
||||||
if not enka_result.startswith('更新成功'):
|
if await self.is_bind():
|
||||||
result += f'{enka_result}\n'
|
|
||||||
if include_talent and await self.is_bind():
|
|
||||||
talent_result = await self.update_talent()
|
talent_result = await self.update_talent()
|
||||||
if talent_result not in ['更新成功', mihoyo_result]:
|
result += f'天赋数据:\n{talent_result}\n'
|
||||||
result += f'{talent_result}\n'
|
else:
|
||||||
|
result += '天赋数据:\n未绑定私人Cookie\n'
|
||||||
|
|
||||||
|
enka_result = await self.update_from_enka()
|
||||||
|
result += f'Enka数据:\n{enka_result}'
|
||||||
return result or enka_result
|
return result or enka_result
|
||||||
|
|
||||||
async def update_from_enka(self) -> str:
|
async def update_from_enka(self) -> str:
|
||||||
@ -72,7 +70,7 @@ class GenshinInfoManager:
|
|||||||
for character in data['avatarInfoList']:
|
for character in data['avatarInfoList']:
|
||||||
await Character.update_info(self.user_id, self.uid, character, 'enka')
|
await Character.update_info(self.user_id, self.uid, character, 'enka')
|
||||||
logger.info('原神信息', f'➤UID<m>{self.uid}</m><g>更新Enka成功</g>')
|
logger.info('原神信息', f'➤UID<m>{self.uid}</m><g>更新Enka成功</g>')
|
||||||
return '更新成功,本次更新的角色有:\n' + ' '.join(
|
return '更新以下角色成功:\n' + ' '.join(
|
||||||
[get_name_by_id(str(c['avatarId'])) for c in data['playerInfo']['showAvatarInfoList']])
|
[get_name_by_id(str(c['avatarId'])) for c in data['playerInfo']['showAvatarInfoList']])
|
||||||
|
|
||||||
async def update_talent(self) -> str:
|
async def update_talent(self) -> str:
|
||||||
@ -117,8 +115,8 @@ class GenshinInfoManager:
|
|||||||
if not isinstance(data, dict):
|
if not isinstance(data, dict):
|
||||||
return data
|
return data
|
||||||
elif data['retcode'] == 1034:
|
elif data['retcode'] == 1034:
|
||||||
logger.info('原神信息', f'更新<m>{self.uid}</m>的玩家数据时出错,状态码为1034,疑似验证码</r>')
|
logger.info('原神信息', f'更新<m>{self.uid}</m>的玩家数据时出错,状态码为1034,<r>疑似验证码</r>')
|
||||||
return '疑似遇米游社验证码阻拦,请稍后再试'
|
return '疑似遇验证码阻拦,请稍后再试'
|
||||||
elif data['retcode'] != 0:
|
elif data['retcode'] != 0:
|
||||||
logger.info('原神信息', f'更新<m>{self.uid}</m>的玩家数据时出错,消息为<r>{data["message"]}</r>')
|
logger.info('原神信息', f'更新<m>{self.uid}</m>的玩家数据时出错,消息为<r>{data["message"]}</r>')
|
||||||
return data['message']
|
return data['message']
|
||||||
@ -150,7 +148,7 @@ class GenshinInfoManager:
|
|||||||
获取原神玩家总体信息
|
获取原神玩家总体信息
|
||||||
:return: 玩家信息
|
:return: 玩家信息
|
||||||
"""
|
"""
|
||||||
await self.set_last_query()
|
await LastQuery.update_last_query(self.user_id, self.uid)
|
||||||
return await PlayerInfo.get_or_none(user_id=self.user_id, uid=self.uid)
|
return await PlayerInfo.get_or_none(user_id=self.user_id, uid=self.uid)
|
||||||
|
|
||||||
async def get_character(self, name: Optional[str] = None, character_id: Optional[int] = None,
|
async def get_character(self, name: Optional[str] = None, character_id: Optional[int] = None,
|
||||||
@ -172,13 +170,15 @@ class GenshinInfoManager:
|
|||||||
if data_source == 'enka':
|
if data_source == 'enka':
|
||||||
"""如果角色不存在或者角色的更新时间在6小时前,则更新角色信息"""
|
"""如果角色不存在或者角色的更新时间在6小时前,则更新角色信息"""
|
||||||
character = await Character.get_or_none(**query, data_source='enka')
|
character = await Character.get_or_none(**query, data_source='enka')
|
||||||
if not character or character.update_time < (datetime.datetime.now() - datetime.timedelta(hours=config.ysd_auto_update)).replace(
|
if not character or character.update_time < (
|
||||||
|
datetime.datetime.now() - datetime.timedelta(hours=config.ysd_auto_update)).replace(
|
||||||
tzinfo=pytz.timezone('UTC')):
|
tzinfo=pytz.timezone('UTC')):
|
||||||
await self.update_from_enka()
|
await self.update_from_enka()
|
||||||
if character := await Character.get_or_none(**query, data_source='enka'):
|
if character := await Character.get_or_none(**query, data_source='enka'):
|
||||||
logger.info('原神角色面板', '➤➤', {'角色': name or character_id}, '数据更新成功', True)
|
logger.info('原神角色面板', '➤➤', {'角色': name or character_id}, '数据更新成功', True)
|
||||||
else:
|
else:
|
||||||
logger.info('原神角色面板', '➤➤', {'角色': name or character_id}, '不在游戏内展示柜中,更新失败', False)
|
logger.info('原神角色面板', '➤➤', {'角色': name or character_id}, '不在游戏内展示柜中,更新失败',
|
||||||
|
False)
|
||||||
else:
|
else:
|
||||||
logger.info('原神角色面板', '➤➤', {'角色': name or character_id}, '数据获取成功', True)
|
logger.info('原神角色面板', '➤➤', {'角色': name or character_id}, '数据获取成功', True)
|
||||||
return character
|
return character
|
||||||
@ -193,7 +193,7 @@ class GenshinInfoManager:
|
|||||||
获取原神角色背包信息
|
获取原神角色背包信息
|
||||||
:return: 原神玩家信息和角色列表
|
:return: 原神玩家信息和角色列表
|
||||||
"""
|
"""
|
||||||
await self.set_last_query()
|
await LastQuery.update_last_query(self.user_id, self.uid)
|
||||||
player_info = await PlayerInfo.get_or_none(user_id=self.user_id, uid=self.uid)
|
player_info = await PlayerInfo.get_or_none(user_id=self.user_id, uid=self.uid)
|
||||||
if player_info is None or player_info.update_time is None or player_info.update_time < (
|
if player_info is None or player_info.update_time is None or player_info.update_time < (
|
||||||
datetime.datetime.now() - datetime.timedelta(hours=config.ysa_auto_update)).replace(
|
datetime.datetime.now() - datetime.timedelta(hours=config.ysa_auto_update)).replace(
|
||||||
@ -210,7 +210,7 @@ class GenshinInfoManager:
|
|||||||
return player_info, character_list
|
return player_info, character_list
|
||||||
|
|
||||||
async def get_player_info(self) -> Tuple[Union[PlayerInfo, str], Optional[List[Character]]]:
|
async def get_player_info(self) -> Tuple[Union[PlayerInfo, str], Optional[List[Character]]]:
|
||||||
await self.set_last_query()
|
await LastQuery.update_last_query(self.user_id, self.uid)
|
||||||
player_info = await PlayerInfo.get_or_none(user_id=self.user_id, uid=self.uid)
|
player_info = await PlayerInfo.get_or_none(user_id=self.user_id, uid=self.uid)
|
||||||
if player_info is None or player_info.update_time is None or player_info.update_time < (
|
if player_info is None or player_info.update_time is None or player_info.update_time < (
|
||||||
datetime.datetime.now() - datetime.timedelta(hours=config.ys_auto_update)).replace(
|
datetime.datetime.now() - datetime.timedelta(hours=config.ys_auto_update)).replace(
|
||||||
@ -228,7 +228,7 @@ class GenshinInfoManager:
|
|||||||
return player_info, characters_list
|
return player_info, characters_list
|
||||||
|
|
||||||
async def get_abyss_info(self, abyss_index: int = 1) -> Union[AbyssInfo, str]:
|
async def get_abyss_info(self, abyss_index: int = 1) -> Union[AbyssInfo, str]:
|
||||||
await self.set_last_query()
|
await LastQuery.update_last_query(self.user_id, self.uid)
|
||||||
await AbyssInfo.filter(user_id=self.user_id, uid=self.uid).delete()
|
await AbyssInfo.filter(user_id=self.user_id, uid=self.uid).delete()
|
||||||
result = await self.update_abyss_info(abyss_index)
|
result = await self.update_abyss_info(abyss_index)
|
||||||
if result != '更新成功':
|
if result != '更新成功':
|
||||||
@ -263,13 +263,15 @@ class GenshinTools:
|
|||||||
:param effective: 有效词条列表
|
:param effective: 有效词条列表
|
||||||
:return: 评分
|
:return: 评分
|
||||||
"""
|
"""
|
||||||
prop_map = {'攻击力': 4.975, '生命值': 4.975, '防御力': 6.2, '暴击率': 3.3, '暴击伤害': 6.6, '元素精通': 19.75, '元素充能效率': 5.5}
|
prop_map = {'攻击力': 4.975, '生命值': 4.975, '防御力': 6.2, '暴击率': 3.3, '暴击伤害': 6.6,
|
||||||
|
'元素精通': 19.75, '元素充能效率': 5.5}
|
||||||
|
|
||||||
if prop_name in effective and prop_name in {'攻击力', '生命值', '防御力'}:
|
if prop_name in effective and prop_name in {'攻击力', '生命值', '防御力'}:
|
||||||
return round(prop_value / role_prop[prop_name] * 100 / prop_map[prop_name] * effective[prop_name], 2)
|
return round(prop_value / role_prop[prop_name] * 100 / prop_map[prop_name] * effective[prop_name], 2)
|
||||||
|
|
||||||
if prop_name.replace('百分比', '') in effective:
|
if prop_name.replace('百分比', '') in effective:
|
||||||
return round(prop_value / prop_map[prop_name.replace('百分比', '')] * effective[prop_name.replace('百分比', '')],
|
return round(
|
||||||
|
prop_value / prop_map[prop_name.replace('百分比', '')] * effective[prop_name.replace('百分比', '')],
|
||||||
2)
|
2)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
@ -22,7 +22,6 @@ async def get_status():
|
|||||||
bot_status = await bot.get_status()
|
bot_status = await bot.get_status()
|
||||||
status_result['bot_id'] = bot.self_id
|
status_result['bot_id'] = bot.self_id
|
||||||
if bot_status := bot_status.get('stat'):
|
if bot_status := bot_status.get('stat'):
|
||||||
print(bot_status)
|
|
||||||
status_result['msg_received'] = bot_status.get('message_received', '未知')
|
status_result['msg_received'] = bot_status.get('message_received', '未知')
|
||||||
status_result['msg_sent'] = bot_status.get('message_sent', '未知')
|
status_result['msg_sent'] = bot_status.get('message_sent', '未知')
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -4,7 +4,7 @@ from pathlib import Path
|
|||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
from LittlePaimon.config import ConfigManager, ConfigModel, PluginManager, PluginInfo
|
from LittlePaimon.config import ConfigManager, PluginManager, PluginInfo
|
||||||
from LittlePaimon.database import PluginPermission
|
from LittlePaimon.database import PluginPermission
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -130,10 +130,8 @@ async def set_config(data: dict):
|
|||||||
data['实时便签停止检查结束时间'] = int(temp_time_split[1][:2])
|
data['实时便签停止检查结束时间'] = int(temp_time_split[1][:2])
|
||||||
if '云原神签到开始时间' in data:
|
if '云原神签到开始时间' in data:
|
||||||
data['云原神签到时间(小时)'] = int(data['云原神签到开始时间'])
|
data['云原神签到时间(小时)'] = int(data['云原神签到开始时间'])
|
||||||
config = ConfigManager.config.dict(by_alias=True)
|
ConfigManager.config.update(**data)
|
||||||
config.update(**data)
|
ConfigManager.save()
|
||||||
ConfigManager.config = ConfigModel.parse_obj(config)
|
|
||||||
PluginManager.save()
|
|
||||||
return {
|
return {
|
||||||
'status': 0,
|
'status': 0,
|
||||||
'msg': '保存成功'
|
'msg': '保存成功'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user