Skip to content

Commit 2924033

Browse files
committed
feat: add support for sapi pack
1 parent 074759f commit 2924033

File tree

1 file changed

+38
-26
lines changed

1 file changed

+38
-26
lines changed

internal/content/content.go

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"io"
1111
"math"
1212
"os"
13+
"path"
1314
"path/filepath"
1415
"reflect"
1516
"strconv"
@@ -333,12 +334,12 @@ func ImportMcpackToDirs(data []byte, archiveName string, resDir string, bpDir st
333334
manifestDir := ""
334335
var manifest bedrockManifest
335336
for _, f := range zr.File {
336-
nameInZip := strings.TrimPrefix(f.Name, "./")
337+
nameInZip := normalizeZipEntryName(f.Name)
337338
if strings.HasSuffix(nameInZip, "/") {
338339
continue
339340
}
340-
if strings.EqualFold(filepath.Base(nameInZip), "manifest.json") {
341-
dir := filepath.Dir(nameInZip)
341+
if strings.EqualFold(path.Base(nameInZip), "manifest.json") {
342+
dir := path.Dir(nameInZip)
342343
rc, er := f.Open()
343344
if er == nil {
344345
b, _ := io.ReadAll(rc)
@@ -374,7 +375,7 @@ func ImportMcpackToDirs(data []byte, archiveName string, resDir string, bpDir st
374375
if tp == "resources" && strings.TrimSpace(resDir) != "" {
375376
targets = append(targets, filepath.Join(resDir, baseName))
376377
hasRes = true
377-
} else if tp == "data" && strings.TrimSpace(bpDir) != "" {
378+
} else if (tp == "data" || tp == "script") && strings.TrimSpace(bpDir) != "" {
378379
targets = append(targets, filepath.Join(bpDir, baseName))
379380
hasData = true
380381
}
@@ -393,7 +394,7 @@ func ImportMcpackToDirs(data []byte, archiveName string, resDir string, bpDir st
393394
}
394395
}
395396
for _, f := range zr.File {
396-
nameInZip := strings.TrimPrefix(f.Name, "./")
397+
nameInZip := normalizeZipEntryName(f.Name)
397398
var relInDir string
398399
if manifestDir != "" {
399400
if nameInZip != manifestDir && !strings.HasPrefix(nameInZip, manifestDir+"/") {
@@ -458,6 +459,17 @@ func stripKnownArchiveExt(name string) string {
458459
return base
459460
}
460461

462+
func normalizeZipEntryName(name string) string {
463+
n := strings.TrimSpace(name)
464+
n = strings.TrimPrefix(n, "./")
465+
n = strings.ReplaceAll(n, "\\", "/")
466+
n = strings.TrimPrefix(n, "/")
467+
for strings.Contains(n, "//") {
468+
n = strings.ReplaceAll(n, "//", "/")
469+
}
470+
return n
471+
}
472+
461473
func ImportMcpackToDirs2(data []byte, archiveName string, resDir string, bpDir string, skinDir string, overwrite bool) string {
462474
if len(data) == 0 || (strings.TrimSpace(resDir) == "" && strings.TrimSpace(bpDir) == "" && strings.TrimSpace(skinDir) == "") {
463475
return "ERR_OPEN_ZIP"
@@ -469,12 +481,12 @@ func ImportMcpackToDirs2(data []byte, archiveName string, resDir string, bpDir s
469481
manifestDir := ""
470482
var manifest bedrockManifest
471483
for _, f := range zr.File {
472-
nameInZip := strings.TrimPrefix(f.Name, "./")
484+
nameInZip := normalizeZipEntryName(f.Name)
473485
if strings.HasSuffix(nameInZip, "/") {
474486
continue
475487
}
476-
if strings.EqualFold(filepath.Base(nameInZip), "manifest.json") {
477-
dir := filepath.Dir(nameInZip)
488+
if strings.EqualFold(path.Base(nameInZip), "manifest.json") {
489+
dir := path.Dir(nameInZip)
478490
rc, er := f.Open()
479491
if er == nil {
480492
b, _ := io.ReadAll(rc)
@@ -510,7 +522,7 @@ func ImportMcpackToDirs2(data []byte, archiveName string, resDir string, bpDir s
510522
if tp == "resources" && strings.TrimSpace(resDir) != "" {
511523
targets = append(targets, filepath.Join(resDir, baseName))
512524
hasAny = true
513-
} else if tp == "data" && strings.TrimSpace(bpDir) != "" {
525+
} else if (tp == "data" || tp == "script") && strings.TrimSpace(bpDir) != "" {
514526
targets = append(targets, filepath.Join(bpDir, baseName))
515527
hasAny = true
516528
} else if tp == "skin_pack" {
@@ -538,7 +550,7 @@ func ImportMcpackToDirs2(data []byte, archiveName string, resDir string, bpDir s
538550
}
539551
}
540552
for _, f := range zr.File {
541-
nameInZip := strings.TrimPrefix(f.Name, "./")
553+
nameInZip := normalizeZipEntryName(f.Name)
542554
var relInDir string
543555
if manifestDir != "" {
544556
if nameInZip != manifestDir && !strings.HasPrefix(nameInZip, manifestDir+"/") {
@@ -622,12 +634,12 @@ func ImportMcaddonToDirs2(data []byte, resDir string, bpDir string, skinDir stri
622634
}
623635
packs := []packInfo{}
624636
for _, f := range zr.File {
625-
nameInZip := strings.TrimPrefix(f.Name, "./")
637+
nameInZip := normalizeZipEntryName(f.Name)
626638
if strings.HasSuffix(nameInZip, "/") {
627639
continue
628640
}
629-
if strings.EqualFold(filepath.Base(nameInZip), "manifest.json") {
630-
dir := filepath.Dir(nameInZip)
641+
if strings.EqualFold(path.Base(nameInZip), "manifest.json") {
642+
dir := path.Dir(nameInZip)
631643
if dir == "." || strings.TrimSpace(dir) == "" {
632644
continue
633645
}
@@ -643,7 +655,7 @@ func ImportMcaddonToDirs2(data []byte, resDir string, bpDir string, skinDir stri
643655
}
644656
}
645657
for _, p := range packs {
646-
baseName := utils.SanitizeFilename(filepath.Base(p.dir))
658+
baseName := utils.SanitizeFilename(path.Base(p.dir))
647659
if strings.TrimSpace(baseName) == "" || baseName == "." || baseName == string(os.PathSeparator) {
648660
baseName = "pack"
649661
}
@@ -655,7 +667,7 @@ func ImportMcaddonToDirs2(data []byte, resDir string, bpDir string, skinDir stri
655667
if tp == "resources" && strings.TrimSpace(resDir) != "" {
656668
targets = append(targets, filepath.Join(resDir, baseName))
657669
hasAny = true
658-
} else if tp == "data" && strings.TrimSpace(bpDir) != "" {
670+
} else if (tp == "data" || tp == "script") && strings.TrimSpace(bpDir) != "" {
659671
targets = append(targets, filepath.Join(bpDir, baseName))
660672
hasAny = true
661673
} else if tp == "skin_pack" {
@@ -683,7 +695,7 @@ func ImportMcaddonToDirs2(data []byte, resDir string, bpDir string, skinDir stri
683695
}
684696
}
685697
for _, f := range zr.File {
686-
nameInZip := strings.TrimPrefix(f.Name, "./")
698+
nameInZip := normalizeZipEntryName(f.Name)
687699
var relInDir string
688700
if nameInZip != p.dir && !strings.HasPrefix(nameInZip, p.dir+"/") {
689701
continue
@@ -770,12 +782,12 @@ func ImportMcaddonToDirs(data []byte, resDir string, bpDir string, overwrite boo
770782
}
771783
packs := []packInfo{}
772784
for _, f := range zr.File {
773-
nameInZip := strings.TrimPrefix(f.Name, "./")
785+
nameInZip := normalizeZipEntryName(f.Name)
774786
if strings.HasSuffix(nameInZip, "/") {
775787
continue
776788
}
777-
if strings.EqualFold(filepath.Base(nameInZip), "manifest.json") {
778-
dir := filepath.Dir(nameInZip)
789+
if strings.EqualFold(path.Base(nameInZip), "manifest.json") {
790+
dir := path.Dir(nameInZip)
779791
if dir == "." || strings.TrimSpace(dir) == "" {
780792
continue
781793
}
@@ -791,7 +803,7 @@ func ImportMcaddonToDirs(data []byte, resDir string, bpDir string, overwrite boo
791803
}
792804
}
793805
for _, p := range packs {
794-
baseName := utils.SanitizeFilename(filepath.Base(p.dir))
806+
baseName := utils.SanitizeFilename(path.Base(p.dir))
795807
if strings.TrimSpace(baseName) == "" || baseName == "." || baseName == string(os.PathSeparator) {
796808
baseName = "pack"
797809
}
@@ -803,7 +815,7 @@ func ImportMcaddonToDirs(data []byte, resDir string, bpDir string, overwrite boo
803815
if tp == "resources" && strings.TrimSpace(resDir) != "" {
804816
targets = append(targets, filepath.Join(resDir, baseName))
805817
hasRes = true
806-
} else if tp == "data" && strings.TrimSpace(bpDir) != "" {
818+
} else if (tp == "data" || tp == "script") && strings.TrimSpace(bpDir) != "" {
807819
targets = append(targets, filepath.Join(bpDir, baseName))
808820
hasData = true
809821
}
@@ -822,7 +834,7 @@ func ImportMcaddonToDirs(data []byte, resDir string, bpDir string, overwrite boo
822834
}
823835
}
824836
for _, f := range zr.File {
825-
nameInZip := strings.TrimPrefix(f.Name, "./")
837+
nameInZip := normalizeZipEntryName(f.Name)
826838
var relInDir string
827839
if nameInZip != p.dir && !strings.HasPrefix(nameInZip, p.dir+"/") {
828840
continue
@@ -882,12 +894,12 @@ func ImportMcworldToDir(data []byte, archiveName string, worldsDir string, overw
882894
}
883895
levelDir := ""
884896
for _, f := range zr.File {
885-
nameInZip := strings.TrimPrefix(f.Name, "./")
897+
nameInZip := normalizeZipEntryName(f.Name)
886898
if strings.HasSuffix(nameInZip, "/") {
887899
continue
888900
}
889-
if strings.EqualFold(filepath.Base(nameInZip), "level.dat") {
890-
d := filepath.Dir(nameInZip)
901+
if strings.EqualFold(path.Base(nameInZip), "level.dat") {
902+
d := path.Dir(nameInZip)
891903
if d != "." && strings.TrimSpace(d) != "" {
892904
levelDir = d
893905
}
@@ -914,7 +926,7 @@ func ImportMcworldToDir(data []byte, archiveName string, worldsDir string, overw
914926
}
915927
}
916928
for _, f := range zr.File {
917-
nameInZip := strings.TrimPrefix(f.Name, "./")
929+
nameInZip := normalizeZipEntryName(f.Name)
918930
var relInDir string
919931
if levelDir != "" {
920932
if nameInZip != levelDir && !strings.HasPrefix(nameInZip, levelDir+"/") {

0 commit comments

Comments
 (0)