feat(config): 添加配置管理功能

This commit is contained in:
2025-07-20 18:12:35 +08:00
parent 228e66315c
commit 747ad6387b
4 changed files with 827 additions and 51 deletions

View File

@@ -15,17 +15,17 @@ type MirrorResponse struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data struct {
VersionName string `json:"version_name"`
VersionNumber int `json:"version_number"`
URL string `json:"url,omitempty"` // Only present when using CDK
SHA256 string `json:"sha256,omitempty"` // Only present when using CDK
Channel string `json:"channel"`
OS string `json:"os"`
Arch string `json:"arch"`
UpdateType string `json:"update_type,omitempty"` // Only present when using CDK
ReleaseNote string `json:"release_note"`
FileSize int64 `json:"filesize,omitempty"` // Only present when using CDK
CDKExpiredTime int64 `json:"cdk_expired_time,omitempty"` // Only present when using CDK
VersionName string `json:"version_name"`
VersionNumber int `json:"version_number"`
URL string `json:"url,omitempty"` // Only present when using CDK
SHA256 string `json:"sha256,omitempty"` // Only present when using CDK
Channel string `json:"channel"`
OS string `json:"os"`
Arch string `json:"arch"`
UpdateType string `json:"update_type,omitempty"` // Only present when using CDK
ReleaseNote string `json:"release_note"`
FileSize int64 `json:"filesize,omitempty"` // Only present when using CDK
CDKExpiredTime int64 `json:"cdk_expired_time,omitempty"` // Only present when using CDK
} `json:"data"`
}
@@ -66,62 +66,62 @@ func NewClient() *Client {
func (c *Client) CheckUpdate(params UpdateCheckParams) (*MirrorResponse, error) {
// Construct the API URL
apiURL := fmt.Sprintf("%s/%s/latest", c.baseURL, params.ResourceID)
// Parse URL to add query parameters
u, err := url.Parse(apiURL)
if err != nil {
return nil, fmt.Errorf("failed to parse API URL: %w", err)
}
// Add query parameters
q := u.Query()
q.Set("current_version", params.CurrentVersion)
q.Set("channel", params.Channel)
q.Set("os", "") // Empty for cross-platform
q.Set("arch", "") // Empty for cross-platform
q.Set("os", "") // Empty for cross-platform
q.Set("arch", "") // Empty for cross-platform
if params.CDK != "" {
q.Set("cdk", params.CDK)
}
u.RawQuery = q.Encode()
// Create HTTP request
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
return nil, fmt.Errorf("failed to create HTTP request: %w", err)
}
// Set User-Agent header
if params.UserAgent != "" {
req.Header.Set("User-Agent", params.UserAgent)
} else {
req.Header.Set("User-Agent", "LightweightUpdater/1.0")
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36")
}
// Make HTTP request
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("failed to make HTTP request: %w", err)
}
defer resp.Body.Close()
// Check HTTP status code
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API returned non-200 status code: %d", resp.StatusCode)
}
// Read response body
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response body: %w", err)
}
// Parse JSON response
var mirrorResp MirrorResponse
if err := json.Unmarshal(body, &mirrorResp); err != nil {
return nil, fmt.Errorf("failed to parse JSON response: %w", err)
}
return &mirrorResp, nil
}
@@ -129,13 +129,13 @@ func (c *Client) CheckUpdate(params UpdateCheckParams) (*MirrorResponse, error)
func (c *Client) CheckUpdateLegacy(resourceID, currentVersion, cdk, userAgent string) (*MirrorResponse, error) {
// Construct the API URL
apiURL := fmt.Sprintf("%s/%s/latest", c.baseURL, resourceID)
// Parse URL to add query parameters
u, err := url.Parse(apiURL)
if err != nil {
return nil, fmt.Errorf("failed to parse API URL: %w", err)
}
// Add query parameters
q := u.Query()
q.Set("current_version", currentVersion)
@@ -143,44 +143,44 @@ func (c *Client) CheckUpdateLegacy(resourceID, currentVersion, cdk, userAgent st
q.Set("cdk", cdk)
}
u.RawQuery = q.Encode()
// Create HTTP request
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
return nil, fmt.Errorf("failed to create HTTP request: %w", err)
}
// Set User-Agent header
if userAgent != "" {
req.Header.Set("User-Agent", userAgent)
} else {
req.Header.Set("User-Agent", "LightweightUpdater/1.0")
}
// Make HTTP request
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("failed to make HTTP request: %w", err)
}
defer resp.Body.Close()
// Check HTTP status code
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API returned non-200 status code: %d", resp.StatusCode)
}
// Read response body
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response body: %w", err)
}
// Parse JSON response
var mirrorResp MirrorResponse
if err := json.Unmarshal(body, &mirrorResp); err != nil {
return nil, fmt.Errorf("failed to parse JSON response: %w", err)
}
return &mirrorResp, nil
}
@@ -190,17 +190,17 @@ func (c *Client) IsUpdateAvailable(response *MirrorResponse, currentVersion stri
if response.Code != 0 {
return false
}
// Get latest version from response
latestVersion := response.Data.VersionName
if latestVersion == "" {
return false
}
// Convert version formats for comparison
currentVersionNormalized := c.normalizeVersionForComparison(currentVersion)
latestVersionNormalized := c.normalizeVersionForComparison(latestVersion)
// Compare versions using semantic version comparison
return compareVersions(currentVersionNormalized, latestVersionNormalized) < 0
}
@@ -219,7 +219,7 @@ func (c *Client) normalizeVersionForComparison(version string) string {
}
}
}
// Return as-is if already in standard format
return version
}
@@ -230,17 +230,17 @@ func compareVersions(v1, v2 string) int {
// Normalize versions by removing 'v' prefix if present
v1 = normalizeVersion(v1)
v2 = normalizeVersion(v2)
// Parse version components
parts1 := parseVersionParts(v1)
parts2 := parseVersionParts(v2)
// Compare each component
maxLen := len(parts1)
if len(parts2) > maxLen {
maxLen = len(parts2)
}
for i := 0; i < maxLen; i++ {
var p1, p2 int
if i < len(parts1) {
@@ -249,14 +249,14 @@ func compareVersions(v1, v2 string) int {
if i < len(parts2) {
p2 = parts2[i]
}
if p1 < p2 {
return -1
} else if p1 > p2 {
return 1
}
}
return 0
}
@@ -273,10 +273,10 @@ func parseVersionParts(version string) []int {
if version == "" {
return []int{0}
}
parts := make([]int, 0, 3)
current := 0
for _, char := range version {
if char >= '0' && char <= '9' {
current = current*10 + int(char-'0')
@@ -288,15 +288,15 @@ func parseVersionParts(version string) []int {
break
}
}
// Add the last component
parts = append(parts, current)
// Ensure at least 3 components (major.minor.patch)
for len(parts) < 3 {
parts = append(parts, 0)
}
return parts
}
@@ -304,17 +304,17 @@ func parseVersionParts(version string) []int {
func (c *Client) GetOfficialDownloadURL(versionName string) string {
// Official download site base URL
baseURL := "http://221.236.27.82:10197/d/AUTO_MAA"
// Convert version name to filename format
// e.g., "v4.4.0" -> "AUTO_MAA_v4.4.0.zip"
// e.g., "v4.4.1-beta3" -> "AUTO_MAA_v4.4.1-beta.3.zip"
filename := fmt.Sprintf("AUTO_MAA_%s.zip", versionName)
// Handle beta versions: convert "beta3" to "beta.3"
if strings.Contains(filename, "-beta") && !strings.Contains(filename, "-beta.") {
filename = strings.Replace(filename, "-beta", "-beta.", 1)
}
return fmt.Sprintf("%s/%s", baseURL, filename)
}
@@ -329,4 +329,4 @@ func (c *Client) GetDownloadURL(response *MirrorResponse) string {
return response.Data.URL
}
return c.GetOfficialDownloadURL(response.Data.VersionName)
}
}