new:进一步完善加点代码导入

This commit is contained in:
2026-08-10 14:47:46 +08:00
parent 7d63093971
commit 0f648a94e8
2 changed files with 512 additions and 21 deletions
+103 -21
View File
@@ -81,7 +81,7 @@ def decode_skill_hash(encoded: str) -> dict:
break
skills.append(
{
'skill_index': high[i],
'skill_index': high[i] + 0x100 if low[i + 1] else high[i],
'level': high[i + 1],
'skill_flag': low[i],
'level_flag': low[i + 1],
@@ -91,7 +91,7 @@ def decode_skill_hash(encoded: str) -> dict:
sec2_bytes = data[(1 + num_pairs * 2) * 2 :]
evolutions, enhancements, keybinds, remaining = _parse_section2(sec2_bytes)
return {
result = {
'header': header,
'skills': skills,
'evolutions': evolutions,
@@ -100,6 +100,10 @@ def decode_skill_hash(encoded: str) -> dict:
'section2_remaining': remaining,
'raw_size': len(raw),
}
# 黑暗武士才有技能排列;其他职业保持原有返回结构不变。
if header['job_bytes'][0] == 9:
result['arrangements'] = _parse_dark_knight_arrangements(remaining)
return result
def _parse_header(raw: bytes) -> dict:
@@ -141,7 +145,7 @@ def _parse_section2(sec2: bytes):
break
evolutions.append(
{
'skill_index': sec2[off],
'skill_index': sec2[off] + 0x100 if sec2[off + 1] else sec2[off],
'flag': sec2[off + 1],
'type': sec2[off + 2] + 1,
}
@@ -159,7 +163,7 @@ def _parse_section2(sec2: bytes):
break
enhancements.append(
{
'skill_index': sec2[off],
'skill_index': sec2[off] + 0x100 if sec2[off + 1] else sec2[off],
'flag': sec2[off + 1],
'type': sec2[off + 2] + 1,
}
@@ -175,7 +179,7 @@ def _parse_section2(sec2: bytes):
for slot in range(key_count):
if off + 2 > len(sec2):
break
idx = sec2[off]
idx = sec2[off] + 0x100 if sec2[off + 1] else sec2[off]
flag = sec2[off + 1]
keybinds.append(
{
@@ -190,23 +194,61 @@ def _parse_section2(sec2: bytes):
return evolutions, enhancements, keybinds, remaining
def _resolve_openapi_skill_id(skill_index: int, level_flag: int, skill_name_map: dict[str, str]) -> int | None:
if level_flag:
high_skill_id = skill_index + 0x100
if str(high_skill_id) in skill_name_map:
return high_skill_id
def _parse_dark_knight_arrangements(remaining: bytes) -> list[dict]:
"""从原始 remaining 前缀中读取黑暗武士技能排列。
黑暗武士的排列格式为:排列组数(1B),随后每组依次存储
排列槽索引(2B)、组内技能数(1B)和对应数量的技能索引(2B)。
本函数只读取已确认的排列前缀,不解析或截断排列后的未知数据;
decode_skill_hash 仍按原格式返回完整的 section2_remaining。
"""
if not remaining:
return []
arrangement_count = remaining[0]
off = 1
arrangements = []
for _ in range(arrangement_count):
if off + 3 > len(remaining):
break
slot_index = remaining[off] + 0x100 if remaining[off + 1] else remaining[off]
off += 2
skill_count = remaining[off]
off += 1
if off + skill_count * 2 > len(remaining):
break
skills = []
for _ in range(skill_count):
skill_index = remaining[off] + 0x100 if remaining[off + 1] else remaining[off]
skills.append(skill_index)
off += 2
arrangements.append(
{
'slot_index': slot_index,
'skills': skills,
}
)
return arrangements
def _resolve_openapi_skill_id(skill_index: int, skill_name_map: dict[str, str]) -> int | None:
if str(skill_index) in skill_name_map:
return skill_index
return None
def _resolve_section_skill_id(skill_index: int, skill_name_map: dict[str, str]) -> int | None:
high_skill_id = skill_index + 0x100
if str(high_skill_id) in skill_name_map:
return high_skill_id
if str(skill_index) in skill_name_map:
return skill_index
return None
# def _resolve_section_skill_id(skill_index: int, skill_name_map: dict[str, str]) -> int | None:
# high_skill_id = skill_index + 0x100
# if str(high_skill_id) in skill_name_map:
# return high_skill_id
# if str(skill_index) in skill_name_map:
# return skill_index
# return None
def get_skill_tree_info(encoded: str) -> dict:
@@ -241,7 +283,7 @@ def get_skill_tree_info(encoded: str) -> dict:
skillMap = {}
for index, i in enumerate(r['skills']):
skillIndex = i['skill_index']
actualSkillId = _resolve_openapi_skill_id(skillIndex, i.get('level_flag'), skill_name_map)
actualSkillId = _resolve_openapi_skill_id(skillIndex, skill_name_map)
skillName = skill_name_map.get(str(actualSkillId)) if actualSkillId is not None else None
skills = [skill for skill in character.skills if skill.name == skillName] if skillName else []
i['actual_skill_id'] = actualSkillId
@@ -273,14 +315,14 @@ def get_skill_tree_info(encoded: str) -> dict:
}
# 处理进化
for evo in r['evolutions']:
actualSkillId = _resolve_section_skill_id(evo['skill_index'], skill_name_map)
actualSkillId = _resolve_openapi_skill_id(evo['skill_index'], skill_name_map)
for s in skillMap.get(actualSkillId, []):
if getattr(s, 'hasVP', False) and str(s.id) in skillLearn:
skillLearn[str(s.id)]['vp'] = evo['type']
# 处理强化
for enh in r['enhancements']:
actualSkillId = _resolve_section_skill_id(enh['skill_index'], skill_name_map)
actualSkillId = _resolve_openapi_skill_id(enh['skill_index'], skill_name_map)
for s in skillMap.get(actualSkillId, []):
if getattr(s, 'hasUP', False) and str(s.id) in skillLearn:
skillLearn[str(s.id)]['up'] = enh['type']
@@ -292,11 +334,51 @@ def get_skill_tree_info(encoded: str) -> dict:
'vp': 0,
'name': i.name,
}
shortcuts = []
for k in r['keybinds']:
actualSkillId = _resolve_openapi_skill_id(k['skill_index'], skill_name_map)
if actualSkillId is None:
shortcuts.append({
'slot': k['slot'],
'skill_id': None,
'skill_name': None,
})
continue
for s in skillMap.get(actualSkillId, []):
if str(s.id) in skillLearn:
shortcuts.append({
'slot': k['slot'],
'skill_id': s.id,
'skill_name': s.name,
})
if s is None:
shortcuts.append({
'slot': k['slot'],
'skill_id': None,
'skill_name': None,
})
combos = []
for a in r.get('arrangements', []):
combo = {
'slot_index': a['slot_index'],
'skills': [],
}
for skillIndex in a['skills']:
actualSkillId = _resolve_openapi_skill_id(skillIndex, skill_name_map)
for s in skillMap.get(actualSkillId, []):
if str(s.id) in skillLearn:
combo['skills'].append({
'skill_id': s.id,
'skill_name': s.name,
})
combos.append(combo)
return {
"name": header['name'],
"level": header['level'],
"job":advInfo,
"skills": skillLearn
"skills": skillLearn,
"shortcuts":shortcuts,
"combos":combos,
}