解出来的spine放view看里正常,但是放无名杀里有白边怎么解决?

站里有个银与绯的帖子你可以去看看,解包方法基本没变化。只是新版解包出来的.skel文件需要处理一下文件头,代码是这个:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import argparse
import os
import sys
from pathlib import Path

VERSION_MARK = bytes.fromhex("07 34 2E 31 2E 32 34")  # 07 + "4.1.24"
HASH_LEN = 8

def find_all(data: bytes, needle: bytes):
    pos = []
    start = 0
    while True:
        i = data.find(needle, start)
        if i == -1:
            break
        pos.append(i)
        start = i + 1
    return pos

def strip_one_skel_dat(src_path: Path, overwrite: bool, occurrence: int) -> tuple[bool, str]:
    """
    Returns (success, message). On success, writes <stem>.skel next to src.
    Example: Jacinta.skel.dat -> Jacinta.skel
    """
    try:
        data = src_path.read_bytes()
    except Exception as e:
        return False, f"READ_FAIL: {e}"

    positions = find_all(data, VERSION_MARK)
    if not positions:
        return False, "MARK_NOT_FOUND"

    if occurrence < 1 or occurrence > len(positions):
        return False, f"BAD_OCCURRENCE: requested={occurrence} found={len(positions)} offsets={positions}"

    ver_idx = positions[occurrence - 1]
    spine_offset = ver_idx - HASH_LEN
    if spine_offset < 0:
        return False, f"BAD_OFFSET: marker_at={ver_idx} < {HASH_LEN}"

    # sanity check: after 8-byte hash should be the version marker
    trimmed = data[spine_offset:]
    if trimmed[HASH_LEN:HASH_LEN + len(VERSION_MARK)] != VERSION_MARK:
        return False, "SANITY_FAIL"

    # Output: remove only the trailing ".dat"
    # foo.skel.dat -> foo.skel
    out_path = src_path.with_suffix("")  # drops .dat
    if out_path.exists() and not overwrite:
        return False, f"SKIP_EXISTS: {out_path.name}"

    try:
        out_path.write_bytes(trimmed)
    except Exception as e:
        return False, f"WRITE_FAIL: {e}"

    return True, f"OK offset={spine_offset} (0x{spine_offset:X}) -> {out_path.name}"

def rename_atlas_prefab(p: Path, overwrite: bool) -> tuple[bool, str]:
    """
    foo.atlas.prefab -> foo.atlas
    """
    if not p.name.endswith(".atlas.prefab"):
        return False, "NOT_MATCH"

    dst = p.with_suffix("")  # drops ".prefab" -> foo.atlas
    if dst.exists() and not overwrite:
        return False, f"SKIP_EXISTS: {dst.name}"

    try:
        # If overwriting, remove dst first to avoid Windows rename errors
        if dst.exists() and overwrite:
            dst.unlink()
        p.rename(dst)
    except Exception as e:
        return False, f"RENAME_FAIL: {e}"

    return True, f"OK -> {dst.name}"

def iter_files(root: Path, recursive: bool):
    if recursive:
        yield from root.rglob("*")
    else:
        yield from root.glob("*")

def main():
    ap = argparse.ArgumentParser(
        description="Batch-strip prefix from *.skel.dat by locating 4.1.24 version marker and backing up 8 bytes; rename *.atlas.prefab -> *.atlas."
    )
    ap.add_argument(
        "--recursive", action="store_true",
        help="Also process subfolders (default: only current directory)."
    )
    ap.add_argument(
        "--overwrite", action="store_true",
        help="Overwrite existing output files if they already exist."
    )
    ap.add_argument(
        "-n", "--occurrence", type=int, default=1,
        help="If marker appears multiple times, use the Nth occurrence (1-based). Default=1"
    )
    ap.add_argument(
        "--skip-rename", action="store_true",
        help="Skip renaming *.atlas.prefab -> *.atlas."
    )
    ap.add_argument(
        "--skip-skel", action="store_true",
        help="Skip processing *.skel.dat."
    )
    args = ap.parse_args()

    root = Path.cwd()

    skel_total = skel_ok = 0
    atlas_total = atlas_ok = 0

    # 1) Process *.skel.dat
    if not args.skip_skel:
        for p in iter_files(root, args.recursive):
            if p.is_file() and p.name.endswith(".skel.dat"):
                skel_total += 1
                ok, msg = strip_one_skel_dat(p, args.overwrite, args.occurrence)
                if ok:
                    skel_ok += 1
                    print(f"[SKEL] {p.name}: {msg}")
                else:
                    print(f"[SKEL] {p.name}: {msg}")

    # 2) Rename *.atlas.prefab
    if not args.skip_rename:
        for p in iter_files(root, args.recursive):
            if p.is_file() and p.name.endswith(".atlas.prefab"):
                atlas_total += 1
                ok, msg = rename_atlas_prefab(p, args.overwrite)
                if ok:
                    atlas_ok += 1
                    print(f"[ATLAS] {p.name}: {msg}")
                else:
                    print(f"[ATLAS] {p.name}: {msg}")

    print("\n=== Summary ===")
    if not args.skip_skel:
        print(f"SKEL:  {skel_ok}/{skel_total} converted")
    if not args.skip_rename:
        print(f"ATLAS: {atlas_ok}/{atlas_total} renamed")

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        print("\nInterrupted.", file=sys.stderr)
        sys.exit(130)

简单来讲就是新版银与绯给skel文件的头部加了几个字节的数据导致直接读取会出错,需要先截掉

银与绯的spine解出来了,没加密很简单,但是想问下背景在哪里,就算是通用的背景,我也想提取出来方便用无名杀。

另外就是现在在解少女战争,发现解出来的spine贴图有问题,放无名杀有白色色块,用了你的脚本之后没了白色色块,但是图片就变很黑还有奇怪的红光橙光什么的,问ai:

没预乘反而更亮? :cross_mark: 播放器误以为是 Premultiplied Alpha,重复增强
如何修复? :white_check_mark: 关闭播放器的 Premultiplied Alpha 设置
是否需要预乘? :cross_mark: 不需要!Spine 默认就是 Straight Alpha

但没法改无名杀的播放器,你知道怎么处理吗

这是没预乘,然后预乘心形没了

跟用spine viewer 看的差太多

少女战争的这个光不想要可以把那个插槽关闭掉,可以把skel转Json,然后修改json达成效果

似乎是光晕部分都有问题,没有光晕的动画就很正常,有光晕的基本上光晕都过曝了,一定要修json或者关插槽了吗,还有更好办法不?

主要是在spine viewer里面是正常的 无名杀的参数哪里有问题现在ai也讲不清楚 试了让ai修无名杀的参数也不知道要修哪里

画面也比其他播放器要暗灰蒙蒙的 到底咋回事

这个是动画贴图,不想要就把插槽关闭,还有就是修改图片把光照部分贴图透明化(更麻烦,不如改josn省时省力)

这个名称光晕的插槽关闭掉就没了

skel转json的话你在帖子里面搜一下就能找到工具,关闭指定名称插槽直接找ai写个脚本就行

无名杀,我之前也有玩过, 有群组不,一起哇

有个三国杀群 247361537。

这样搞也不行啊,难道几百份spine一个个去弄吗,不可能的。

现在问题重点在 为啥就无名杀这块出问题,用其他播放器就正常

我想一劳永逸修改无名杀的spine.js文件,我让ai去研究 然后折腾一天了也没弄好。不知道咋整了。

所以我最开始回你的是转json,再使用脚本批量关闭插槽 :joy: ,你不想这样弄我只能给你出个暴力的笨办法。不过借用脚本读取atlas内容,透明化png指定名称插槽之前也有兄弟弄过脚本,搜一下应该能找到,我之前试过,简单的区域色块可以透明化掉,不过复杂一点的我没试过就不清楚了

无名杀修改,播放spine我没弄过,所以不清楚是啥情况,我只能从修改spine文件这块给你提供点思路

你看看 BlendMode 是不是 Screen,如果是的话试试这样能不能解决:

image

spine.webgl.WebGLBlendModeConverter.SREEN_BLEND_MODE_HIJACK = 1

可以试一下十周年那边的皮切:plus:新十周年…自带无视预乘