diff --git a/doc/4.md b/doc/4.md index 8696738..0c433e4 100644 --- a/doc/4.md +++ b/doc/4.md @@ -4,7 +4,7 @@ 启动游戏,查看 `honoka-chan` 窗口输出,第一次运行会生成配置文件 `config.json`。打开该文件,设置好 `sif_cdn_server`,如果你是按前面的操作,数据都放在本程序的 `static` 目录下的话,那就改成你的服务器地址+`static` 就行,类似默认生成的 `http://192.168.1.123/static`。如果你有自己的服务器存放更新数据,设置成相应地址即可。 -`99_0_115.zip` 是固定必选包。默认会从 `cdn_server/{系统}/archives/99_0_115.zip` 下载。 +`99_0_115.zip` 不是必选包。服务端会先尝试请求该文件,只有确认可访问时才会把它加入下载列表;请求不到就跳过,不影响数据库里的原始下载列表。 如果你需要改成其他地址(例如不走 `cdn_server`),可以启用 `settings.override_server_config`。该配置固定用于 `99_0_115.zip`,分别设置 Android 和 iOS 的下载地址与大小: @@ -30,6 +30,8 @@ `size` 可选,填 `0` 会在服务端请求该 URL 自动探测文件大小;如果你已知大小,建议直接填写可减少请求开销。 +启用覆盖配置后,会优先使用你填写的 `url`。如果该地址请求失败,`99_0_115.zip` 同样不会被下发,也不会再回退到 `cdn_server`。 + 如果第三方 CDN 上某些包实际文件大小与数据库 `pkg_size` 不一致(例如 `99_0_113.zip`),可以使用 `settings.override_file_size` 覆盖返回给客户端的大小(不改数据库): ```json diff --git a/internal/handler/download/update.go b/internal/handler/download/update.go index b514e5f..eae2ef0 100644 --- a/internal/handler/download/update.go +++ b/internal/handler/download/update.go @@ -53,34 +53,22 @@ func update(ctx *gin.Context) { pkgMap[fileName] = len(pkgList) - 1 } + overrideSource := getOverrideSource(downloadReq.TargetOs) serverConfigURL := fmt.Sprintf("%s/%s/archives/%s", config.Conf.Settings.CdnServer, downloadReq.TargetOs, overrideServerConfigFileName) - serverConfigSize := getRemoteFileSize(serverConfigURL) + serverConfigURL, serverConfigSize, serverConfigAvailable := resolveServerConfigFile(serverConfigURL, overrideSource) - overrideSource := getOverrideSource(downloadReq.TargetOs) - if config.Conf.Settings.OverrideServerConfig.Enable && overrideSource.URL != "" { - serverConfigURL = overrideSource.URL - if overrideSource.Size > 0 { - serverConfigSize = overrideSource.Size - } else { - overrideSize := getRemoteFileSize(serverConfigURL) - if overrideSize > 0 { - serverConfigSize = overrideSize - } - } - } - - if index, ok := pkgMap[overrideServerConfigFileName]; ok { - pkgList[index].URL = serverConfigURL - if serverConfigSize > 0 { + if serverConfigAvailable { + if index, ok := pkgMap[overrideServerConfigFileName]; ok { + pkgList[index].URL = serverConfigURL pkgList[index].Size = serverConfigSize + } else { + pkgList = append(pkgList, downloadschema.UpdateData{ + Size: serverConfigSize, + URL: serverConfigURL, + Version: config.PackageVersion, + }) } - } else { - pkgList = append(pkgList, downloadschema.UpdateData{ - Size: serverConfigSize, - URL: serverConfigURL, - Version: config.PackageVersion, - }) } applyOverrideFileSize(downloadReq.TargetOs, pkgList) @@ -103,31 +91,52 @@ func getOverrideSource(targetOs string) config.OverrideFileSource { return config.OverrideFileSource{} } -func getRemoteFileSize(url string) int { +func resolveServerConfigFile(defaultURL string, overrideSource config.OverrideFileSource) (string, int, bool) { + if config.Conf.Settings.OverrideServerConfig.Enable && overrideSource.URL != "" { + size, ok := getRemoteFileSize(overrideSource.URL) + if !ok { + return overrideSource.URL, 0, false + } + if overrideSource.Size > 0 { + size = overrideSource.Size + } + return overrideSource.URL, size, true + } + + size, ok := getRemoteFileSize(defaultURL) + return defaultURL, size, ok +} + +func getRemoteFileSize(url string) (int, bool) { client := &http.Client{Timeout: 5 * time.Second} headReq, err := http.NewRequest(http.MethodHead, url, nil) if err == nil { if resp, err := client.Do(headReq); err == nil { _ = resp.Body.Close() - if resp.ContentLength > 0 { - return int(resp.ContentLength) + if resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusMultipleChoices { + if resp.ContentLength > 0 { + return int(resp.ContentLength), true + } } } } getResp, err := client.Get(url) if err != nil { - return 0 + return 0, false } defer getResp.Body.Close() + if getResp.StatusCode < http.StatusOK || getResp.StatusCode >= http.StatusMultipleChoices { + return 0, false + } dataLen, err := io.Copy(io.Discard, getResp.Body) if err != nil { - return 0 + return 0, false } - return int(dataLen) + return int(dataLen), dataLen > 0 } func applyOverrideFileSize(targetOs string, pkgList []downloadschema.UpdateData) { @@ -147,7 +156,7 @@ func applyOverrideFileSize(targetOs string, pkgList []downloadschema.UpdateData) if strings.EqualFold(strings.TrimSpace(override.FileName), fileName) { size, ok := urlSizeCache[pkgList[i].URL] if !ok { - size = getRemoteFileSize(pkgList[i].URL) + size, _ = getRemoteFileSize(pkgList[i].URL) urlSizeCache[pkgList[i].URL] = size }