sa2kit 1.6.13 → 1.6.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/PMXParser-L6IWHL4I.mjs +4 -0
  2. package/dist/PMXParser-L6IWHL4I.mjs.map +1 -0
  3. package/dist/PMXParser-YBS3B6HM.js +13 -0
  4. package/dist/PMXParser-YBS3B6HM.js.map +1 -0
  5. package/dist/audioDetection/index.js.map +1 -1
  6. package/dist/audioDetection/index.mjs.map +1 -1
  7. package/dist/auth/index.js +3 -3
  8. package/dist/auth/index.mjs +1 -1
  9. package/dist/{chunk-FAHLZIYQ.js → chunk-5D7ZFZIM.js} +2 -2
  10. package/dist/{chunk-FAHLZIYQ.js.map → chunk-5D7ZFZIM.js.map} +1 -1
  11. package/dist/{chunk-G4AMEDO5.js → chunk-66EHKQVS.js} +2 -2
  12. package/dist/{chunk-G4AMEDO5.js.map → chunk-66EHKQVS.js.map} +1 -1
  13. package/dist/{chunk-CDK3DHKM.mjs → chunk-GGGTJETD.mjs} +3 -3
  14. package/dist/{chunk-CDK3DHKM.mjs.map → chunk-GGGTJETD.mjs.map} +1 -1
  15. package/dist/chunk-JZXJQMVE.js +363 -0
  16. package/dist/chunk-JZXJQMVE.js.map +1 -0
  17. package/dist/{chunk-2ODO4HEI.js → chunk-LFM5QSFW.js} +2 -2
  18. package/dist/{chunk-2ODO4HEI.js.map → chunk-LFM5QSFW.js.map} +1 -1
  19. package/dist/{chunk-ZYXF3L6T.mjs → chunk-MRGFYQTC.mjs} +2 -2
  20. package/dist/{chunk-ZYXF3L6T.mjs.map → chunk-MRGFYQTC.mjs.map} +1 -1
  21. package/dist/{chunk-ZCLAF3XN.mjs → chunk-TGL6BATG.mjs} +2 -2
  22. package/dist/{chunk-ZCLAF3XN.mjs.map → chunk-TGL6BATG.mjs.map} +1 -1
  23. package/dist/{chunk-L5PW2YTI.js → chunk-UUM5BIOU.js} +7 -7
  24. package/dist/{chunk-L5PW2YTI.js.map → chunk-UUM5BIOU.js.map} +1 -1
  25. package/dist/chunk-VRTRSEEH.mjs +361 -0
  26. package/dist/chunk-VRTRSEEH.mjs.map +1 -0
  27. package/dist/{chunk-6BZ3QFA5.mjs → chunk-VZFHU553.mjs} +2 -2
  28. package/dist/{chunk-6BZ3QFA5.mjs.map → chunk-VZFHU553.mjs.map} +1 -1
  29. package/dist/imageCrop/index.js.map +1 -1
  30. package/dist/imageCrop/index.mjs.map +1 -1
  31. package/dist/index.js +1 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/index.mjs +1 -1
  34. package/dist/index.mjs.map +1 -1
  35. package/dist/mmd/admin/index.d.mts +1 -1
  36. package/dist/mmd/admin/index.d.ts +1 -1
  37. package/dist/mmd/index.d.mts +753 -3
  38. package/dist/mmd/index.d.ts +753 -3
  39. package/dist/mmd/index.js +7542 -5841
  40. package/dist/mmd/index.js.map +1 -1
  41. package/dist/mmd/index.mjs +7453 -5776
  42. package/dist/mmd/index.mjs.map +1 -1
  43. package/dist/mmd/server/index.d.mts +1 -1
  44. package/dist/mmd/server/index.d.ts +1 -1
  45. package/dist/music/index.js +16 -16
  46. package/dist/music/index.mjs +2 -2
  47. package/dist/music/server/index.js +8 -8
  48. package/dist/music/server/index.mjs +1 -1
  49. package/dist/testYourself/admin/index.js +3 -3
  50. package/dist/testYourself/admin/index.mjs +1 -1
  51. package/dist/testYourself/index.js +7 -7
  52. package/dist/testYourself/index.js.map +1 -1
  53. package/dist/testYourself/index.mjs +2 -2
  54. package/dist/testYourself/index.mjs.map +1 -1
  55. package/dist/{types-BB-7_WtE.d.ts → types-HorDyIRv.d.mts} +50 -0
  56. package/dist/{types-BB-7_WtE.d.mts → types-HorDyIRv.d.ts} +50 -0
  57. package/package.json +19 -17
@@ -0,0 +1,361 @@
1
+ // src/mmd/pmx/parser/PMXParser.ts
2
+ var PMXParser = class {
3
+ constructor() {
4
+ this.offset = 0;
5
+ this.textEncoding = "utf16le";
6
+ this.textureIndexSize = 1;
7
+ this.additionalVec4Count = 0;
8
+ this.vertexIndexSize = 1;
9
+ this.boneIndexSize = 1;
10
+ }
11
+ /**
12
+ * 从URL加载并解析PMX文件
13
+ */
14
+ async loadAndParse(url) {
15
+ const response = await fetch(url);
16
+ if (!response.ok) {
17
+ throw new Error(`Failed to load PMX file: ${response.statusText}`);
18
+ }
19
+ const buffer = await response.arrayBuffer();
20
+ return this.parse(buffer);
21
+ }
22
+ /**
23
+ * 解析PMX文件
24
+ */
25
+ parse(buffer) {
26
+ this.view = new DataView(buffer);
27
+ this.offset = 0;
28
+ console.log("[PMXParser] Starting parse, file size:", buffer.byteLength);
29
+ const header = this.parseHeader();
30
+ console.log("[PMXParser] Header parsed, offset:", this.offset);
31
+ console.log("[PMXParser] Globals:", header.globals);
32
+ const modelInfo = this.parseModelInfo();
33
+ console.log("[PMXParser] Model info parsed, offset:", this.offset);
34
+ console.log("[PMXParser] Model name:", modelInfo.modelName);
35
+ const vertexCount = this.skipVertices();
36
+ console.log("[PMXParser] Vertices skipped, count:", vertexCount, "offset:", this.offset);
37
+ const faceCount = this.skipFaces();
38
+ console.log("[PMXParser] Faces skipped, count:", faceCount, "offset:", this.offset);
39
+ const textures = this.parseTextures();
40
+ console.log("[PMXParser] Textures parsed, count:", textures.length, "offset:", this.offset);
41
+ const materials = this.parseMaterials();
42
+ console.log("[PMXParser] Materials parsed, count:", materials.length, "offset:", this.offset);
43
+ const materialTextureMappings = this.generateMaterialTextureMappings(
44
+ materials,
45
+ textures
46
+ );
47
+ return {
48
+ header,
49
+ modelInfo,
50
+ textures,
51
+ materials,
52
+ materialTextureMappings,
53
+ vertexCount,
54
+ faceCount
55
+ };
56
+ }
57
+ /**
58
+ * 解析文件头
59
+ */
60
+ parseHeader() {
61
+ const signature = this.readString(4);
62
+ if (signature !== "PMX ") {
63
+ throw new Error(`Invalid PMX signature: ${signature}`);
64
+ }
65
+ const version = this.view.getFloat32(this.offset, true);
66
+ this.offset += 4;
67
+ const globalsCount = this.view.getUint8(this.offset);
68
+ this.offset += 1;
69
+ if (globalsCount !== 8) {
70
+ throw new Error(`Unexpected globals count: ${globalsCount}`);
71
+ }
72
+ const encoding = this.view.getUint8(this.offset);
73
+ this.offset += 1;
74
+ this.textEncoding = encoding === 0 ? "utf16le" : "utf8";
75
+ const additionalVec4Count = this.view.getUint8(this.offset);
76
+ this.offset += 1;
77
+ this.additionalVec4Count = additionalVec4Count;
78
+ const vertexIndexSize = this.view.getUint8(this.offset);
79
+ this.offset += 1;
80
+ this.vertexIndexSize = vertexIndexSize;
81
+ const textureIndexSize = this.view.getUint8(this.offset);
82
+ this.offset += 1;
83
+ this.textureIndexSize = textureIndexSize;
84
+ const materialIndexSize = this.view.getUint8(this.offset);
85
+ this.offset += 1;
86
+ const boneIndexSize = this.view.getUint8(this.offset);
87
+ this.offset += 1;
88
+ this.boneIndexSize = boneIndexSize;
89
+ const morphIndexSize = this.view.getUint8(this.offset);
90
+ this.offset += 1;
91
+ const rigidBodyIndexSize = this.view.getUint8(this.offset);
92
+ this.offset += 1;
93
+ return {
94
+ signature,
95
+ version,
96
+ globals: {
97
+ encoding,
98
+ additionalVec4Count,
99
+ vertexIndexSize,
100
+ textureIndexSize,
101
+ materialIndexSize,
102
+ boneIndexSize,
103
+ morphIndexSize,
104
+ rigidBodyIndexSize
105
+ }
106
+ };
107
+ }
108
+ /**
109
+ * 解析模型信息
110
+ */
111
+ parseModelInfo() {
112
+ const modelName = this.readTextBuffer();
113
+ const modelNameEnglish = this.readTextBuffer();
114
+ const comment = this.readTextBuffer();
115
+ const commentEnglish = this.readTextBuffer();
116
+ return {
117
+ modelName,
118
+ modelNameEnglish,
119
+ comment,
120
+ commentEnglish
121
+ };
122
+ }
123
+ /**
124
+ * 跳过顶点数据(只返回数量)
125
+ */
126
+ skipVertices() {
127
+ const count = this.view.getInt32(this.offset, true);
128
+ this.offset += 4;
129
+ for (let i = 0; i < count; i++) {
130
+ this.offset += 12;
131
+ this.offset += 12;
132
+ this.offset += 8;
133
+ this.offset += this.additionalVec4Count * 16;
134
+ const weightType = this.view.getUint8(this.offset);
135
+ this.offset += 1;
136
+ this.skipVertexWeight(weightType);
137
+ this.offset += 4;
138
+ }
139
+ return count;
140
+ }
141
+ /**
142
+ * 跳过顶点权重数据
143
+ */
144
+ skipVertexWeight(weightType) {
145
+ switch (weightType) {
146
+ case 0:
147
+ this.offset += this.boneIndexSize;
148
+ break;
149
+ case 1:
150
+ this.offset += this.boneIndexSize * 2 + 4;
151
+ break;
152
+ case 2:
153
+ this.offset += this.boneIndexSize * 4 + 16;
154
+ break;
155
+ case 3:
156
+ this.offset += this.boneIndexSize * 2 + 4 + 36;
157
+ break;
158
+ case 4:
159
+ this.offset += this.boneIndexSize * 4 + 16;
160
+ break;
161
+ }
162
+ }
163
+ /**
164
+ * 跳过面数据(只返回数量)
165
+ */
166
+ skipFaces() {
167
+ const count = this.view.getInt32(this.offset, true);
168
+ this.offset += 4;
169
+ this.offset += count * this.vertexIndexSize;
170
+ return count / 3;
171
+ }
172
+ /**
173
+ * 解析纹理列表
174
+ */
175
+ parseTextures() {
176
+ const count = this.view.getInt32(this.offset, true);
177
+ this.offset += 4;
178
+ console.log("[PMXParser] Parsing textures, count:", count);
179
+ if (count < 0 || count > 1e4) {
180
+ throw new Error(`Invalid texture count: ${count} at offset ${this.offset - 4}`);
181
+ }
182
+ const textures = [];
183
+ for (let i = 0; i < count; i++) {
184
+ const path = this.readTextBuffer();
185
+ textures.push({
186
+ index: i,
187
+ path
188
+ });
189
+ console.log(`[PMXParser] Texture ${i}: ${path}`);
190
+ }
191
+ return textures;
192
+ }
193
+ /**
194
+ * 解析材质列表
195
+ */
196
+ parseMaterials() {
197
+ const count = this.view.getInt32(this.offset, true);
198
+ this.offset += 4;
199
+ const materials = [];
200
+ for (let i = 0; i < count; i++) {
201
+ const name = this.readTextBuffer();
202
+ const nameEnglish = this.readTextBuffer();
203
+ const diffuse = [
204
+ this.view.getFloat32(this.offset, true),
205
+ this.view.getFloat32(this.offset + 4, true),
206
+ this.view.getFloat32(this.offset + 8, true),
207
+ this.view.getFloat32(this.offset + 12, true)
208
+ ];
209
+ this.offset += 16;
210
+ const specular = [
211
+ this.view.getFloat32(this.offset, true),
212
+ this.view.getFloat32(this.offset + 4, true),
213
+ this.view.getFloat32(this.offset + 8, true)
214
+ ];
215
+ this.offset += 12;
216
+ const specularStrength = this.view.getFloat32(this.offset, true);
217
+ this.offset += 4;
218
+ const ambient = [
219
+ this.view.getFloat32(this.offset, true),
220
+ this.view.getFloat32(this.offset + 4, true),
221
+ this.view.getFloat32(this.offset + 8, true)
222
+ ];
223
+ this.offset += 12;
224
+ const drawingFlags = this.view.getUint8(this.offset);
225
+ this.offset += 1;
226
+ const edgeColor = [
227
+ this.view.getFloat32(this.offset, true),
228
+ this.view.getFloat32(this.offset + 4, true),
229
+ this.view.getFloat32(this.offset + 8, true),
230
+ this.view.getFloat32(this.offset + 12, true)
231
+ ];
232
+ this.offset += 16;
233
+ const edgeSize = this.view.getFloat32(this.offset, true);
234
+ this.offset += 4;
235
+ const textureIndex = this.readIndex(this.textureIndexSize);
236
+ const sphereTextureIndex = this.readIndex(this.textureIndexSize);
237
+ const sphereMode = this.view.getUint8(this.offset);
238
+ this.offset += 1;
239
+ const isSharedToon = this.view.getUint8(this.offset) === 1;
240
+ this.offset += 1;
241
+ const toonTextureIndex = isSharedToon ? this.view.getUint8(this.offset++) : this.readIndex(this.textureIndexSize);
242
+ const memo = this.readTextBuffer();
243
+ const surfaceCount = this.view.getInt32(this.offset, true);
244
+ this.offset += 4;
245
+ materials.push({
246
+ name,
247
+ nameEnglish,
248
+ diffuse,
249
+ specular,
250
+ specularStrength,
251
+ ambient,
252
+ drawingFlags,
253
+ edgeColor,
254
+ edgeSize,
255
+ textureIndex,
256
+ sphereTextureIndex,
257
+ sphereMode,
258
+ isSharedToon,
259
+ toonTextureIndex,
260
+ memo,
261
+ surfaceCount
262
+ });
263
+ }
264
+ return materials;
265
+ }
266
+ /**
267
+ * 生成材质纹理映射
268
+ */
269
+ generateMaterialTextureMappings(materials, textures) {
270
+ const sphereModeMap = ["none", "multiply", "add", "subTexture"];
271
+ return materials.map((material, index) => {
272
+ const mapping = {
273
+ materialIndex: index,
274
+ materialName: material.name,
275
+ materialNameEnglish: material.nameEnglish,
276
+ surfaceCount: material.surfaceCount
277
+ };
278
+ if (material.textureIndex >= 0 && material.textureIndex < textures.length) {
279
+ mapping.mainTexture = {
280
+ index: material.textureIndex,
281
+ path: textures[material.textureIndex].path
282
+ };
283
+ }
284
+ if (material.sphereTextureIndex >= 0 && material.sphereTextureIndex < textures.length && material.sphereMode > 0) {
285
+ mapping.sphereTexture = {
286
+ index: material.sphereTextureIndex,
287
+ path: textures[material.sphereTextureIndex].path,
288
+ mode: sphereModeMap[material.sphereMode]
289
+ };
290
+ }
291
+ if (material.isSharedToon) {
292
+ mapping.toonTexture = {
293
+ index: material.toonTextureIndex,
294
+ path: `toon${String(material.toonTextureIndex).padStart(2, "0")}.bmp`,
295
+ isShared: true
296
+ };
297
+ } else if (material.toonTextureIndex >= 0 && material.toonTextureIndex < textures.length) {
298
+ mapping.toonTexture = {
299
+ index: material.toonTextureIndex,
300
+ path: textures[material.toonTextureIndex].path,
301
+ isShared: false
302
+ };
303
+ }
304
+ return mapping;
305
+ });
306
+ }
307
+ /**
308
+ * 读取文本缓冲区
309
+ */
310
+ readTextBuffer() {
311
+ const length = this.view.getInt32(this.offset, true);
312
+ this.offset += 4;
313
+ if (length === 0) return "";
314
+ if (length < 0 || length > 1e7) {
315
+ throw new Error(`Invalid text buffer length: ${length} at offset ${this.offset - 4}`);
316
+ }
317
+ if (this.offset + length > this.view.buffer.byteLength) {
318
+ throw new Error(`Text buffer extends beyond file boundary: offset=${this.offset}, length=${length}, fileSize=${this.view.buffer.byteLength}`);
319
+ }
320
+ const bytes = new Uint8Array(this.view.buffer, this.offset, length);
321
+ this.offset += length;
322
+ if (this.textEncoding === "utf8") {
323
+ return new TextDecoder("utf-8").decode(bytes);
324
+ } else {
325
+ return new TextDecoder("utf-16le").decode(bytes);
326
+ }
327
+ }
328
+ /**
329
+ * 读取固定长度字符串
330
+ */
331
+ readString(length) {
332
+ const bytes = new Uint8Array(this.view.buffer, this.offset, length);
333
+ this.offset += length;
334
+ return new TextDecoder("ascii").decode(bytes);
335
+ }
336
+ /**
337
+ * 读取索引
338
+ */
339
+ readIndex(size) {
340
+ let value;
341
+ switch (size) {
342
+ case 1:
343
+ value = this.view.getInt8(this.offset);
344
+ break;
345
+ case 2:
346
+ value = this.view.getInt16(this.offset, true);
347
+ break;
348
+ case 4:
349
+ value = this.view.getInt32(this.offset, true);
350
+ break;
351
+ default:
352
+ throw new Error(`Invalid index size: ${size}`);
353
+ }
354
+ this.offset += size;
355
+ return value;
356
+ }
357
+ };
358
+
359
+ export { PMXParser };
360
+ //# sourceMappingURL=chunk-VRTRSEEH.mjs.map
361
+ //# sourceMappingURL=chunk-VRTRSEEH.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mmd/pmx/parser/PMXParser.ts"],"names":[],"mappings":"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","file":"chunk-VRTRSEEH.mjs","sourcesContent":["/**\n * PMX模型文件解析器\n * 用于解析PMX格式的MMD模型文件,提取纹理映射关系\n */\n\nimport {\n PMXHeader,\n PMXModelInfo,\n PMXMaterial,\n PMXTexture,\n PMXParseResult,\n MaterialTextureMapping,\n} from '../types';\n\nexport class PMXParser {\n private view!: DataView;\n private offset: number = 0;\n private textEncoding: 'utf16le' | 'utf8' = 'utf16le';\n private textureIndexSize: number = 1;\n private additionalVec4Count: number = 0;\n private vertexIndexSize: number = 1;\n private boneIndexSize: number = 1;\n\n /**\n * 从URL加载并解析PMX文件\n */\n async loadAndParse(url: string): Promise<PMXParseResult> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to load PMX file: ${response.statusText}`);\n }\n\n const buffer = await response.arrayBuffer();\n return this.parse(buffer);\n }\n\n /**\n * 解析PMX文件\n */\n parse(buffer: ArrayBuffer): PMXParseResult {\n this.view = new DataView(buffer);\n this.offset = 0;\n\n console.log('[PMXParser] Starting parse, file size:', buffer.byteLength);\n\n // 1. 解析头部\n const header = this.parseHeader();\n console.log('[PMXParser] Header parsed, offset:', this.offset);\n console.log('[PMXParser] Globals:', header.globals);\n\n // 2. 解析模型信息\n const modelInfo = this.parseModelInfo();\n console.log('[PMXParser] Model info parsed, offset:', this.offset);\n console.log('[PMXParser] Model name:', modelInfo.modelName);\n\n // 3. 解析顶点(只统计数量,不解析详细数据以提高性能)\n const vertexCount = this.skipVertices();\n console.log('[PMXParser] Vertices skipped, count:', vertexCount, 'offset:', this.offset);\n\n // 4. 解析面(只统计数量)\n const faceCount = this.skipFaces();\n console.log('[PMXParser] Faces skipped, count:', faceCount, 'offset:', this.offset);\n\n // 5. 解析纹理列表\n const textures = this.parseTextures();\n console.log('[PMXParser] Textures parsed, count:', textures.length, 'offset:', this.offset);\n\n // 6. 解析材质\n const materials = this.parseMaterials();\n console.log('[PMXParser] Materials parsed, count:', materials.length, 'offset:', this.offset);\n\n // 7. 生成材质纹理映射\n const materialTextureMappings = this.generateMaterialTextureMappings(\n materials,\n textures\n );\n\n return {\n header,\n modelInfo,\n textures,\n materials,\n materialTextureMappings,\n vertexCount,\n faceCount,\n };\n }\n\n /**\n * 解析文件头\n */\n private parseHeader(): PMXHeader {\n // 签名 \"PMX \" (4 bytes)\n const signature = this.readString(4);\n if (signature !== 'PMX ') {\n throw new Error(`Invalid PMX signature: ${signature}`);\n }\n\n // 版本号 (4 bytes float)\n const version = this.view.getFloat32(this.offset, true);\n this.offset += 4;\n\n // 全局设置数量 (1 byte)\n const globalsCount = this.view.getUint8(this.offset);\n this.offset += 1;\n\n if (globalsCount !== 8) {\n throw new Error(`Unexpected globals count: ${globalsCount}`);\n }\n\n // 读取全局设置\n const encoding = this.view.getUint8(this.offset);\n this.offset += 1;\n this.textEncoding = encoding === 0 ? 'utf16le' : 'utf8';\n\n const additionalVec4Count = this.view.getUint8(this.offset);\n this.offset += 1;\n this.additionalVec4Count = additionalVec4Count;\n\n const vertexIndexSize = this.view.getUint8(this.offset);\n this.offset += 1;\n this.vertexIndexSize = vertexIndexSize;\n\n const textureIndexSize = this.view.getUint8(this.offset);\n this.offset += 1;\n this.textureIndexSize = textureIndexSize;\n\n const materialIndexSize = this.view.getUint8(this.offset);\n this.offset += 1;\n\n const boneIndexSize = this.view.getUint8(this.offset);\n this.offset += 1;\n this.boneIndexSize = boneIndexSize;\n\n const morphIndexSize = this.view.getUint8(this.offset);\n this.offset += 1;\n\n const rigidBodyIndexSize = this.view.getUint8(this.offset);\n this.offset += 1;\n\n return {\n signature,\n version,\n globals: {\n encoding,\n additionalVec4Count,\n vertexIndexSize,\n textureIndexSize,\n materialIndexSize,\n boneIndexSize,\n morphIndexSize,\n rigidBodyIndexSize,\n },\n };\n }\n\n /**\n * 解析模型信息\n */\n private parseModelInfo(): PMXModelInfo {\n const modelName = this.readTextBuffer();\n const modelNameEnglish = this.readTextBuffer();\n const comment = this.readTextBuffer();\n const commentEnglish = this.readTextBuffer();\n\n return {\n modelName,\n modelNameEnglish,\n comment,\n commentEnglish,\n };\n }\n\n /**\n * 跳过顶点数据(只返回数量)\n */\n private skipVertices(): number {\n const count = this.view.getInt32(this.offset, true);\n this.offset += 4;\n\n // 跳过所有顶点数据\n // 每个顶点的大小是可变的,需要根据权重类型计算\n for (let i = 0; i < count; i++) {\n // Position (12 bytes)\n this.offset += 12;\n // Normal (12 bytes)\n this.offset += 12;\n // UV (8 bytes)\n this.offset += 8;\n\n // Additional UV (使用保存的additionalVec4Count)\n this.offset += this.additionalVec4Count * 16;\n\n // Weight type\n const weightType = this.view.getUint8(this.offset);\n this.offset += 1;\n\n // 根据权重类型跳过不同大小的数据\n this.skipVertexWeight(weightType);\n\n // Edge scale (4 bytes)\n this.offset += 4;\n }\n\n return count;\n }\n\n /**\n * 跳过顶点权重数据\n */\n private skipVertexWeight(weightType: number): void {\n switch (weightType) {\n case 0: // BDEF1\n this.offset += this.boneIndexSize;\n break;\n case 1: // BDEF2\n this.offset += this.boneIndexSize * 2 + 4;\n break;\n case 2: // BDEF4\n this.offset += this.boneIndexSize * 4 + 16;\n break;\n case 3: // SDEF\n this.offset += this.boneIndexSize * 2 + 4 + 36;\n break;\n case 4: // QDEF\n this.offset += this.boneIndexSize * 4 + 16;\n break;\n }\n }\n\n /**\n * 跳过面数据(只返回数量)\n */\n private skipFaces(): number {\n const count = this.view.getInt32(this.offset, true);\n this.offset += 4;\n\n this.offset += count * this.vertexIndexSize;\n\n return count / 3; // 返回面数(每个面3个顶点)\n }\n\n /**\n * 解析纹理列表\n */\n private parseTextures(): PMXTexture[] {\n const count = this.view.getInt32(this.offset, true);\n this.offset += 4;\n\n console.log('[PMXParser] Parsing textures, count:', count);\n\n if (count < 0 || count > 10000) {\n throw new Error(`Invalid texture count: ${count} at offset ${this.offset - 4}`);\n }\n\n const textures: PMXTexture[] = [];\n\n for (let i = 0; i < count; i++) {\n const path = this.readTextBuffer();\n textures.push({\n index: i,\n path,\n });\n console.log(`[PMXParser] Texture ${i}: ${path}`);\n }\n\n return textures;\n }\n\n /**\n * 解析材质列表\n */\n private parseMaterials(): PMXMaterial[] {\n const count = this.view.getInt32(this.offset, true);\n this.offset += 4;\n\n const materials: PMXMaterial[] = [];\n\n for (let i = 0; i < count; i++) {\n // 材质名称\n const name = this.readTextBuffer();\n const nameEnglish = this.readTextBuffer();\n\n // 颜色信息\n const diffuse: [number, number, number, number] = [\n this.view.getFloat32(this.offset, true),\n this.view.getFloat32(this.offset + 4, true),\n this.view.getFloat32(this.offset + 8, true),\n this.view.getFloat32(this.offset + 12, true),\n ];\n this.offset += 16;\n\n const specular: [number, number, number] = [\n this.view.getFloat32(this.offset, true),\n this.view.getFloat32(this.offset + 4, true),\n this.view.getFloat32(this.offset + 8, true),\n ];\n this.offset += 12;\n\n const specularStrength = this.view.getFloat32(this.offset, true);\n this.offset += 4;\n\n const ambient: [number, number, number] = [\n this.view.getFloat32(this.offset, true),\n this.view.getFloat32(this.offset + 4, true),\n this.view.getFloat32(this.offset + 8, true),\n ];\n this.offset += 12;\n\n // 绘制标志\n const drawingFlags = this.view.getUint8(this.offset);\n this.offset += 1;\n\n // 边缘信息\n const edgeColor: [number, number, number, number] = [\n this.view.getFloat32(this.offset, true),\n this.view.getFloat32(this.offset + 4, true),\n this.view.getFloat32(this.offset + 8, true),\n this.view.getFloat32(this.offset + 12, true),\n ];\n this.offset += 16;\n\n const edgeSize = this.view.getFloat32(this.offset, true);\n this.offset += 4;\n\n // 纹理信息\n const textureIndex = this.readIndex(this.textureIndexSize);\n const sphereTextureIndex = this.readIndex(this.textureIndexSize);\n const sphereMode = this.view.getUint8(this.offset);\n this.offset += 1;\n\n // Toon信息\n const isSharedToon = this.view.getUint8(this.offset) === 1;\n this.offset += 1;\n\n const toonTextureIndex = isSharedToon\n ? this.view.getUint8(this.offset++)\n : this.readIndex(this.textureIndexSize);\n\n // 备注\n const memo = this.readTextBuffer();\n\n // 面数\n const surfaceCount = this.view.getInt32(this.offset, true);\n this.offset += 4;\n\n materials.push({\n name,\n nameEnglish,\n diffuse,\n specular,\n specularStrength,\n ambient,\n drawingFlags,\n edgeColor,\n edgeSize,\n textureIndex,\n sphereTextureIndex,\n sphereMode,\n isSharedToon,\n toonTextureIndex,\n memo,\n surfaceCount,\n });\n }\n\n return materials;\n }\n\n /**\n * 生成材质纹理映射\n */\n private generateMaterialTextureMappings(\n materials: PMXMaterial[],\n textures: PMXTexture[]\n ): MaterialTextureMapping[] {\n const sphereModeMap = ['none', 'multiply', 'add', 'subTexture'] as const;\n\n return materials.map((material, index) => {\n const mapping: MaterialTextureMapping = {\n materialIndex: index,\n materialName: material.name,\n materialNameEnglish: material.nameEnglish,\n surfaceCount: material.surfaceCount,\n };\n\n // 主纹理\n if (material.textureIndex >= 0 && material.textureIndex < textures.length) {\n mapping.mainTexture = {\n index: material.textureIndex,\n path: textures[material.textureIndex]!.path,\n };\n }\n\n // Sphere纹理\n if (\n material.sphereTextureIndex >= 0 &&\n material.sphereTextureIndex < textures.length &&\n material.sphereMode > 0\n ) {\n mapping.sphereTexture = {\n index: material.sphereTextureIndex,\n path: textures[material.sphereTextureIndex]!.path,\n mode: sphereModeMap[material.sphereMode] as 'multiply' | 'add' | 'subTexture',\n };\n }\n\n // Toon纹理\n if (material.isSharedToon) {\n mapping.toonTexture = {\n index: material.toonTextureIndex,\n path: `toon${String(material.toonTextureIndex).padStart(2, '0')}.bmp`,\n isShared: true,\n };\n } else if (\n material.toonTextureIndex >= 0 &&\n material.toonTextureIndex < textures.length\n ) {\n mapping.toonTexture = {\n index: material.toonTextureIndex,\n path: textures[material.toonTextureIndex]!.path,\n isShared: false,\n };\n }\n\n return mapping;\n });\n }\n\n /**\n * 读取文本缓冲区\n */\n private readTextBuffer(): string {\n const length = this.view.getInt32(this.offset, true);\n this.offset += 4;\n\n if (length === 0) return '';\n\n // 添加边界检查\n if (length < 0 || length > 10000000) { // 10MB 限制\n throw new Error(`Invalid text buffer length: ${length} at offset ${this.offset - 4}`);\n }\n\n if (this.offset + length > this.view.buffer.byteLength) {\n throw new Error(`Text buffer extends beyond file boundary: offset=${this.offset}, length=${length}, fileSize=${this.view.buffer.byteLength}`);\n }\n\n const bytes = new Uint8Array(this.view.buffer, this.offset, length);\n this.offset += length;\n\n if (this.textEncoding === 'utf8') {\n return new TextDecoder('utf-8').decode(bytes);\n } else {\n return new TextDecoder('utf-16le').decode(bytes);\n }\n }\n\n /**\n * 读取固定长度字符串\n */\n private readString(length: number): string {\n const bytes = new Uint8Array(this.view.buffer, this.offset, length);\n this.offset += length;\n return new TextDecoder('ascii').decode(bytes);\n }\n\n /**\n * 读取索引\n */\n private readIndex(size: number): number {\n let value: number;\n\n switch (size) {\n case 1:\n value = this.view.getInt8(this.offset);\n break;\n case 2:\n value = this.view.getInt16(this.offset, true);\n break;\n case 4:\n value = this.view.getInt32(this.offset, true);\n break;\n default:\n throw new Error(`Invalid index size: ${size}`);\n }\n\n this.offset += size;\n return value;\n }\n}\n\n"]}
@@ -29,5 +29,5 @@ async function validateApiAuthNumeric(request) {
29
29
  }
30
30
 
31
31
  export { validateApiAuth, validateApiAuthNumeric };
32
- //# sourceMappingURL=chunk-6BZ3QFA5.mjs.map
33
- //# sourceMappingURL=chunk-6BZ3QFA5.mjs.map
32
+ //# sourceMappingURL=chunk-VZFHU553.mjs.map
33
+ //# sourceMappingURL=chunk-VZFHU553.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/auth/server.ts"],"names":["user"],"mappings":";;;AAOA,eAAsB,gBAAgB,OAAA,EAAsB;AAC1D,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,oBAAoB,OAAO,CAAA;AACzC,IAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AAInB,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,UAAA,IAAc,iBAAA;AACzC,IAAA,MAAM,OAAA,GAAU,MAAM,cAAA,CAAe,KAAA,EAAO,MAAM,CAAA;AAElD,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,OAAA,CAAQ,QAAQ,OAAO,IAAA;AAExC,IAAA,OAAO;AAAA,MACL,IAAI,OAAA,CAAQ,MAAA;AAAA,MACZ,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,UAAU,OAAA,CAAQ,QAAA;AAAA,MAClB,MAAM,OAAA,CAAQ;AAAA,KAChB;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,6CAAe,KAAK,CAAA;AAClC,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAMA,eAAsB,uBAAuB,OAAA,EAAsB;AACjE,EAAA,MAAMA,KAAAA,GAAO,MAAM,eAAA,CAAgB,OAAO,CAAA;AAC1C,EAAA,IAAI,CAACA,OAAM,OAAO,IAAA;AAElB,EAAA,OAAO;AAAA,IACL,GAAGA,KAAAA;AAAA,IACH,EAAA,EAAI,QAAA,CAASA,KAAAA,CAAK,EAAA,EAAI,EAAE;AAAA,GAC1B;AACF","file":"chunk-6BZ3QFA5.mjs","sourcesContent":["import { NextRequest } from 'next/server';\nimport { getTokenFromRequest, verifyJwtToken } from './services';\n\n/**\n * 验证 API 请求的身份\n * 从请求头中获取 Token 并验证,返回用户信息\n */\nexport async function validateApiAuth(request: NextRequest) {\n try {\n const token = getTokenFromRequest(request);\n if (!token) return null;\n\n // 注意:这里需要 JWT_SECRET,在演示环境中可能没有\n // 这是一个基础实现,实际使用时需要确保环境变量正确\n const secret = process.env.JWT_SECRET || 'your-secret-key';\n const payload = await verifyJwtToken(token, secret);\n \n if (!payload || !payload.userId) return null;\n\n return {\n id: payload.userId,\n email: payload.email,\n username: payload.username,\n role: payload.role,\n };\n } catch (error) {\n console.error('API 身份验证失败:', error);\n return null;\n }\n}\n\n/**\n * 验证 API 请求的身份(针对使用数字 ID 的项目)\n * 将 string 类型的 userId 转换为 number 类型\n */\nexport async function validateApiAuthNumeric(request: NextRequest) {\n const user = await validateApiAuth(request);\n if (!user) return null;\n \n return {\n ...user,\n id: parseInt(user.id, 10)\n };\n}\n\n"]}
1
+ {"version":3,"sources":["../src/auth/server.ts"],"names":["user"],"mappings":";;;AAOA,eAAsB,gBAAgB,OAAA,EAAsB;AAC1D,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,oBAAoB,OAAO,CAAA;AACzC,IAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AAInB,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,UAAA,IAAc,iBAAA;AACzC,IAAA,MAAM,OAAA,GAAU,MAAM,cAAA,CAAe,KAAA,EAAO,MAAM,CAAA;AAElD,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,OAAA,CAAQ,QAAQ,OAAO,IAAA;AAExC,IAAA,OAAO;AAAA,MACL,IAAI,OAAA,CAAQ,MAAA;AAAA,MACZ,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,UAAU,OAAA,CAAQ,QAAA;AAAA,MAClB,MAAM,OAAA,CAAQ;AAAA,KAChB;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,6CAAe,KAAK,CAAA;AAClC,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAMA,eAAsB,uBAAuB,OAAA,EAAsB;AACjE,EAAA,MAAMA,KAAAA,GAAO,MAAM,eAAA,CAAgB,OAAO,CAAA;AAC1C,EAAA,IAAI,CAACA,OAAM,OAAO,IAAA;AAElB,EAAA,OAAO;AAAA,IACL,GAAGA,KAAAA;AAAA,IACH,EAAA,EAAI,QAAA,CAASA,KAAAA,CAAK,EAAA,EAAI,EAAE;AAAA,GAC1B;AACF","file":"chunk-VZFHU553.mjs","sourcesContent":["import { NextRequest } from 'next/server';\nimport { getTokenFromRequest, verifyJwtToken } from './services';\n\n/**\n * 验证 API 请求的身份\n * 从请求头中获取 Token 并验证,返回用户信息\n */\nexport async function validateApiAuth(request: NextRequest) {\n try {\n const token = getTokenFromRequest(request);\n if (!token) return null;\n\n // 注意:这里需要 JWT_SECRET,在演示环境中可能没有\n // 这是一个基础实现,实际使用时需要确保环境变量正确\n const secret = process.env.JWT_SECRET || 'your-secret-key';\n const payload = await verifyJwtToken(token, secret);\n \n if (!payload || !payload.userId) return null;\n\n return {\n id: payload.userId,\n email: payload.email,\n username: payload.username,\n role: payload.role,\n };\n } catch (error) {\n console.error('API 身份验证失败:', error);\n return null;\n }\n}\n\n/**\n * 验证 API 请求的身份(针对使用数字 ID 的项目)\n * 将 string 类型的 userId 转换为 number 类型\n */\nexport async function validateApiAuthNumeric(request: NextRequest) {\n const user = await validateApiAuth(request);\n if (!user) return null;\n \n return {\n ...user,\n id: parseInt(user.id, 10)\n };\n}\n\n\n\n\n"]}