173 lines
4.1 KiB
Go
173 lines
4.1 KiB
Go
package diffService
|
|
|
|
import (
|
|
"firefly-launcher/pkg/firefly"
|
|
"firefly-launcher/pkg/firefly/pb"
|
|
"firefly-launcher/pkg/hpatchz"
|
|
"firefly-launcher/pkg/models"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/wailsapp/wails/v3/pkg/application"
|
|
)
|
|
|
|
func (h *DiffService) LDiffPatchData(gamePath string) (bool, string) {
|
|
entries, err := os.ReadDir(gamePath)
|
|
if err != nil {
|
|
return false, err.Error()
|
|
}
|
|
ldiffPath := filepath.Join(gamePath, "ldiff")
|
|
|
|
for _, entry := range entries {
|
|
if entry.IsDir() {
|
|
continue
|
|
}
|
|
if !entry.Type().IsRegular() {
|
|
continue
|
|
}
|
|
|
|
name := entry.Name()
|
|
if strings.HasPrefix(name, "manifest") {
|
|
manifestName := entry.Name()
|
|
manifestPath := filepath.Join(gamePath, manifestName)
|
|
|
|
manifest, err := firefly.LoadManifestProto(manifestPath)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
ldiffEntries, err := os.ReadDir(ldiffPath)
|
|
if err != nil {
|
|
return false, err.Error()
|
|
}
|
|
application.Get().Event.Emit("diff:stage", map[string]string{"stage": "Processing LDiff"})
|
|
for i, ldiffEntry := range ldiffEntries {
|
|
assetName := ldiffEntry.Name()
|
|
var matchingAssets []struct {
|
|
AssetName string
|
|
AssetSize int64
|
|
Asset *pb.AssetManifest
|
|
}
|
|
|
|
application.Get().Event.Emit(
|
|
"diff:progress", map[string]int{
|
|
"progress": i,
|
|
"maxProgress": len(ldiffEntries),
|
|
})
|
|
|
|
var wg sync.WaitGroup
|
|
var mu sync.Mutex
|
|
|
|
for _, assetGroup := range manifest.Assets {
|
|
assetGroup := assetGroup
|
|
wg.Go(func() {
|
|
if data := assetGroup.AssetData; data != nil {
|
|
for _, asset := range data.Assets {
|
|
if asset.ChunkFileName == assetName {
|
|
mu.Lock()
|
|
matchingAssets = append(matchingAssets, struct {
|
|
AssetName string
|
|
AssetSize int64
|
|
Asset *pb.AssetManifest
|
|
}{assetGroup.AssetName, assetGroup.AssetSize, asset})
|
|
mu.Unlock()
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
for _, ma := range matchingAssets {
|
|
err := firefly.LDiffFile(ma.Asset, ma.AssetName, ma.AssetSize, ldiffPath, gamePath)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
|
|
diffMapNames := make([]string, len(ldiffEntries))
|
|
for i, e := range ldiffEntries {
|
|
diffMapNames[i] = e.Name()
|
|
}
|
|
|
|
diffMapList, err := MakeDiffMap(manifest, diffMapNames)
|
|
if err != nil {
|
|
return false, err.Error()
|
|
}
|
|
application.Get().Event.Emit("diff:stage", map[string]string{"stage": "Patching HDiff"})
|
|
for i, entry := range diffMapList {
|
|
application.Get().Event.Emit(
|
|
"diff:progress", map[string]int{
|
|
"progress": i,
|
|
"maxProgress": len(diffMapList),
|
|
})
|
|
sourceFile := filepath.Join(gamePath, entry.SourceFileName)
|
|
patchFile := filepath.Join(gamePath, entry.PatchFileName)
|
|
targetFile := filepath.Join(gamePath, entry.TargetFileName)
|
|
|
|
if _, err := os.Stat(patchFile); os.IsNotExist(err) {
|
|
continue
|
|
}
|
|
|
|
if entry.SourceFileName == "" {
|
|
hpatchz.ApplyPatchEmpty(patchFile, targetFile)
|
|
os.Remove(patchFile)
|
|
continue
|
|
}
|
|
|
|
if _, err := os.Stat(sourceFile); os.IsNotExist(err) {
|
|
continue
|
|
}
|
|
|
|
hpatchz.ApplyPatch(sourceFile, patchFile, targetFile)
|
|
if entry.SourceFileName != entry.TargetFileName {
|
|
os.Remove(sourceFile)
|
|
}
|
|
os.Remove(patchFile)
|
|
}
|
|
|
|
}
|
|
}
|
|
os.RemoveAll(ldiffPath)
|
|
return true, "patching completed"
|
|
}
|
|
|
|
func MakeDiffMap(manifest *pb.ManifestProto, chunkNames []string) ([]*models.HDiffData, error) {
|
|
var hdiffFiles []*models.HDiffData
|
|
|
|
for _, asset := range manifest.Assets {
|
|
assetName := asset.AssetName
|
|
assetSize := asset.AssetSize
|
|
|
|
if asset.AssetData != nil {
|
|
for _, chunk := range asset.AssetData.Assets {
|
|
matched := false
|
|
for _, name := range chunkNames {
|
|
if name == chunk.ChunkFileName {
|
|
matched = true
|
|
break
|
|
}
|
|
}
|
|
if !matched {
|
|
continue
|
|
}
|
|
|
|
if chunk.OriginalFileSize != 0 || chunk.HdiffFileSize != assetSize {
|
|
hdiffFiles = append(hdiffFiles, &models.HDiffData{
|
|
SourceFileName: chunk.OriginalFilePath,
|
|
TargetFileName: assetName,
|
|
PatchFileName: fmt.Sprintf("%s.hdiff", assetName),
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return hdiffFiles, nil
|
|
}
|