spine连接器和导出修改
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
import { mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
|
||||
const root = new URL('../', import.meta.url)
|
||||
const connectorUrl = process.env.SPINE_CONNECTOR_URL || 'http://127.0.0.1:27843'
|
||||
const origin = process.env.SPINE_CONNECTOR_TEST_ORIGIN || 'http://127.0.0.1:5173'
|
||||
const imagePath = new URL('public/images/star.png', root)
|
||||
|
||||
const healthResponse = await fetch(`${connectorUrl}/v1/health`, { headers: { Origin: origin } })
|
||||
if (!healthResponse.ok) throw new Error(`连接器健康检查失败:HTTP ${healthResponse.status}`)
|
||||
const health = await healthResponse.json()
|
||||
if (!health.authorized) throw new Error('测试来源没有获得连接器授权')
|
||||
if (!health.spineFound) throw new Error('连接器没有找到本机 Spine')
|
||||
|
||||
const skeletonJson = JSON.stringify({
|
||||
skeleton: { spine: '4.2', images: './images/', fps: 30 },
|
||||
bones: [{ name: 'root' }, { name: 'particle', parent: 'root' }],
|
||||
slots: [{ name: 'particle', bone: 'particle', attachment: 'star' }],
|
||||
skins: [{ name: 'default', attachments: { particle: { star: { path: 'star', width: 64, height: 64 } } } }],
|
||||
animations: { animation: {} },
|
||||
})
|
||||
const image = await readFile(imagePath)
|
||||
const payload = {
|
||||
schemaVersion: 1,
|
||||
projectName: 'Spine粒子连接器测试',
|
||||
spineVersion: JSON.parse(skeletonJson).skeleton.spine,
|
||||
skeletonJson,
|
||||
images: [{ path: 'star.png', dataBase64: image.toString('base64') }],
|
||||
}
|
||||
const response = await fetch(`${connectorUrl}/v1/convert`, {
|
||||
method: 'POST',
|
||||
headers: { Origin: origin, 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
if (!response.ok) throw new Error(`转换失败:${await response.text()}`)
|
||||
|
||||
const temp = await mkdtemp(join(tmpdir(), 'spine-connector-verify-'))
|
||||
const output = join(temp, 'SpineParticleConnectorTest.zip')
|
||||
try {
|
||||
const archive = Buffer.from(await response.arrayBuffer())
|
||||
await writeFile(output, archive)
|
||||
const info = await stat(output)
|
||||
if (!info.isFile() || info.size === 0 || archive.readUInt32LE(0) !== 0x04034b50) throw new Error('连接器返回的不是有效 ZIP')
|
||||
const entries = []
|
||||
let offset = 0
|
||||
while (offset + 30 <= archive.length && archive.readUInt32LE(offset) === 0x04034b50) {
|
||||
const size = archive.readUInt32LE(offset + 18)
|
||||
const nameLength = archive.readUInt16LE(offset + 26)
|
||||
const extraLength = archive.readUInt16LE(offset + 28)
|
||||
const name = archive.subarray(offset + 30, offset + 30 + nameLength).toString('utf8')
|
||||
entries.push({ name, size })
|
||||
offset += 30 + nameLength + extraLength + size
|
||||
}
|
||||
if (!entries.some((entry) => entry.name.endsWith('.spine') && entry.size > 0)) throw new Error('ZIP 中缺少 .spine 工程')
|
||||
if (!entries.some((entry) => entry.name === 'images/star.png' && entry.size === image.length)) throw new Error('ZIP 中缺少 images/star.png')
|
||||
console.log(JSON.stringify({
|
||||
connectorVersion: health.connectorVersion,
|
||||
requestedSpineVersion: payload.spineVersion,
|
||||
actualSpineVersion: response.headers.get('x-spine-editor-version'),
|
||||
encodedFileName: response.headers.get('x-spine-file-name'),
|
||||
imageCount: payload.images.length,
|
||||
archiveBytes: info.size,
|
||||
entries,
|
||||
}, null, 2))
|
||||
} finally {
|
||||
await rm(temp, { recursive: true, force: true })
|
||||
}
|
||||
Reference in New Issue
Block a user