init
This commit is contained in:
35
pkg/constant/constant.go
Normal file
35
pkg/constant/constant.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package constant
|
||||
|
||||
const ProxyGitUrl = "https://git.kain.io.vn/api/v1/repos/Firefly-Shelter/Firefly_Proxy/releases"
|
||||
const ServerGitUrl = "https://git.kain.io.vn/api/v1/repos/Firefly-Shelter/FireflyGo_Local_Archive/releases"
|
||||
const ServerStorageUrl = "./server"
|
||||
const ProxyStorageUrl = "./proxy"
|
||||
const ServerZipFile = "prebuild_win_x86.zip"
|
||||
const ProxyZipFile = "64bit.zip"
|
||||
const TempUrl = "./temp"
|
||||
|
||||
type ToolFile string
|
||||
|
||||
const (
|
||||
Tool7zaExe ToolFile = "bin/7za.exe"
|
||||
Tool7zaDLL ToolFile = "bin/7za.dll"
|
||||
Tool7zxaDLL ToolFile = "bin/7zxa.dll"
|
||||
ToolHPatchzExe ToolFile = "bin/hpatchz.exe"
|
||||
ToolHDiffzExe ToolFile = "bin/hdiffz.exe"
|
||||
)
|
||||
|
||||
var RequiredFiles = map[ToolFile]string{
|
||||
Tool7zaExe: "assets/7zip/7za.exe",
|
||||
Tool7zaDLL: "assets/7zip/7za.dll",
|
||||
Tool7zxaDLL: "assets/7zip/7zxa.dll",
|
||||
ToolHPatchzExe: "assets/HDiffPatch/hpatchz.exe",
|
||||
ToolHDiffzExe: "assets/HDiffPatch/hdiffz.exe",
|
||||
}
|
||||
|
||||
func (t ToolFile) GetEmbedPath() string {
|
||||
return RequiredFiles[t]
|
||||
}
|
||||
|
||||
func (t ToolFile) String() string {
|
||||
return string(t)
|
||||
}
|
||||
73
pkg/models/binary-version.go
Normal file
73
pkg/models/binary-version.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type BinaryVersion struct {
|
||||
Major int
|
||||
Minor int
|
||||
Patch int
|
||||
}
|
||||
|
||||
func ParseBinaryVersion(path string) (*BinaryVersion, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
content := string(data)
|
||||
|
||||
dashPos := strings.LastIndex(content, "-")
|
||||
if dashPos == -1 {
|
||||
return nil, errors.New("no dash found in version string")
|
||||
}
|
||||
|
||||
start := dashPos - 6
|
||||
if start < 0 {
|
||||
start = 0
|
||||
}
|
||||
|
||||
versionSlice := content[start:]
|
||||
end := strings.Index(versionSlice, "-")
|
||||
if end == -1 {
|
||||
end = len(versionSlice)
|
||||
}
|
||||
|
||||
versionStr := versionSlice[:end]
|
||||
parts := strings.SplitN(versionStr, ".", 3)
|
||||
if len(parts) != 3 {
|
||||
return nil, errors.New("invalid version format")
|
||||
}
|
||||
|
||||
major, err := strconv.Atoi(parts[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
minor, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
patch, err := strconv.Atoi(parts[2])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &BinaryVersion{major, minor, patch}, nil
|
||||
}
|
||||
|
||||
func (v *BinaryVersion) String() string {
|
||||
return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
|
||||
}
|
||||
|
||||
func (v BinaryVersion) ToInt() int {
|
||||
return v.Major*100 + v.Minor*10 + v.Patch
|
||||
}
|
||||
|
||||
func (v BinaryVersion) Subtract(other BinaryVersion) int {
|
||||
return v.ToInt() - other.ToInt()
|
||||
}
|
||||
15
pkg/models/hdiffmap.go
Normal file
15
pkg/models/hdiffmap.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package models
|
||||
|
||||
type DiffMapType struct {
|
||||
SourceFileName string `json:"source_file_name"`
|
||||
SourceFileMD5 string `json:"source_file_md5"`
|
||||
SourceFileSize int64 `json:"source_file_size"`
|
||||
|
||||
TargetFileName string `json:"target_file_name"`
|
||||
TargetFileMD5 string `json:"target_file_md5"`
|
||||
TargetFileSize int64 `json:"target_file_size"`
|
||||
|
||||
PatchFileName string `json:"patch_file_name"`
|
||||
PatchFileMD5 string `json:"patch_file_md5"`
|
||||
PatchFileSize int64 `json:"patch_file_size"`
|
||||
}
|
||||
56
pkg/models/release.go
Normal file
56
pkg/models/release.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package models
|
||||
|
||||
type ReleaseType struct {
|
||||
ID int `json:"id"`
|
||||
TagName string `json:"tag_name"`
|
||||
TargetCommitish string `json:"target_commitish"`
|
||||
Name string `json:"name"`
|
||||
Body string `json:"body"`
|
||||
URL string `json:"url"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
TarballURL string `json:"tarball_url"`
|
||||
ZipballURL string `json:"zipball_url"`
|
||||
UploadURL string `json:"upload_url"`
|
||||
Draft bool `json:"draft"`
|
||||
Prerelease bool `json:"prerelease"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
PublishedAt string `json:"published_at"`
|
||||
Author AuthorType `json:"author"`
|
||||
Assets []AssetType `json:"assets"`
|
||||
}
|
||||
|
||||
type AuthorType struct {
|
||||
ID int `json:"id"`
|
||||
Login string `json:"login"`
|
||||
LoginName string `json:"login_name"`
|
||||
SourceID int `json:"source_id"`
|
||||
FullName string `json:"full_name"`
|
||||
Email string `json:"email"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
Language string `json:"language"`
|
||||
IsAdmin bool `json:"is_admin"`
|
||||
LastLogin string `json:"last_login"`
|
||||
Created string `json:"created"`
|
||||
Restricted bool `json:"restricted"`
|
||||
Active bool `json:"active"`
|
||||
ProhibitLogin bool `json:"prohibit_login"`
|
||||
Location string `json:"location"`
|
||||
Website string `json:"website"`
|
||||
Description string `json:"description"`
|
||||
Visibility string `json:"visibility"`
|
||||
FollowersCount int `json:"followers_count"`
|
||||
FollowingCount int `json:"following_count"`
|
||||
StarredReposCount int `json:"starred_repos_count"`
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
type AssetType struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Size int `json:"size"`
|
||||
DownloadCount int `json:"download_count"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UUID string `json:"uuid"`
|
||||
BrowserDownloadURL string `json:"browser_download_url"`
|
||||
}
|
||||
44
pkg/sevenzip/sevenzip.go
Normal file
44
pkg/sevenzip/sevenzip.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package sevenzip
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"firefly-launcher/pkg/constant"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func IsFileIn7z(archivePath, fileInside string) (bool, error) {
|
||||
cmd := exec.Command(constant.Tool7zaExe.String(), "l", archivePath)
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
cmd.Stderr = &out
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return false, fmt.Errorf("7za list failed: %v\nOutput: %s", err, out.String())
|
||||
}
|
||||
|
||||
lines := strings.Split(out.String(), "\n")
|
||||
for _, line := range lines {
|
||||
if strings.Contains(line, fileInside) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, fmt.Errorf("%s not found in %s", fileInside, archivePath)
|
||||
}
|
||||
|
||||
func ExtractAFileFromZip(archivePath, fileInside, outDir string) error {
|
||||
cmd := exec.Command(constant.Tool7zaExe.String(), "e", archivePath, fileInside, "-o"+outDir, "-y")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func ExtractAllFilesFromZip(archivePath, outDir string) error {
|
||||
cmd := exec.Command(constant.Tool7zaExe.String(), "x", archivePath, "-o"+outDir, "-y")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
98
pkg/verifier/verifier.go
Normal file
98
pkg/verifier/verifier.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package verifier
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"firefly-launcher/pkg/models"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
)
|
||||
|
||||
type Verifier struct {
|
||||
GamePath string
|
||||
HdiffPath string
|
||||
DiffMapEntries []*models.DiffMapType
|
||||
}
|
||||
|
||||
func NewVerifier(gamePath, hdiffPath string) (*Verifier, error) {
|
||||
data, err := os.ReadFile(hdiffPath + "/hdiffmap.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var jsonData struct {
|
||||
DiffMap []*models.DiffMapType `json:"diff_map"`
|
||||
}
|
||||
if err := json.Unmarshal(data, &jsonData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Verifier{
|
||||
GamePath: gamePath,
|
||||
HdiffPath: hdiffPath,
|
||||
DiffMapEntries: jsonData.DiffMap,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (v *Verifier) VerifyAll() error {
|
||||
for i, entry := range v.DiffMapEntries {
|
||||
application.Get().EmitEvent(
|
||||
"hdiffz:progress", map[string]int{
|
||||
"progress": i,
|
||||
"maxProgress": len(v.DiffMapEntries),
|
||||
})
|
||||
if err := check(entry.SourceFileName, entry.SourceFileSize, entry.SourceFileMD5, v.GamePath); err != nil {
|
||||
return fmt.Errorf("source_file failed: %w", err)
|
||||
}
|
||||
// if err := check(entry.PatchFileName, entry.PatchFileSize, entry.PatchFileMD5, v.HdiffPath); err != nil {
|
||||
// return fmt.Errorf("patch_file failed: %w", err)
|
||||
// }
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func check(relPath string, expectedSize int64, expectedMD5, base string) error {
|
||||
fullPath := filepath.Join(base, relPath)
|
||||
|
||||
info, err := os.Stat(fullPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("file not found: %s", fullPath)
|
||||
}
|
||||
|
||||
if info.Size() != expectedSize {
|
||||
return fmt.Errorf("file size mismatch for %s: expected %d, got %d",
|
||||
fullPath, expectedSize, info.Size())
|
||||
}
|
||||
|
||||
md5Hash, err := fileMD5(fullPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading %s: %w", fullPath, err)
|
||||
}
|
||||
|
||||
if md5Hash != expectedMD5 {
|
||||
return fmt.Errorf("md5 mismatch for %s: expected %s, got %s",
|
||||
fullPath, expectedMD5, md5Hash)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func fileMD5(path string) (string, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
h := md5.New()
|
||||
if _, err := io.Copy(h, f); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return hex.EncodeToString(h.Sum(nil)), nil
|
||||
}
|
||||
Reference in New Issue
Block a user