Skip to content

Commit 1311cb0

Browse files
committed
Sync Upstream
1 parent 950e846 commit 1311cb0

12 files changed

Lines changed: 127 additions & 51 deletions

File tree

internal/service/COM3D2/anm.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ func (m *AnmService) ReadAnmFile(path string) (*COM3D2.Anm, error) {
3030
return anmData, nil
3131
}
3232

33-
br := bufio.NewReaderSize(f, 1024*128) // 128KB 缓冲,7931 个样本中 90% 文件小于 97.35 KB,平均 848.27 KB,中位数 16.89 KB,最大 81.28 MB
34-
anmData, err := COM3D2.ReadAnm(br)
33+
br := bufio.NewReaderSize(f, 1024*128)
34+
anmData, err := COM3D2.ReadAnm(br) // 128KB 缓冲,8042 个样本中 90% 文件小于 152.39 KB,平均 1.01 MB,中位数 16.89 KB,最大 81.28 MB
3535
if err != nil {
3636
return nil, fmt.Errorf("parsing the .anm file failed: %w", err)
3737
}

internal/service/COM3D2/arc.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package COM3D2
2+
3+
import (
4+
"fmt"
5+
"path/filepath"
6+
7+
"github.com/MeidoPromotionAssociation/MeidoSerialization/serialization/COM3D2/arc"
8+
)
9+
10+
type ArcService struct{}
11+
12+
// NewArc 创建一个空的 Arc 结构体
13+
func (a *ArcService) NewArc(name string) *arc.Arc {
14+
return arc.New(name)
15+
}
16+
17+
// ReadArc 读取 .arc 文件并返回对应结构体
18+
func (a *ArcService) ReadArc(path string) (*arc.Arc, error) {
19+
return arc.ReadArc(path)
20+
}
21+
22+
// UnpackArc 将 .arc 文件解压到指定文件夹
23+
func (a *ArcService) UnpackArc(path string, outDir string) error {
24+
return arc.UnpackArc(path, outDir)
25+
}
26+
27+
// PackArc 将文件夹打包为 .arc 文件
28+
func (a *ArcService) PackArc(dirPath string, arcPath string) error {
29+
return arc.Pack(dirPath, arcPath)
30+
}
31+
32+
// MergeArc 将 fromArc 合并到 toArc 中。如果 keepDupes 为真,则使用文件的完整路径作为键;否则使用最后一个段。
33+
func (a *ArcService) MergeArc(fromArc *arc.Arc, toArc *arc.Arc, keepDupes bool) *arc.Arc {
34+
toArc.MergeFrom(fromArc, keepDupes)
35+
return toArc
36+
}
37+
38+
// GetFileList 获取 Arc 中的所有文件列表(相对路径)
39+
func (a *ArcService) GetFileList(fs *arc.Arc) []string {
40+
return fs.GetFileList()
41+
}
42+
43+
// CopyFile 在 Arc 内部复制文件
44+
func (a *ArcService) CopyFile(fs *arc.Arc, srcPath, dstPath string) error {
45+
return fs.CopyFile(srcPath, dstPath)
46+
}
47+
48+
// ExtractFile 从 Arc 中提取单个文件
49+
func (a *ArcService) ExtractFile(fs *arc.Arc, path, outPath string) error {
50+
f := fs.GetFile(path)
51+
if f == nil {
52+
return fmt.Errorf("file not found: %s", path)
53+
}
54+
return f.Extract(outPath)
55+
}
56+
57+
// ExtractFiles 从 Arc 中提取多个文件到指定目录
58+
func (a *ArcService) ExtractFiles(fs *arc.Arc, paths []string, outDir string) error {
59+
for _, p := range paths {
60+
f := fs.GetFile(p)
61+
if f == nil {
62+
return fmt.Errorf("file not found: %s", p)
63+
}
64+
targetPath := filepath.Join(outDir, f.RelativePath())
65+
if err := f.Extract(targetPath); err != nil {
66+
return err
67+
}
68+
}
69+
return nil
70+
}
71+
72+
// CreateFile 在 Arc 中创建或更新文件
73+
func (a *ArcService) CreateFile(fs *arc.Arc, path string, data []byte) error {
74+
f := fs.CreateFile(path, data)
75+
if f == nil {
76+
return fmt.Errorf("failed to create file: %s", path)
77+
}
78+
return nil
79+
}
80+
81+
// DeleteFile 在 Arc 中删除文件
82+
func (a *ArcService) DeleteFile(fs *arc.Arc, path string) error {
83+
if !fs.DeleteFile(path) {
84+
return fmt.Errorf("file not found: %s", path)
85+
}
86+
return nil
87+
}

internal/service/COM3D2/col.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func (m *ColService) ReadColFile(path string) (*COM3D2.Col, error) {
3030
return colData, nil
3131
}
3232

33-
colData, err := COM3D2.ReadCol(f) // 无需缓冲,2690 个样本中 90% 的文件小于 1.65 KB
33+
colData, err := COM3D2.ReadCol(f) //无需缓冲,2740 个样本中 90% 文件小于: 1.65 KB,平均 915.16 B,中位数 904.00 B,最大值 3.41 KB
3434
if err != nil {
3535
return nil, fmt.Errorf("parsing the .col file failed: %w", err)
3636
}

internal/service/COM3D2/mate.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ func (m *MateService) ReadMateFile(path string) (*COM3D2.Mate, error) {
3030
return mateData, nil
3131
}
3232

33-
mateData, err := COM3D2.ReadMate(f) // .mate needs io.ReadSeeker
33+
br := bufio.NewReader(f) // 需要 Peek
34+
mateData, err := COM3D2.ReadMate(br) // 4KB 缓冲,74497 个样本中 90% 文件小于 1.81 KB,平均 1.62 KB,中位数 1.11 KB,最大值 16.01 KB
3435
if err != nil {
3536
return nil, fmt.Errorf("parsing the .mate file failed: %w", err)
3637
}

internal/service/COM3D2/menu.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ func (s *MenuService) ReadMenuFile(path string) (*COM3D2.Menu, error) {
3030
return menuData, nil
3131
}
3232

33-
menuData, err := COM3D2.ReadMenu(f) // 无需缓冲,132831 个样本中 90% 文件小于: 1.14 KB,平均 898 B,中位数 687 B
33+
br := bufio.NewReader(f) // 需要 Peek
34+
menuData, err := COM3D2.ReadMenu(br) // 4KB 缓冲,134279 个样本中 90% 文件小于: 1.14 KB,平均 898.32 B,中位数 687.00 B,最大值 19.39 KB
3435
if err != nil {
3536
return nil, fmt.Errorf("parsing the .menu file failed: %w", err)
3637
}

internal/service/COM3D2/model.go

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ func (m *ModelService) ReadModelFile(path string) (*COM3D2.Model, error) {
3030
return modelData, nil
3131
}
3232

33-
modelData, err := COM3D2.ReadModel(f) // .model need seek
33+
br := bufio.NewReaderSize(f, 2*1024*1024) // 需要 Peek 和缓冲
34+
modelData, err := COM3D2.ReadModel(br) // 2MB 缓冲区,30091 个样本中 90% 文件小于: 1.94 MB,平均 929.99 KB,中位数 269.53 KB,最大值 117.46 MB
3435
if err != nil {
3536
return nil, fmt.Errorf("parsing the .model file failed: %w", err)
3637
}
@@ -76,29 +77,29 @@ func (m *ModelService) ReadModelMetadata(path string) (*COM3D2.ModelMetadata, er
7677
}
7778
defer f.Close()
7879

79-
var modelData *COM3D2.Model
80-
8180
if strings.HasSuffix(path, ".json") {
8281
decoder := json.NewDecoder(f)
83-
modelData = &COM3D2.Model{}
82+
modelData := &COM3D2.Model{}
8483
if err = decoder.Decode(modelData); err != nil {
8584
return nil, fmt.Errorf("failed to read .model.json file: %w", err)
8685
}
87-
} else {
88-
modelData, err = COM3D2.ReadModel(f)
89-
if err != nil {
90-
return nil, fmt.Errorf("parsing the .model file failed: %w", err)
91-
}
86+
return &COM3D2.ModelMetadata{
87+
Signature: modelData.Signature,
88+
Version: modelData.Version,
89+
Name: modelData.Name,
90+
RootBoneName: modelData.RootBoneName,
91+
ShadowCastingMode: modelData.ShadowCastingMode,
92+
Materials: modelData.Materials,
93+
}, nil
94+
}
95+
96+
br := bufio.NewReaderSize(f, 1*1024*1024) // 1MB 缓冲区,因为只读取部分数据
97+
metadata, err := COM3D2.ReadModelMetadata(br)
98+
if err != nil {
99+
return nil, fmt.Errorf("parsing the .model metadata failed: %w", err)
92100
}
93101

94-
return &COM3D2.ModelMetadata{
95-
Signature: modelData.Signature,
96-
Version: modelData.Version,
97-
Name: modelData.Name,
98-
RootBoneName: modelData.RootBoneName,
99-
ShadowCastingMode: modelData.ShadowCastingMode,
100-
Materials: modelData.Materials,
101-
}, nil
102+
return metadata, nil
102103
}
103104

104105
// WriteModelMetadata 将元数据写入现有的 .model 文件
@@ -136,27 +137,11 @@ func (m *ModelService) WriteModelMetadata(inputPath string, outputPath string, m
136137

137138
// ReadModelMaterial 读取 .model 文件,但只返回其中的材质数据
138139
func (m *ModelService) ReadModelMaterial(path string) ([]*COM3D2.Material, error) {
139-
f, err := os.Open(path)
140-
if err != nil {
141-
return nil, fmt.Errorf("cannot open .model file: %w", err)
142-
}
143-
defer f.Close()
144-
145-
if strings.HasSuffix(path, ".json") {
146-
decoder := json.NewDecoder(f)
147-
modelData := &COM3D2.Model{}
148-
if err := decoder.Decode(modelData); err != nil {
149-
return nil, fmt.Errorf("failed to read.model.json file: %w", err)
150-
}
151-
return modelData.Materials, nil
152-
}
153-
154-
modelData, err := COM3D2.ReadModel(f)
140+
metadata, err := m.ReadModelMetadata(path)
155141
if err != nil {
156-
return nil, fmt.Errorf("parsing the .model file failed: %w", err)
142+
return nil, err
157143
}
158-
159-
return modelData.Materials, nil
144+
return metadata.Materials, nil
160145
}
161146

162147
// WriteModelMaterial 接收 Material 数据并写入.model 文件

internal/service/COM3D2/nei.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ func (s *NeiService) ReadNeiFile(path string) (*COM3D2.Nei, error) {
2020
}
2121
defer f.Close()
2222

23-
br := bufio.NewReaderSize(f, 1024*4) //4KB 缓冲区, 175 个样本中 90% 文件小于 2.94 KB,中位数 1.72 KB,平均 1.89 KB
24-
neiData, err := COM3D2.ReadNei(br, nil)
23+
br := bufio.NewReader(f)
24+
neiData, err := COM3D2.ReadNei(br, nil) // 4KB 缓冲区, 172 个样本中 90% 文件小于 2.94 KB,平均 1.91 KB,中位数 1.74 KB,最大值 10.63 KB
2525
if err != nil {
2626
return nil, fmt.Errorf("parsing the .nei file failed: %w", err)
2727
}

internal/service/COM3D2/phy.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func (m *PhyService) ReadPhyFile(path string) (*COM3D2.Phy, error) {
3030
return phyData, nil
3131
}
3232

33-
phyData, err := COM3D2.ReadPhy(f) // 无需缓冲,3579 个样本中 90% 文件小于: 754 B
33+
phyData, err := COM3D2.ReadPhy(f) // 无需缓冲区,3656 个样本中 90% 文件小于: 739.00 B,平均 449.80 B,中位数 184.00 B,最大值 16.52 KB
3434
if err != nil {
3535
return nil, fmt.Errorf("parsing the .phy file failed: %w", err)
3636
}

internal/service/COM3D2/pmat.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func (s *PMatService) ReadPMatFile(path string) (*COM3D2.PMat, error) {
3030
return pmatData, nil
3131
}
3232

33-
PMatData, err := COM3D2.ReadPMat(f) // 无需缓冲,4147 个样本中 90% 文件小于: 88 B
33+
PMatData, err := COM3D2.ReadPMat(f) // 无需缓冲区,4188 个样本中 90% 文件小于: 88.00 B,平均 71.75 B,中位数 67.00 B,最大值 118.00 B
3434
if err != nil {
3535
return nil, fmt.Errorf("parsing the .pmat file failed: %w", err)
3636
}

internal/service/COM3D2/preset.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"strings"
99

1010
"github.com/MeidoPromotionAssociation/MeidoSerialization/serialization/COM3D2"
11+
"github.com/MeidoPromotionAssociation/MeidoSerialization/serialization/binaryio/stream"
1112
)
1213

1314
// PresetService 专门处理 .preset 文件的读写
@@ -30,8 +31,8 @@ func (s *PresetService) ReadPresetFile(path string) (*COM3D2.Preset, error) {
3031
return presetData, nil
3132
}
3233

33-
br := bufio.NewReaderSize(f, 1024*64) //64KB 缓冲区,3231 个样本中 90% 文件小于 58.80 KB,中位数 50.57 KB,平均 51.32 KB
34-
presetData, err := COM3D2.ReadPreset(br)
34+
br := bufio.NewReaderSize(f, 1024*64)
35+
presetData, err := COM3D2.ReadPreset(br) // 64KB 缓冲区,4574 个样本中 90% 文件小于 58.83 KB,平均 51.33 KB,中位数 50.51 KB,最大值 157.35 KB
3536
if err != nil {
3637
return nil, fmt.Errorf("parsing the .preset file failed: %w", err)
3738
}
@@ -57,7 +58,8 @@ func (s *PresetService) ReadPresetFileMetadata(path string) (*COM3D2.PresetMetad
5758
}
5859

5960
br := bufio.NewReaderSize(f, 1024*64) //64KB 缓冲区, 3231 个样本中 90% 文件小于 58.80 KB,中位数 50.57 KB
60-
presetData, err := COM3D2.ReadPresetMetadata(br)
61+
reader := stream.NewBinaryReader(br)
62+
presetData, err := COM3D2.ReadPresetMetadata(reader)
6163
if err != nil {
6264
return nil, fmt.Errorf("parsing the .preset file failed: %w", err)
6365
}

0 commit comments

Comments
 (0)