Skip to content

Commit 12bdb2e

Browse files
committed
fix: 整合包扫描不符合预期
1 parent 3b28d3f commit 12bdb2e

File tree

2 files changed

+145
-51
lines changed

2 files changed

+145
-51
lines changed

core/download.go

Lines changed: 94 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ type ProgressReader struct {
1515
Total int64
1616
Current int64
1717
FilePath string
18-
UpdateInterval int64 // 更新间隔,单位秒
18+
UpdateInterval int64 //
1919
lastUpdatedTime int64
2020
}
2121

22-
// Read 实现了 io.Reader 接口
22+
var gitversion string
23+
24+
// Read 实现 io.Reader 接口
2325
func (pr *ProgressReader) Read(p []byte) (n int, err error) {
2426
n, err = pr.Reader.Read(p)
2527
pr.Current += int64(n)
@@ -33,7 +35,37 @@ func (pr *ProgressReader) Read(p []byte) (n int, err error) {
3335
return
3436
}
3537

38+
// URL 和路径下载文件,支持断点续传和分片下载
3639
func DownloadFile(url, filePath string) error {
40+
if gitversion == "" {
41+
gitversion = "NaN"
42+
}
43+
const minChunkSize = 10 * 1024 * 1024 // 10MB
44+
const chunkSize = 2 * 1024 * 1024 // 2MB
45+
46+
resp, err := http.Head(url)
47+
if err != nil {
48+
return fmt.Errorf("无法获取文件信息: %w", err)
49+
}
50+
defer resp.Body.Close()
51+
52+
if resp.StatusCode != http.StatusOK {
53+
return fmt.Errorf("HEAD 请求失败,状态码: %d", resp.StatusCode)
54+
}
55+
56+
totalSize := resp.ContentLength
57+
useChunk := totalSize > minChunkSize && !startsWith(url, "https://bmclapi2.bangbang93.com")
58+
59+
if useChunk {
60+
fmt.Println("启用分片下载...")
61+
return chunkDownload(url, filePath, totalSize, chunkSize)
62+
}
63+
64+
return normalDownload(url, filePath, totalSize)
65+
}
66+
67+
// 普通下载 + 断点续传
68+
func normalDownload(url, filePath string, totalSize int64) error {
3769
const maxRetries = 3
3870

3971
fileInfo, err := os.Stat(filePath)
@@ -55,11 +87,10 @@ func DownloadFile(url, filePath string) error {
5587
if start > 0 {
5688
req.Header.Set("Range", "bytes="+strconv.FormatInt(start, 10)+"-")
5789
}
58-
var gitversion string
59-
req.Header.Set("User-Agent", "AutoInstall"+gitversion)
90+
req.Header.Set("User-Agent", "AutoInstall/"+gitversion)
91+
6092
client := &http.Client{}
6193
resp, err := client.Do(req)
62-
6394
if err != nil {
6495
fmt.Printf("尝试 %d/%d 下载失败: %v\n", i+1, maxRetries, err)
6596
continue
@@ -72,38 +103,31 @@ func DownloadFile(url, filePath string) error {
72103
}
73104

74105
if start > 0 && resp.StatusCode != http.StatusPartialContent {
75-
fmt.Printf("服务器不支持断点续传,状态码: %d,尝试重新下载\n", resp.StatusCode)
106+
fmt.Printf("服务器不支持断点续传,状态码: %d,重新下载...\n", resp.StatusCode)
76107
start = 0
77-
os.Remove(filePath) // 删除已存在的文件,重新下载
108+
os.Remove(filePath)
78109
continue
79110
}
80111

81112
if start == 0 && resp.StatusCode != http.StatusOK {
82-
fmt.Printf("尝试 %d/%d,HTTP 状态码: %d\n", i+1, maxRetries, resp.StatusCode)
113+
fmt.Printf("HTTP 状态码: %d\n", resp.StatusCode)
83114
continue
84115
}
85116

86-
total := resp.ContentLength + start
87-
if total <= 0 {
88-
fmt.Println("无法获取文件大小,将不显示进度")
89-
}
90-
91117
var outFile *os.File
92-
var createErr error
93118
if start > 0 {
94-
outFile, createErr = os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY, 0644)
119+
outFile, err = os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY, 0644)
95120
} else {
96-
outFile, createErr = os.Create(filePath)
121+
outFile, err = os.Create(filePath)
97122
}
98-
99-
if createErr != nil {
100-
return fmt.Errorf("创建/追加文件失败: %w", createErr)
123+
if err != nil {
124+
return fmt.Errorf("打开文件失败: %w", err)
101125
}
102126
defer outFile.Close()
103127

104128
reader := &ProgressReader{
105129
Reader: resp.Body,
106-
Total: total,
130+
Total: totalSize,
107131
Current: start,
108132
FilePath: filePath,
109133
UpdateInterval: 3,
@@ -119,5 +143,54 @@ func DownloadFile(url, filePath string) error {
119143
return nil
120144
}
121145

122-
return fmt.Errorf("多次尝试下载失败 (共 %d 次)", maxRetries)
146+
return fmt.Errorf("多次尝试下载失败")
147+
}
148+
149+
// 分片下载
150+
func chunkDownload(url, filePath string, totalSize int64, chunkSize int64) error {
151+
outFile, err := os.Create(filePath)
152+
if err != nil {
153+
return fmt.Errorf("创建文件失败: %w", err)
154+
}
155+
defer outFile.Close()
156+
157+
var downloaded int64 = 0
158+
client := &http.Client{}
159+
160+
for downloaded < totalSize {
161+
end := downloaded + chunkSize - 1
162+
if end >= totalSize {
163+
end = totalSize - 1
164+
}
165+
166+
req, _ := http.NewRequest("GET", url, nil)
167+
req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", downloaded, end))
168+
req.Header.Set("User-Agent", "AutoInstall/"+gitversion)
169+
170+
resp, err := client.Do(req)
171+
if err != nil {
172+
return fmt.Errorf("分片请求失败: %w", err)
173+
}
174+
if resp.StatusCode != http.StatusPartialContent {
175+
return fmt.Errorf("服务器不支持分片下载,状态码: %d", resp.StatusCode)
176+
}
177+
178+
n, err := io.Copy(outFile, resp.Body)
179+
resp.Body.Close()
180+
if err != nil {
181+
return fmt.Errorf("写入分片失败: %w", err)
182+
}
183+
184+
downloaded += n
185+
percent := float64(downloaded) / float64(totalSize) * 100
186+
fmt.Printf("下载进度: %.2f%% (%s)\n", percent, filePath)
187+
}
188+
189+
fmt.Println("下载完成!")
190+
return nil
191+
}
192+
193+
// 判断字符串前缀
194+
func startsWith(s, prefix string) bool {
195+
return len(s) >= len(prefix) && s[:len(prefix)] == prefix
123196
}

main.go

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,52 +14,73 @@ import (
1414
var gitversion string
1515

1616
func Search() {
17-
mrpackFiles, err := filepath.Glob("modpack.mrpack")
18-
if err != nil {
19-
return
20-
}
21-
indexFiles, err := filepath.Glob("modrinth.index.json")
22-
if err != nil {
23-
return
24-
}
25-
zipFiles, err := filepath.Glob("modpack.zip")
26-
if err != nil {
27-
return
28-
}
29-
variablesFiles, err := filepath.Glob("variables.txt")
30-
if err != nil {
31-
return
32-
}
17+
mrpackFiles, _ := filepath.Glob("modpack.mrpack")
18+
indexFiles, _ := filepath.Glob("modrinth.index.json")
19+
zipFiles, _ := filepath.Glob("modpack.zip")
20+
variablesFiles, _ := filepath.Glob("variables.txt")
21+
22+
allMrpacks, _ := filepath.Glob("*.mrpack")
23+
allZips, _ := filepath.Glob("*.zip")
3324

25+
// 合并整合包文件
26+
allPacks := append(allMrpacks, allZips...)
27+
28+
// 合并所有类型文件用于判断是否完全为空
3429
allFiles := append(append(append(mrpackFiles, indexFiles...), zipFiles...), variablesFiles...)
3530

36-
if len(allFiles) == 0 {
37-
fmt.Println("未找到整合包")
38-
return
39-
}
31+
// 输出已有文件信息
4032
for _, file := range mrpackFiles {
41-
fmt.Println("已有" + file)
33+
fmt.Println("已有 " + file)
4234
pkg.Modrinth(file)
4335
}
4436
for _, file := range indexFiles {
45-
fmt.Println("已有" + file)
37+
fmt.Println("已有 " + file)
4638
pkg.Modrinth(file)
4739
}
4840
for _, zipFile := range zipFiles {
49-
fmt.Println("发现其他整合包")
41+
fmt.Println("已有 " + zipFile)
5042
pkg.SPCInstall(zipFile)
5143
}
5244

53-
// 如果只有其他文件,则使用第一个
54-
if len(allFiles) == 1 {
55-
fmt.Println("发现整合包: " + allFiles[0])
56-
pkg.SPCInstall(allFiles[0])
57-
} else if len(allFiles) > 1 {
58-
fmt.Println("发现多个整合包,请手动指定")
59-
for _, file := range allFiles {
45+
if len(allFiles) == 0 && len(allPacks) == 0 {
46+
fmt.Println("未找到整合包")
47+
return
48+
}
49+
50+
if contains(allMrpacks, "modpack.mrpack") {
51+
fmt.Println("发现整合包: modpack.mrpack")
52+
pkg.SPCInstall("modpack.mrpack")
53+
return
54+
} else if contains(allZips, "modpack.zip") {
55+
fmt.Println("发现整合包: modpack.zip")
56+
pkg.SPCInstall("modpack.zip")
57+
return
58+
}
59+
60+
// 只有一个整合包
61+
if len(allPacks) == 1 {
62+
fmt.Println("发现整合包: " + allPacks[0])
63+
pkg.SPCInstall(allPacks[0])
64+
return
65+
}
66+
67+
// 多个整合包
68+
if len(allPacks) > 1 {
69+
fmt.Println("发现多个整合包,但未找到 modpack.zip 或 modpack.mrpack")
70+
fmt.Println("请将要使用的整合包重命名为 modpack.zip 或 modpack.mrpack 后重试")
71+
for _, file := range allPacks {
6072
fmt.Println(" " + file)
6173
}
74+
os.Exit(0)
75+
}
76+
}
77+
func contains(list []string, target string) bool {
78+
for _, item := range list {
79+
if item == target {
80+
return true
81+
}
6282
}
83+
return false
6384
}
6485

6586
func main() {

0 commit comments

Comments
 (0)