new:MCP及openapi新增技能特殊属性查询
This commit is contained in:
@@ -8,6 +8,7 @@ import redis
|
|||||||
|
|
||||||
from api.core.Gzip import gzip_zip
|
from api.core.Gzip import gzip_zip
|
||||||
from api.utils.skill_detail import SKILL_DETAIL_NORMALIZE_VERSION, normalize_skill_detail
|
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.character import createCharacter
|
||||||
from core.basic.equipment import get_equipment
|
from core.basic.equipment import get_equipment
|
||||||
from core.character.adventure import adv, get_adv_list
|
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]
|
job_grow_id = relative.parts[1]
|
||||||
tasks.append(
|
tasks.append(
|
||||||
(
|
(
|
||||||
f'openapi:{job_id}:{job_grow_id}:skills',
|
f'openapi:{SKILL_TREE_WITH_DESC_SPECIAL_VERSION}:{job_id}:{job_grow_id}:skills',
|
||||||
lambda path=path: json.loads(path.read_text(encoding='utf-8')),
|
lambda job_id=job_id, job_grow_id=job_grow_id: load_skill_tree_with_desc_special(job_id, job_grow_id),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return tasks
|
return tasks
|
||||||
|
|||||||
@@ -5,6 +5,11 @@ from api.core.Response import response
|
|||||||
from api.core.Redis import get_redis_info
|
from api.core.Redis import get_redis_info
|
||||||
from api.dp import RedisDep
|
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_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
|
import re
|
||||||
from typing import Annotated
|
from typing import Annotated
|
||||||
|
|
||||||
@@ -89,25 +94,23 @@ async def get_cn_skills_by_job(
|
|||||||
redis: RedisDep,
|
redis: RedisDep,
|
||||||
jobId: Annotated[str, Path(..., description='职业')],
|
jobId: Annotated[str, Path(..., description='职业')],
|
||||||
jobGrowId: Annotated[str, Path(..., description='转职')],
|
jobGrowId: Annotated[str, Path(..., description='转职')],
|
||||||
|
descSpecial: Annotated[str, Query(description='技能特殊功能')] = '',
|
||||||
) -> SkillsListResponse:
|
) -> SkillsListResponse:
|
||||||
"""
|
"""
|
||||||
获取职业技能列表
|
获取职业技能列表,职业ID和转职ID可通过jobsInfo获取
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
jobId (str): 职业ID,必填参数
|
jobId (str): 职业ID,必填参数
|
||||||
jobGrowId (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():
|
def get_skills_by_job():
|
||||||
# This function should retrieve the skills by job and jobGrow
|
return load_skill_tree_with_desc_special(jobId, jobGrowId)
|
||||||
# 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
|
|
||||||
|
|
||||||
skills_list = get_redis_info(redis, key, get_skills_by_job)
|
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)
|
@router.get('/{jobId}/{jobGrowId}/{skillId}/', operation_id='skillDetail', response_model=SkillDetailResponse)
|
||||||
|
|||||||
@@ -140,6 +140,8 @@ class SkillListItem(BaseModel):
|
|||||||
"""学习等级"""
|
"""学习等级"""
|
||||||
type: SkillType = Field(..., description='技能类型')
|
type: SkillType = Field(..., description='技能类型')
|
||||||
"""技能类型"""
|
"""技能类型"""
|
||||||
|
descSpecial: list[str] | None = Field(None, description='特殊功能')
|
||||||
|
"""特殊功能"""
|
||||||
|
|
||||||
|
|
||||||
class SkillSummaryItem(BaseModel):
|
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) {
|
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 {
|
if err != nil {
|
||||||
writeError(w, http.StatusNotFound, err)
|
writeError(w, http.StatusNotFound, err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -68,18 +68,45 @@ func (s *OpenAPIService) JobsInfo(jobName string) ([]map[string]string, error) {
|
|||||||
return result, nil
|
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)
|
jobDir, jobGrowDir, err := s.adventure.ResolveDirectories(jobID, jobGrowID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var data any
|
var data []map[string]any
|
||||||
path := filepath.Join(s.projectRoot, "openapi", "data", jobDir, jobGrowDir, "cn", "skill_tree.json")
|
path := filepath.Join(s.projectRoot, "openapi", "data", jobDir, jobGrowDir, "cn", "skill_tree.json")
|
||||||
if err := s.readJSON(path, &data); err != nil {
|
if err := s.readJSON(path, &data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return data, nil
|
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) {
|
func (s *OpenAPIService) SkillDetail(jobID string, jobGrowID string, skillID string, level *int) (any, error) {
|
||||||
|
|||||||
+1
-1
Submodule backend/openapi updated: 221e81715a...6ad1935813
Reference in New Issue
Block a user