213 lines
5.1 KiB
Go
213 lines
5.1 KiB
Go
package internal
|
|
|
|
import (
|
|
"bufio"
|
|
"encoding/json"
|
|
"firefly-launcher/pkg/constant"
|
|
"firefly-launcher/pkg/models"
|
|
"firefly-launcher/pkg/sevenzip"
|
|
"firefly-launcher/pkg/verifier"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"github.com/wailsapp/wails/v3/pkg/application"
|
|
)
|
|
|
|
type HdiffzService struct{}
|
|
|
|
func (h *HdiffzService) VersionValidate(gamePath, patchPath string) (bool, string) {
|
|
oldVersionData, err := models.ParseBinaryVersion(filepath.Join(gamePath, "StarRail_Data\\StreamingAssets\\BinaryVersion.bytes"))
|
|
if err != nil {
|
|
return false, err.Error()
|
|
}
|
|
|
|
if _, err := os.Stat(patchPath); err != nil {
|
|
return false, err.Error()
|
|
}
|
|
|
|
if _, err := os.Stat(constant.TempUrl); os.IsNotExist(err) {
|
|
if err := os.MkdirAll(constant.TempUrl, os.ModePerm); err != nil {
|
|
return false, err.Error()
|
|
}
|
|
}
|
|
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"
|
|
}
|
|
func (h *HdiffzService) DataExtract(gamePath, patchPath string) (bool, string) {
|
|
if _, err := os.Stat(gamePath); err != nil {
|
|
return false, err.Error()
|
|
}
|
|
|
|
if _, err := os.Stat(patchPath); err != nil {
|
|
return false, err.Error()
|
|
}
|
|
|
|
if _, err := os.Stat(constant.TempUrl); os.IsNotExist(err) {
|
|
if err := os.MkdirAll(constant.TempUrl, os.ModePerm); err != nil {
|
|
return false, err.Error()
|
|
}
|
|
}
|
|
|
|
if err := sevenzip.ExtractAllFilesFromZip(patchPath, constant.TempUrl); err != nil {
|
|
os.RemoveAll(constant.TempUrl)
|
|
return false, err.Error()
|
|
}
|
|
|
|
validator, err := verifier.NewVerifier(gamePath, constant.TempUrl)
|
|
if err != nil {
|
|
os.RemoveAll(constant.TempUrl)
|
|
return false, err.Error()
|
|
}
|
|
|
|
if err := validator.VerifyAll(); err != nil {
|
|
os.RemoveAll(constant.TempUrl)
|
|
return false, err.Error()
|
|
}
|
|
|
|
return true, "validated"
|
|
}
|
|
|
|
func (h *HdiffzService) CutData(gamePath string) (bool, string) {
|
|
if _, err := os.Stat(constant.TempUrl); os.IsNotExist(err) {
|
|
return false, err.Error()
|
|
}
|
|
|
|
err := filepath.Walk(constant.TempUrl, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
relPath, err := filepath.Rel(constant.TempUrl, path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
destPath := filepath.Join(gamePath, relPath)
|
|
application.Get().EmitEvent("hdiffz:message", map[string]string{"message": destPath})
|
|
if info.IsDir() {
|
|
return os.MkdirAll(destPath, os.ModePerm)
|
|
}
|
|
|
|
if err := os.MkdirAll(filepath.Dir(destPath), os.ModePerm); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := os.Rename(path, destPath); err != nil {
|
|
srcFile, err := os.Open(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer srcFile.Close()
|
|
|
|
dstFile, err := os.Create(destPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer dstFile.Close()
|
|
|
|
if _, err := io.Copy(dstFile, srcFile); err != nil {
|
|
return err
|
|
}
|
|
_ = os.Remove(path)
|
|
}
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return false, err.Error()
|
|
}
|
|
|
|
_ = os.RemoveAll(constant.TempUrl)
|
|
|
|
return true, "cut completed"
|
|
}
|
|
|
|
func (h *HdiffzService) PatchData(gamePath string) (bool, string) {
|
|
data, err := os.ReadFile(filepath.Join(gamePath, "hdiffmap.json"))
|
|
if err != nil {
|
|
return false, err.Error()
|
|
}
|
|
|
|
var jsonData struct {
|
|
DiffMap []*models.DiffMapType `json:"diff_map"`
|
|
}
|
|
if err := json.Unmarshal(data, &jsonData); err != nil {
|
|
return false, err.Error()
|
|
}
|
|
|
|
for i, entry := range jsonData.DiffMap {
|
|
application.Get().EmitEvent(
|
|
"hdiffz:progress", map[string]int{
|
|
"progress": i,
|
|
"maxProgress": len(jsonData.DiffMap),
|
|
})
|
|
sourceFile := filepath.Join(gamePath, entry.SourceFileName)
|
|
patchFile := filepath.Join(gamePath, entry.PatchFileName)
|
|
targetFile := filepath.Join(gamePath, entry.TargetFileName)
|
|
|
|
if _, err := os.Stat(sourceFile); os.IsNotExist(err) {
|
|
continue
|
|
}
|
|
if _, err := os.Stat(patchFile); os.IsNotExist(err) {
|
|
continue
|
|
}
|
|
|
|
cmd := exec.Command(constant.ToolHPatchzExe.String(), sourceFile, patchFile, targetFile)
|
|
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
|
_, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
}
|
|
|
|
return true, "patching completed"
|
|
}
|
|
|
|
func (h *HdiffzService) DeleteFiles(gamePath string) (bool, string) {
|
|
var deleteFiles []string
|
|
|
|
file, err := os.Open(filepath.Join(gamePath, "deletefiles.txt"))
|
|
if err != nil {
|
|
return false, ""
|
|
}
|
|
defer file.Close()
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
for scanner.Scan() {
|
|
line := strings.TrimSpace(scanner.Text())
|
|
if line != "" {
|
|
deleteFiles = append(deleteFiles, line)
|
|
}
|
|
}
|
|
|
|
if err := scanner.Err(); err != nil {
|
|
return false, ""
|
|
}
|
|
|
|
for i, file := range deleteFiles {
|
|
os.Remove(filepath.Join(gamePath, file))
|
|
application.Get().EmitEvent("hdiffz:progress", map[string]int{"progress": i, "maxProgress": len(deleteFiles)})
|
|
}
|
|
|
|
return true, ""
|
|
}
|