UPDATE: Add precheck version hdiff, support another hdiff

This commit is contained in:
2025-08-29 21:13:10 +07:00
parent a4de02bc18
commit d58e76d821
12 changed files with 212 additions and 154 deletions

View File

@@ -7,6 +7,7 @@ import (
"firefly-launcher/pkg/hpatchz"
"firefly-launcher/pkg/models"
"firefly-launcher/pkg/sevenzip"
"firefly-launcher/pkg/verifier"
"fmt"
"os"
"path/filepath"
@@ -21,6 +22,9 @@ func (h *DiffService) CheckTypeHDiff(patchPath string) (bool, string, string) {
if ok, err := sevenzip.IsFileIn7z(patchPath, "hdifffiles.txt"); err == nil && ok {
return true, "hdifffiles.txt", ""
}
if ok, err := sevenzip.IsFileIn7z(patchPath, "hdifffiles.txt"); err == nil && ok {
return true, "hdifffiles.json", ""
}
if ok, err := sevenzip.IsFileIn7z(patchPath, "hdiffmap.json"); err == nil && ok {
return true, "hdiffmap.json", ""
}
@@ -31,8 +35,9 @@ func (h *DiffService) CheckTypeHDiff(patchPath string) (bool, string, string) {
return false, "", "not found hdifffiles.txt or hdiffmap.json"
}
func (h *DiffService) VersionValidate(gamePath, patchPath string) (bool, string) {
oldVersionData, err := models.ParseBinaryVersion(filepath.Join(gamePath, "StarRail_Data\\StreamingAssets\\BinaryVersion.bytes"))
func (h *DiffService) VersionValidate(gamePath, patchPath string, isNeedHDiff bool) (bool, string) {
oldBinPath := filepath.Join(gamePath, "StarRail_Data\\StreamingAssets\\BinaryVersion.bytes")
oldVersionData, err := models.ParseBinaryVersion(oldBinPath)
if err != nil {
return false, err.Error()
}
@@ -46,28 +51,104 @@ func (h *DiffService) VersionValidate(gamePath, patchPath string) (bool, string)
return false, err.Error()
}
}
if err := sevenzip.ExtractAFileFromZip(patchPath, "StarRail_Data\\StreamingAssets\\BinaryVersion.bytes", constant.TempUrl); err != nil {
if !isNeedHDiff {
if err := sevenzip.ExtractAFileFromZip(patchPath, "StarRail_Data\\StreamingAssets\\BinaryVersion.bytes", constant.TempUrl); err != nil {
return false, err.Error()
}
binPath := filepath.Join(constant.TempUrl, "BinaryVersion.bytes")
newVersionData, err := models.ParseBinaryVersion(binPath)
if err != nil {
return false, err.Error()
}
defer os.Remove(binPath)
v := newVersionData.Subtract(oldVersionData)
if v != 0 && v != 1 {
return false, fmt.Sprintf("the diff version %s not valid with game version %s", newVersionData, oldVersionData)
}
return true, "validated"
}
if err := sevenzip.ExtractAFileFromZip(patchPath, "StarRail_Data\\StreamingAssets\\BinaryVersion.bytes.hdiff", constant.TempUrl); err != nil {
return false, err.Error()
}
binPath := filepath.Join(constant.TempUrl, "BinaryVersion.bytes")
newVersionData, err := models.ParseBinaryVersion(binPath)
patchBinFile := filepath.Join(constant.TempUrl, "BinaryVersion.bytes.hdiff")
sourceBinFile := filepath.Join(gamePath, "StarRail_Data\\StreamingAssets\\BinaryVersion.bytes")
tempBinFile := filepath.Join(constant.TempUrl, "BinaryVersion.bytes")
if err := hpatchz.ApplyPatch(sourceBinFile, patchBinFile, tempBinFile); err != nil {
os.Remove(patchBinFile)
return false, err.Error()
}
os.Remove(patchBinFile)
okFullPkg, err1 := sevenzip.IsFileIn7z(patchPath, "pkg_version")
okDiffPkg, err2 := sevenzip.IsFileIn7z(patchPath, "pkg_version.hdiff")
if err1 != nil && err2 != nil {
return false, err1.Error()
}
if okFullPkg {
if err := sevenzip.ExtractAFileFromZip(patchPath, "pkg_version", constant.TempUrl); err != nil {
return false, err.Error()
}
}
if okDiffPkg {
if err := sevenzip.ExtractAFileFromZip(patchPath, "pkg_version.hdiff", constant.TempUrl); err != nil {
return false, err.Error()
}
patchPkgFile := filepath.Join(constant.TempUrl, "pkg_version.hdiff")
sourcePkgFile := filepath.Join(gamePath, "pkg_version")
tempPkgFile := filepath.Join(constant.TempUrl, "pkg_version")
if err := hpatchz.ApplyPatch(sourcePkgFile, patchPkgFile, tempPkgFile); err != nil {
os.Remove(patchPkgFile)
os.Remove(tempPkgFile)
return false, err.Error()
}
os.Remove(patchPkgFile)
}
tempPkgFile := filepath.Join(constant.TempUrl, "pkg_version")
pkgDataList, err := models.LoadPkgVersion(tempPkgFile)
if err != nil {
os.Remove(tempPkgFile)
return false, err.Error()
}
defer os.Remove(binPath)
os.Remove(tempPkgFile)
v := newVersionData.Subtract(*oldVersionData)
if v != 0 && v != 1 {
return false, fmt.Sprintf("the diff version %s not valid with game version %s", newVersionData, oldVersionData)
for _, pkgData := range pkgDataList {
if filepath.ToSlash(pkgData.RemoteFile) == "StarRail_Data/StreamingAssets/BinaryVersion.bytes" {
md5, err := verifier.FileMD5(tempBinFile)
if err != nil {
os.Remove(tempBinFile)
return false, err.Error()
}
if md5 != pkgData.MD5 {
os.Remove(tempBinFile)
return false, fmt.Sprintf("md5 mismatch for %s: expected %s, got %s",
tempBinFile, pkgData.MD5, md5)
}
break
}
}
_, err = models.ParseBinaryVersion(tempBinFile)
if err != nil {
os.Remove(tempBinFile)
return false, err.Error()
}
os.Remove(tempBinFile)
return true, "validated"
}
func (h *DiffService) HDiffPatchData(gamePath string) (bool, string) {
hdiffMapPath := filepath.Join(gamePath, "hdiffmap.json")
hdiffFilesPath := filepath.Join(gamePath, "hdifffiles.txt")
hdifffilesJsonPath := filepath.Join(gamePath, "hdifffiles.json")
var jsonData struct {
DiffMap []*models.HDiffData `json:"diff_map"`
@@ -88,6 +169,14 @@ func (h *DiffService) HDiffPatchData(gamePath string) (bool, string) {
for _, entry := range jsonDataDiffMap.DiffMap {
jsonData.DiffMap = append(jsonData.DiffMap, entry.ToHDiffData())
}
} else if _, err := os.Stat(hdifffilesJsonPath); err == nil {
data, err := os.ReadFile(hdifffilesJsonPath)
if err != nil {
return false, err.Error()
}
if err := json.Unmarshal(data, &jsonData); err != nil {
return false, err.Error()
}
} else if _, err := os.Stat(hdiffFilesPath); err == nil {
files, err := models.LoadHDiffFiles(hdiffFilesPath)
if err != nil {
@@ -99,6 +188,7 @@ func (h *DiffService) HDiffPatchData(gamePath string) (bool, string) {
} else {
return false, "no hdiff entries map exist"
}
application.Get().Event.Emit("diff:stage", map[string]string{"stage": "Patching HDiff"})
for i, entry := range jsonData.DiffMap {
application.Get().Event.Emit(
@@ -134,6 +224,7 @@ func (h *DiffService) HDiffPatchData(gamePath string) (bool, string) {
os.Remove(filepath.Join(gamePath, "hdiffmap.json"))
os.Remove(filepath.Join(gamePath, "hdifffiles.txt"))
os.Remove(filepath.Join(gamePath, "hdifffiles.json"))
return true, "patching completed"
}