mirror of
https://github.com/xuthus83/LittlePaimon.git
synced 2025-04-12 23:29:37 +08:00
✨ 新增材料地图
This commit is contained in:
parent
0342e220f6
commit
f875cf8611
@ -7,7 +7,7 @@ from LittlePaimon.utils.migration import migrate_database
|
||||
from LittlePaimon.utils.tool import check_resource
|
||||
|
||||
DRIVER = get_driver()
|
||||
__version__ = '3.0.0beta6'
|
||||
__version__ = '3.0.0beta7'
|
||||
|
||||
try:
|
||||
SUPERUSERS: List[int] = [int(s) for s in DRIVER.config.superusers]
|
||||
|
@ -63,7 +63,7 @@ async def draw_help(plugin_list: List[PluginInfo]):
|
||||
await img.paste(matcher_card, (40 + 336 * matcher_group.index(matcher), height_now))
|
||||
await img.text(matcher.pm_usage, 40 + 336 * matcher_group.index(matcher) + 15, height_now + 10, fm.get('SourceHanSansCN-Bold.otf', 24), 'black')
|
||||
if matcher.pm_description:
|
||||
await img.text_box(matcher.pm_description, (40 + 336 * matcher_group.index(matcher) + 10, 40 + 336 * matcher_group.index(matcher) + matcher_card.width - 22),
|
||||
await img.text_box(matcher.pm_description.replace('\n', '^'), (40 + 336 * matcher_group.index(matcher) + 10, 40 + 336 * matcher_group.index(matcher) + matcher_card.width - 22),
|
||||
(height_now + 44, height_now + max_height - 10), fm.get('SourceHanSansCN-Bold.otf', 18), '#40342d')
|
||||
height_now += max_height + 10 + 6
|
||||
elif plugin.usage:
|
||||
|
@ -1,19 +1,20 @@
|
||||
import time
|
||||
|
||||
from nonebot import on_regex, on_command
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, Message, MessageSegment
|
||||
from nonebot.adapters.onebot.v11 import MessageEvent, Message, MessageSegment, GroupMessageEvent
|
||||
from nonebot.adapters.onebot.v11.helpers import HandleCancellation
|
||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
||||
from nonebot.params import RegexDict, ArgPlainText, CommandArg
|
||||
from nonebot.params import RegexDict, ArgPlainText, CommandArg, Arg
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot.typing import T_State
|
||||
|
||||
from LittlePaimon import NICKNAME, DRIVER
|
||||
from LittlePaimon.utils.alias import get_match_alias
|
||||
from LittlePaimon.utils.tool import freq_limiter
|
||||
from LittlePaimon.utils.message import MessageBuild
|
||||
from LittlePaimon.database.models import PlayerAlias
|
||||
from LittlePaimon.config import RESOURCE_BASE_PATH
|
||||
from .draw_map import init_map, draw_map
|
||||
from .draw_map import init_map, draw_map, get_full_map
|
||||
|
||||
# from .abyss_rate_draw import draw_rate_rank, draw_teams_rate
|
||||
|
||||
@ -54,6 +55,12 @@ material_map = on_command('材料图鉴', priority=11, block=True, state={
|
||||
'pm_usage': '材料图鉴<材料名>[地图]',
|
||||
'pm_priority': 9
|
||||
})
|
||||
material_map_full = on_command('材料地图', priority=11, block=True, state={
|
||||
'pm_name': '材料地图',
|
||||
'pm_description': '查看多个材料大地图采集点。\n示例:材料地图 鸣草 鬼兜虫 提瓦特',
|
||||
'pm_usage': '材料地图<材料名列表>[地图]',
|
||||
'pm_priority': 10
|
||||
})
|
||||
|
||||
|
||||
# abyss_rate = on_command('syrate', aliases={'深渊登场率', '深境螺旋登场率', '深渊登场率排行', '深渊排行'}, priority=11, block=True, state={
|
||||
@ -101,16 +108,20 @@ async def _(event: MessageEvent, regex_dict: dict = RegexDict()):
|
||||
|
||||
@material_map.handle()
|
||||
async def _(event: MessageEvent, state: T_State, msg: Message = CommandArg()):
|
||||
if params := msg.extract_plain_text().strip().split(' '):
|
||||
if params := msg.extract_plain_text().strip():
|
||||
params = params.split(' ')
|
||||
state['name'] = Message(params[0])
|
||||
if len(params) > 1:
|
||||
if params[1] in {'提瓦特', '层岩巨渊', '渊下宫'}:
|
||||
state['map'] = params[1]
|
||||
else:
|
||||
state['map'] = Message('提瓦特')
|
||||
else:
|
||||
state['map'] = Message('提瓦特')
|
||||
|
||||
|
||||
@material_map.got('map', prompt='地图名称有误,请在【提瓦特、层岩巨渊、渊下宫】中选择')
|
||||
@material_map.got('map', prompt='地图名称有误,请在【提瓦特、层岩巨渊、渊下宫】中选择,或回答【取消】退出',
|
||||
parameterless=[HandleCancellation(f'好吧,有需要再找{NICKNAME}')])
|
||||
async def _(event: MessageEvent, state: T_State, map_: str = ArgPlainText('map')):
|
||||
if map_ not in {'提瓦特', '层岩巨渊', '渊下宫'}:
|
||||
await material_map.reject('地图名称有误,请在【提瓦特、层岩巨渊、渊下宫】中选择')
|
||||
@ -128,21 +139,34 @@ async def _(event: MessageEvent, map_: str = ArgPlainText('map'), name: str = Ar
|
||||
await material_map.finish(result, at_sender=True)
|
||||
|
||||
|
||||
@material_map_full.handle()
|
||||
async def _(event: MessageEvent, state: T_State, msg: Message = CommandArg()):
|
||||
state['map'] = '提瓦特'
|
||||
if params := msg.extract_plain_text().strip():
|
||||
params = params.split(' ')
|
||||
for p in params.copy():
|
||||
if p in {'提瓦特', '层岩巨渊', '渊下宫'}:
|
||||
params.remove(p)
|
||||
state['map'] = p
|
||||
state['names'] = params
|
||||
|
||||
|
||||
@material_map_full.got('names', prompt='请输入要查询的材料名称,或回答【取消】退出',
|
||||
parameterless=[HandleCancellation(f'好吧,有需要再找{NICKNAME}')])
|
||||
async def _(event: MessageEvent, map_: str = Arg('map'), names=Arg('names')):
|
||||
if isinstance(names, Message):
|
||||
names = names.extract_plain_text().split(' ')
|
||||
if not freq_limiter.check(f'材料地图_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}'):
|
||||
await material_map_full.finish(f'材料地图查询冷却中,剩余{freq_limiter.left(f"材料地图_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}")}秒', at_sender=True)
|
||||
freq_limiter.start(f'材料地图_{event.group_id if isinstance(event, GroupMessageEvent) else event.user_id}', 15)
|
||||
await material_map_full.send(MessageBuild.Text(f'开始查找{"、".join(names)}的资源点,请稍候...'))
|
||||
result = await get_full_map(names, map_)
|
||||
await material_map_full.finish(result, at_sender=True)
|
||||
|
||||
|
||||
DRIVER.on_bot_connect(init_map)
|
||||
|
||||
|
||||
# @abyss_rate.handle()
|
||||
# async def abyss_rate_handler(event: MessageEvent):
|
||||
# abyss_img = await draw_rate_rank()
|
||||
# await abyss_rate.finish(abyss_img)
|
||||
|
||||
|
||||
# @abyss_team.handle()
|
||||
# async def abyss_team_handler(event: MessageEvent, reGroup=RegexDict()):
|
||||
# abyss_img = await draw_teams_rate(reGroup['floor'])
|
||||
# await abyss_team.finish(abyss_img)
|
||||
|
||||
|
||||
def create_wiki_matcher(pattern: str, help_fun: str, help_name: str):
|
||||
maps = on_regex(pattern, priority=11, block=True, state={
|
||||
'pm_name': help_fun,
|
||||
@ -187,7 +211,7 @@ def create_wiki_matcher(pattern: str, help_fun: str, help_name: str):
|
||||
if isinstance(name, Message):
|
||||
name = name.extract_plain_text().strip()
|
||||
if state['type'] == '角色' and (
|
||||
match_alias := await PlayerAlias.get_or_none(user_id=str(event.user_id), alias=name)):
|
||||
match_alias := await PlayerAlias.get_or_none(user_id=str(event.user_id), alias=name)):
|
||||
try:
|
||||
await maps.finish(MessageSegment.image(state['img_url'].format(match_alias.character)))
|
||||
except ActionFailed:
|
||||
|
@ -1,11 +1,12 @@
|
||||
import math
|
||||
from typing import List
|
||||
from LittlePaimon.config import RESOURCE_BASE_PATH
|
||||
from LittlePaimon.utils import logger, aiorequests
|
||||
from LittlePaimon.utils.files import load_image
|
||||
from LittlePaimon.utils.image import PMImage, font_manager as fm
|
||||
from LittlePaimon.utils.message import MessageBuild
|
||||
|
||||
from .genshinmap import utils, models, request, img
|
||||
from .genshinmap import utils, models, request, img, XYPoint
|
||||
|
||||
from PIL import Image, ImageFile, ImageOps
|
||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||
@ -64,7 +65,7 @@ async def draw_map(name: str, map_: str):
|
||||
return MessageBuild.Text(f'未查找到材料{name}')
|
||||
points = await request.get_points(map_id)
|
||||
if not (points := utils.convert_pos(utils.get_points_by_id(resource.id, points), maps.detail.origin)):
|
||||
return MessageBuild.Text(f'在{map_}上未查找到材料{name},请尝试其他地图')
|
||||
return MessageBuild.Text(f'{map_}未查找到材料{name},请尝试其他地图')
|
||||
point_icon = await load_image(RESOURCE_BASE_PATH / 'genshin_map' / 'point_icon.png')
|
||||
if len(points) >= 3:
|
||||
group_point = img.k_means_points(points, 700)
|
||||
@ -110,5 +111,63 @@ async def draw_map(name: str, map_: str):
|
||||
return MessageBuild.Image(total_img, mode='RGB', quality=85)
|
||||
|
||||
|
||||
async def get_full_map(names: List[str], map_: str):
|
||||
map_id = models.MapID[map_name_reverse[map_]]
|
||||
maps = await request.get_maps(map_id)
|
||||
labels = await request.get_labels(map_id)
|
||||
resources = []
|
||||
resources_not = []
|
||||
resources_points = []
|
||||
childs = [child for label in labels for child in label.children]
|
||||
for name in names:
|
||||
if res_filter := list(filter(lambda x: x.name == name, childs)):
|
||||
resources.append(res_filter[0])
|
||||
else:
|
||||
resources_not.append(name)
|
||||
if not resources:
|
||||
return MessageBuild.Text(f'未查找到材料{"、".join(names)}')
|
||||
points = await request.get_points(map_id)
|
||||
for resource in resources:
|
||||
if points_ := utils.convert_pos(utils.get_points_by_id(resource.id, points), maps.detail.origin):
|
||||
resources_points.append(points_)
|
||||
else:
|
||||
resources_not.append(resource.name)
|
||||
if not resources_points:
|
||||
return MessageBuild.Text(f'{map_}未查找到材料{"、".join(names)},请尝试其他地图')
|
||||
map_img = await load_image(RESOURCE_BASE_PATH / 'genshin_map' / 'results' / f'{map_id.name}.png')
|
||||
box_icon = await load_image(RESOURCE_BASE_PATH / 'genshin_map' / 'point_box.png')
|
||||
i = 0
|
||||
max_point = XYPoint(x=0, y=0)
|
||||
min_point = XYPoint(x=16384, y=12288)
|
||||
for points in resources_points:
|
||||
resource_icon = box_icon.copy()
|
||||
resource_icon.alpha_composite(await aiorequests.get_img(resources[i].icon, size=(90, 90)), (28, 15))
|
||||
resource_icon = resource_icon.resize((48, 48), Image.ANTIALIAS)
|
||||
if len(points) >= 3:
|
||||
group_point = img.k_means_points(points, 16000)
|
||||
else:
|
||||
x1_temp = int(points[0].x) - 16000
|
||||
x2_temp = int(points[0].x) + 16000
|
||||
y1_temp = int(points[0].y) - 16000
|
||||
y2_temp = int(points[0].y) + 16000
|
||||
group_point = [(
|
||||
models.XYPoint(x1_temp, y1_temp),
|
||||
models.XYPoint(x2_temp, y2_temp),
|
||||
points)]
|
||||
lt_point = group_point[0][0]
|
||||
rb_point = group_point[0][1]
|
||||
min_point = XYPoint(x=min(min_point.x, lt_point.x), y=min(min_point.y, lt_point.y))
|
||||
max_point = XYPoint(x=max(max_point.x, rb_point.x), y=max(max_point.y, rb_point.y))
|
||||
for point in group_point[0][2]:
|
||||
point_trans = (int(point.x), int(point.y))
|
||||
map_img.paste(resource_icon, (point_trans[0] - 24, point_trans[1] - 48), resource_icon)
|
||||
i += 1
|
||||
map_img = map_img.crop((int(min_point.x) - 50, int(min_point.y) - 50, int(max_point.x) + 50, int(max_point.y) + 50))
|
||||
if resources_not:
|
||||
return MessageBuild.Text(f'{map_}未找到材料{"、".join(resources_not)},请尝试其他地图\n') + MessageBuild.Image(map_img)
|
||||
else:
|
||||
return MessageBuild.Image(map_img)
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user