mirror of Walter-Sparrow / lunar-tear
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix locale fallback MD5 validation for ja/ko -> en asset candidates

+32 -14
+32 -14
server/internal/service/listbin.go
··· 313 313 return m 314 314 } 315 315 316 - func pathStrToFullPaths(revision, assetType, pathStr string) []string { 316 + type pathCandidate struct { 317 + Path string 318 + IsLocaleFallback bool 319 + } 320 + 321 + // pathStrToFullPaths converts a list.bin path string (using ')' separators) into filesystem 322 + // candidates. The original locale path is returned first; if the path contains ja or ko, 323 + // an en locale fallback is appended (marked IsLocaleFallback so callers can skip MD5 validation). 324 + func pathStrToFullPaths(revision, assetType, pathStr string) []pathCandidate { 317 325 fsPath := strings.ReplaceAll(pathStr, ")", "/") 318 326 if strings.Contains(fsPath, "..") || filepath.IsAbs(fsPath) || strings.HasPrefix(fsPath, "/") { 319 327 return nil ··· 322 330 if strings.Contains(fsPath, "..") { 323 331 return nil 324 332 } 325 - // Prefer "global" (en) when list.bin points to ja/ko: try en first, then original. 326 - var pathStrs []string 333 + type tagged struct { 334 + pathStr string 335 + fallback bool 336 + } 337 + entries := []tagged{{pathStr, false}} 327 338 if strings.Contains(pathStr, ")ja)") { 328 - pathStrs = append(pathStrs, strings.ReplaceAll(pathStr, ")ja)", ")en)")) 339 + entries = append(entries, tagged{strings.ReplaceAll(pathStr, ")ja)", ")en)"), true}) 329 340 } 330 341 if strings.Contains(pathStr, ")ko)") { 331 - pathStrs = append(pathStrs, strings.ReplaceAll(pathStr, ")ko)", ")en)")) 342 + entries = append(entries, tagged{strings.ReplaceAll(pathStr, ")ko)", ")en)"), true}) 332 343 } 333 - pathStrs = append(pathStrs, pathStr) 334 344 base := filepath.Join("assets", "revisions", revision) 335 - var out []string 345 + var out []pathCandidate 336 346 seen := make(map[string]bool) 337 - for _, p := range pathStrs { 338 - cleaned := filepath.Clean(strings.ReplaceAll(p, ")", "/")) 347 + for _, e := range entries { 348 + cleaned := filepath.Clean(strings.ReplaceAll(e.pathStr, ")", "/")) 339 349 if seen[cleaned] { 340 350 continue 341 351 } 342 352 seen[cleaned] = true 353 + var fullPath string 343 354 switch assetType { 344 355 case "assetbundle": 345 - out = append(out, filepath.Join(base, "assetbundle", cleaned+".assetbundle")) 356 + fullPath = filepath.Join(base, "assetbundle", cleaned+".assetbundle") 346 357 case "resources": 347 - out = append(out, filepath.Join(base, "resources", cleaned)) 358 + fullPath = filepath.Join(base, "resources", cleaned) 348 359 default: 349 360 return nil 350 361 } 362 + out = append(out, pathCandidate{Path: fullPath, IsLocaleFallback: e.fallback}) 351 363 } 352 364 return out 353 365 } ··· 372 384 373 385 // objectIdToFilePathCandidates returns candidate file paths for the object: list.bin path, locale fallbacks 374 386 // (ja/ko -> en), then info.json duplicate mappings (from-name -> to-name, possibly in a different revision). 387 + // The original locale path is tried first (with MD5 validation); locale fallbacks are tried after 388 + // (without MD5 validation, since the hash in list.bin refers to the original locale's content). 375 389 // Callers should try each path until one exists on disk. 376 390 func objectIdToFilePathCandidates(revision, assetType, objectId string) (candidates []assetCandidate, size int64, ok bool) { 377 391 idx, ok := loadListBinIndex(revision) ··· 387 401 return nil, 0, false 388 402 } 389 403 seen := make(map[string]bool) 390 - for _, path := range paths { 404 + for _, pc := range paths { 405 + md5 := entry.MD5 406 + if pc.IsLocaleFallback { 407 + md5 = "" 408 + } 391 409 candidates = appendUniqueCandidate(candidates, seen, assetCandidate{ 392 - Path: path, 410 + Path: pc.Path, 393 411 Revision: revision, 394 412 Source: "list.bin", 395 - ExpectedMD5: entry.MD5, 413 + ExpectedMD5: md5, 396 414 }) 397 415 } 398 416 // Add paths from info.json: when requested file is a "from-name" (duplicate not included), serve "to-name" instead.