new:MCP及openapi新增技能特殊属性查询
This commit is contained in:
@@ -8,6 +8,7 @@ import redis
|
||||
|
||||
from api.core.Gzip import gzip_zip
|
||||
from api.utils.skill_detail import SKILL_DETAIL_NORMALIZE_VERSION, normalize_skill_detail
|
||||
from api.utils.skill_tree import SKILL_TREE_WITH_DESC_SPECIAL_VERSION, load_skill_tree_with_desc_special
|
||||
from core.basic.character import createCharacter
|
||||
from core.basic.equipment import get_equipment
|
||||
from core.character.adventure import adv, get_adv_list
|
||||
@@ -146,8 +147,8 @@ def _build_skill_tree_preheat_tasks() -> list[PreheatTask]:
|
||||
job_grow_id = relative.parts[1]
|
||||
tasks.append(
|
||||
(
|
||||
f'openapi:{job_id}:{job_grow_id}:skills',
|
||||
lambda path=path: json.loads(path.read_text(encoding='utf-8')),
|
||||
f'openapi:{SKILL_TREE_WITH_DESC_SPECIAL_VERSION}:{job_id}:{job_grow_id}:skills',
|
||||
lambda job_id=job_id, job_grow_id=job_grow_id: load_skill_tree_with_desc_special(job_id, job_grow_id),
|
||||
)
|
||||
)
|
||||
return tasks
|
||||
|
||||
@@ -5,6 +5,11 @@ from api.core.Response import response
|
||||
from api.core.Redis import get_redis_info
|
||||
from api.dp import RedisDep
|
||||
from api.utils.skill_detail import SKILL_DETAIL_NORMALIZE_VERSION, normalize_skill_detail, skill_detail_for_level
|
||||
from api.utils.skill_tree import (
|
||||
SKILL_TREE_WITH_DESC_SPECIAL_VERSION,
|
||||
filter_skill_tree_by_desc_special,
|
||||
load_skill_tree_with_desc_special,
|
||||
)
|
||||
import re
|
||||
from typing import Annotated
|
||||
|
||||
@@ -89,25 +94,23 @@ async def get_cn_skills_by_job(
|
||||
redis: RedisDep,
|
||||
jobId: Annotated[str, Path(..., description='职业')],
|
||||
jobGrowId: Annotated[str, Path(..., description='转职')],
|
||||
descSpecial: Annotated[str, Query(description='技能特殊功能')] = '',
|
||||
) -> SkillsListResponse:
|
||||
"""
|
||||
获取职业技能列表
|
||||
获取职业技能列表,职业ID和转职ID可通过jobsInfo获取
|
||||
|
||||
Args:
|
||||
jobId (str): 职业ID,必填参数
|
||||
jobGrowId (str): 转职ID,必填参数
|
||||
descSpecial (str, optional): 技能特殊功能,默认为'',可选参数,支持传入以下功能关键词以过滤技能列表:压制、无敌、追踪、聚集敌人、强控敌人
|
||||
"""
|
||||
key = f'openapi:{jobId}:{jobGrowId}:skills'
|
||||
key = f'openapi:{SKILL_TREE_WITH_DESC_SPECIAL_VERSION}:{jobId}:{jobGrowId}:skills'
|
||||
|
||||
def get_skills_by_job():
|
||||
# This function should retrieve the skills by job and jobGrow
|
||||
# For now, we return a placeholder list
|
||||
with open(f'./openapi/data/{jobId}/{jobGrowId}/cn/skill_tree.json', encoding='utf-8') as f:
|
||||
skills_data = json.load(f)
|
||||
return skills_data
|
||||
return load_skill_tree_with_desc_special(jobId, jobGrowId)
|
||||
|
||||
skills_list = get_redis_info(redis, key, get_skills_by_job)
|
||||
return response(data=skills_list)
|
||||
return response(data=filter_skill_tree_by_desc_special(skills_list, descSpecial))
|
||||
|
||||
|
||||
@router.get('/{jobId}/{jobGrowId}/{skillId}/', operation_id='skillDetail', response_model=SkillDetailResponse)
|
||||
|
||||
@@ -140,6 +140,8 @@ class SkillListItem(BaseModel):
|
||||
"""学习等级"""
|
||||
type: SkillType = Field(..., description='技能类型')
|
||||
"""技能类型"""
|
||||
descSpecial: list[str] | None = Field(None, description='特殊功能')
|
||||
"""特殊功能"""
|
||||
|
||||
|
||||
class SkillSummaryItem(BaseModel):
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from database.connect import BACKEND_DIR
|
||||
|
||||
|
||||
SKILL_TREE_WITH_DESC_SPECIAL_VERSION = 'skillTreeWithDescSpecial:v1'
|
||||
|
||||
|
||||
def load_skill_tree_with_desc_special(job_id: str, job_grow_id: str) -> list[dict]:
|
||||
skill_tree_path = BACKEND_DIR / 'openapi' / 'data' / job_id / job_grow_id / 'cn' / 'skill_tree.json'
|
||||
detail_dir = skill_tree_path.parent / 'skillDetail'
|
||||
|
||||
with skill_tree_path.open(encoding='utf-8') as file:
|
||||
skills_data = json.load(file)
|
||||
|
||||
for skill in skills_data:
|
||||
skill_id = skill.get('skillId')
|
||||
desc_special = None
|
||||
if skill_id:
|
||||
detail_path = detail_dir / f'{skill_id}.json'
|
||||
if detail_path.exists():
|
||||
with detail_path.open(encoding='utf-8') as file:
|
||||
desc_special = json.load(file).get('descSpecial')
|
||||
skill['descSpecial'] = desc_special
|
||||
|
||||
return skills_data
|
||||
|
||||
|
||||
def filter_skill_tree_by_desc_special(skills_data: list[dict], desc_special: str) -> list[dict]:
|
||||
if not desc_special:
|
||||
return skills_data
|
||||
print(f'Filtering skills by descSpecial: {desc_special}')
|
||||
print(skills_data)
|
||||
return [
|
||||
skill
|
||||
for skill in skills_data
|
||||
if any(desc_special in item for item in (skill.get('descSpecial') or []))
|
||||
]
|
||||
@@ -213,7 +213,11 @@ func NewRouter(dep Dependencies) http.Handler {
|
||||
})
|
||||
|
||||
r.Get("/{jobId}/{jobGrowId}/skills/", func(w http.ResponseWriter, r *http.Request) {
|
||||
data, err := dep.OpenAPIService.SkillsByJob(chi.URLParam(r, "jobId"), chi.URLParam(r, "jobGrowId"))
|
||||
data, err := dep.OpenAPIService.SkillsByJob(
|
||||
chi.URLParam(r, "jobId"),
|
||||
chi.URLParam(r, "jobGrowId"),
|
||||
r.URL.Query().Get("descSpecial"),
|
||||
)
|
||||
if err != nil {
|
||||
writeError(w, http.StatusNotFound, err)
|
||||
return
|
||||
|
||||
@@ -68,20 +68,47 @@ func (s *OpenAPIService) JobsInfo(jobName string) ([]map[string]string, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *OpenAPIService) SkillsByJob(jobID string, jobGrowID string) (any, error) {
|
||||
func (s *OpenAPIService) SkillsByJob(jobID string, jobGrowID string, descSpecial string) (any, error) {
|
||||
jobDir, jobGrowDir, err := s.adventure.ResolveDirectories(jobID, jobGrowID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var data any
|
||||
var data []map[string]any
|
||||
path := filepath.Join(s.projectRoot, "openapi", "data", jobDir, jobGrowDir, "cn", "skill_tree.json")
|
||||
if err := s.readJSON(path, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
detailDir := filepath.Join(s.projectRoot, "openapi", "data", jobDir, jobGrowDir, "cn", "skillDetail")
|
||||
for _, skill := range data {
|
||||
skillID, _ := skill["skillId"].(string)
|
||||
var detail map[string]any
|
||||
if skillID != "" {
|
||||
err := s.readJSON(filepath.Join(detailDir, skillID+".json"), &detail)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
skill["descSpecial"] = detail["descSpecial"]
|
||||
}
|
||||
if descSpecial == "" {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
filtered := make([]map[string]any, 0)
|
||||
for _, skill := range data {
|
||||
items, _ := skill["descSpecial"].([]any)
|
||||
for _, item := range items {
|
||||
text, _ := item.(string)
|
||||
if strings.Contains(text, descSpecial) {
|
||||
filtered = append(filtered, skill)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return filtered, nil
|
||||
}
|
||||
|
||||
func (s *OpenAPIService) SkillDetail(jobID string, jobGrowID string, skillID string, level *int) (any, error) {
|
||||
jobDir, jobGrowDir, err := s.adventure.ResolveDirectories(jobID, jobGrowID)
|
||||
if err != nil {
|
||||
|
||||
+1
-1
Submodule backend/openapi updated: 221e81715a...6ad1935813
Reference in New Issue
Block a user