From 8a7d7ccb93c1c21067a6042164b8e1105aaf6830 Mon Sep 17 00:00:00 2001 From: Sean Du Date: Tue, 28 Apr 2026 11:44:33 +0800 Subject: [PATCH] Add support for server config override Add settings.override_server_config with enable flag and per-platform (Android/iOS) url + size fields. Use this config in /download/update to override the fixed 99_0_115.zip package source when needed. Signed-off-by: Sean Du --- config/config.go | 29 ++++++++- doc/4.md | 26 +++++++++ internal/handler/download/update.go | 91 ++++++++++++++++++++++++----- static/.gitignore | 2 + 4 files changed, 130 insertions(+), 18 deletions(-) diff --git a/config/config.go b/config/config.go index fed83af..3769003 100644 --- a/config/config.go +++ b/config/config.go @@ -23,9 +23,21 @@ type AppConfigs struct { } type Settings struct { - ListenPort string `json:"listen_port"` - CdnServer string `json:"cdn_server"` - BackupCdnServer string `json:"backup_cdn_server"` + ListenPort string `json:"listen_port"` + CdnServer string `json:"cdn_server"` + BackupCdnServer string `json:"backup_cdn_server"` + OverrideServerConfig OverrideServerConfig `json:"override_server_config"` +} + +type OverrideServerConfig struct { + Enable bool `json:"enable"` + Android OverrideFileSource `json:"android"` + IOS OverrideFileSource `json:"ios"` +} + +type OverrideFileSource struct { + URL string `json:"url"` + Size int `json:"size"` } func InitConfig() { @@ -39,6 +51,17 @@ func DefaultConfigs() *AppConfigs { ListenPort: "8080", CdnServer: "http://127.0.0.1:8080/static", BackupCdnServer: "", + OverrideServerConfig: OverrideServerConfig{ + Enable: false, + Android: OverrideFileSource{ + URL: "", + Size: 0, + }, + IOS: OverrideFileSource{ + URL: "", + Size: 0, + }, + }, }, } } diff --git a/doc/4.md b/doc/4.md index 079e220..9f8a964 100644 --- a/doc/4.md +++ b/doc/4.md @@ -4,6 +4,32 @@ 启动游戏,查看 `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` 下载。 + +如果你需要改成其他地址(例如不走 `cdn_server`),可以启用 `settings.override_server_config`。该配置固定用于 `99_0_115.zip`,分别设置 Android 和 iOS 的下载地址与大小: + +```json +{ + "settings": { + "override_server_config": { + "enable": true, + "android": { + "url": "http://your-host.example.com/Android/archives/99_0_115.zip", + "size": 0 + }, + "ios": { + "url": "http://your-host.example.com/iOS/archives/99_0_115.zip", + "size": 0 + } + } + } +} +``` + +`url` 为下载地址,仅支持 HTTP 协议。 + +`size` 可选,填 `0` 会在服务端请求该 URL 自动探测文件大小;如果你已知大小,建议直接填写可减少请求开销。 + 登录方式为 `手机号密码登录`,都可以随便输。第一次使用的手机号会自动生成账号并记住登录的密码,以及后续的游戏内设置都会保存。 ### SIF 测试 diff --git a/internal/handler/download/update.go b/internal/handler/download/update.go index 4c0b5df..206349c 100644 --- a/internal/handler/download/update.go +++ b/internal/handler/download/update.go @@ -10,10 +10,14 @@ import ( "honoka-chan/internal/session" "io" "net/http" + "strings" + "time" "github.com/gin-gonic/gin" ) +const overrideServerConfigFileName = "99_0_115.zip" + func update(ctx *gin.Context) { ss := session.Get(ctx) defer ss.Finalize() @@ -35,28 +39,48 @@ func update(ctx *gin.Context) { return } + pkgMap := map[string]int{} for _, pkg := range pkgInfo { + fileName := fmt.Sprintf("%d_%d_%d.zip", pkgType, pkg.Id, pkg.Order) + url := fmt.Sprintf("%s/%s/archives/%s", + config.Conf.Settings.CdnServer, downloadReq.TargetOs, fileName) + pkgList = append(pkgList, downloadschema.UpdateData{ - Size: pkg.Size, - URL: fmt.Sprintf("%s/%s/archives/%d_%d_%d.zip", - config.Conf.Settings.CdnServer, downloadReq.TargetOs, pkgType, pkg.Id, pkg.Order), + Size: pkg.Size, + URL: url, Version: config.PackageVersion, }) + pkgMap[fileName] = len(pkgList) - 1 } - patchFileURL := fmt.Sprintf("%s/%s/archives/99_0_115.zip", - config.Conf.Settings.CdnServer, downloadReq.TargetOs) - resp, err := http.Get(patchFileURL) - if err == nil { - res, err := io.ReadAll(resp.Body) - if err == nil { - pkgList = append(pkgList, download.UpdateData{ - Size: len(res), - URL: patchFileURL, - Version: config.PackageVersion, - }) + serverConfigURL := fmt.Sprintf("%s/%s/archives/%s", + config.Conf.Settings.CdnServer, downloadReq.TargetOs, overrideServerConfigFileName) + serverConfigSize := getRemoteFileSize(serverConfigURL) + + 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 + } } - defer resp.Body.Close() + } + + if index, ok := pkgMap[overrideServerConfigFileName]; ok { + pkgList[index].URL = serverConfigURL + if serverConfigSize > 0 { + pkgList[index].Size = serverConfigSize + } + } else { + pkgList = append(pkgList, downloadschema.UpdateData{ + Size: serverConfigSize, + URL: serverConfigURL, + Version: config.PackageVersion, + }) } } @@ -67,6 +91,43 @@ func update(ctx *gin.Context) { }) } +func getOverrideSource(targetOs string) config.OverrideFileSource { + if strings.EqualFold(targetOs, "Android") { + return config.Conf.Settings.OverrideServerConfig.Android + } + if strings.EqualFold(targetOs, "iOS") { + return config.Conf.Settings.OverrideServerConfig.IOS + } + return config.OverrideFileSource{} +} + +func getRemoteFileSize(url string) int { + 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) + } + } + } + + getResp, err := client.Get(url) + if err != nil { + return 0 + } + defer getResp.Body.Close() + + dataLen, err := io.Copy(io.Discard, getResp.Body) + if err != nil { + return 0 + } + + return int(dataLen) +} + func init() { router.AddHandler("main.php", "POST", "/download/update", middleware.Common, update) } diff --git a/static/.gitignore b/static/.gitignore index 16e716b..4abaf42 100644 --- a/static/.gitignore +++ b/static/.gitignore @@ -2,3 +2,5 @@ f7f2ac627227500b Android iOS + +updates