112 lines
3.0 KiB
Go
112 lines
3.0 KiB
Go
package minecraft
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"zlh-agent/internal/provcommon"
|
|
"zlh-agent/internal/state"
|
|
)
|
|
|
|
/* --------------------------------------------------------------------------
|
|
Helper: patch any script/arg files that call plain "java "
|
|
----------------------------------------------------------------------------*/
|
|
func patchForgeJavaCalls(dir string) error {
|
|
entries, err := os.ReadDir(dir)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, e := range entries {
|
|
if e.IsDir() {
|
|
continue
|
|
}
|
|
|
|
name := e.Name()
|
|
if !strings.HasSuffix(name, ".sh") &&
|
|
!strings.HasSuffix(name, ".txt") &&
|
|
!strings.HasSuffix(name, ".args") {
|
|
continue
|
|
}
|
|
|
|
path := filepath.Join(dir, name)
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
continue // best-effort
|
|
}
|
|
|
|
content := string(data)
|
|
patched := strings.ReplaceAll(content, "java ", "/opt/zlh/runtime/java ")
|
|
if patched != content {
|
|
fmt.Println("[forge] patching java call in", name)
|
|
if err := os.WriteFile(path, []byte(patched), 0o755); err != nil {
|
|
return fmt.Errorf("write patched %s: %w", name, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------
|
|
InstallMinecraftForge
|
|
- Uses cfg.ArtifactPath as the Forge installer path (relative or absolute URL)
|
|
- Installs into /opt/zlh/minecraft/forge/world
|
|
----------------------------------------------------------------------------*/
|
|
func InstallMinecraftForge(cfg state.Config) error {
|
|
dir := provcommon.ServerDir(cfg)
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
|
return fmt.Errorf("mkdir server dir: %w", err)
|
|
}
|
|
|
|
if cfg.ArtifactPath == "" {
|
|
return fmt.Errorf("artifact_path missing for forge install")
|
|
}
|
|
|
|
url := provcommon.BuildArtifactURL(cfg.ArtifactPath)
|
|
|
|
installerPath := filepath.Join(dir, "forge-installer.jar")
|
|
|
|
// Download Forge installer into server dir
|
|
cmdDl := exec.Command("bash", "-c",
|
|
fmt.Sprintf("cd %s && curl -fLo %s %q", dir, "forge-installer.jar", url),
|
|
)
|
|
cmdDl.Stdout = os.Stdout
|
|
cmdDl.Stderr = os.Stderr
|
|
|
|
fmt.Println("[forge] downloading installer from:", url)
|
|
if err := cmdDl.Run(); err != nil {
|
|
return fmt.Errorf("forge installer download failed: %w", err)
|
|
}
|
|
|
|
javaBin := filepath.Join(provcommon.JavaRoot, "java")
|
|
|
|
// Run Forge installer
|
|
cmd := exec.Command("/bin/bash", "-c",
|
|
fmt.Sprintf("cd %s && %s -jar %s --installServer", dir, javaBin, installerPath),
|
|
)
|
|
|
|
// Ensure PATH contains our java for any nested calls
|
|
cmd.Env = append(os.Environ(),
|
|
"PATH=/opt/zlh/runtime:/opt/zlh/runtime/java:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
|
)
|
|
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
|
|
fmt.Println("[forge] running installer in", dir)
|
|
if err := cmd.Run(); err != nil {
|
|
return fmt.Errorf("forge installer failed: %w", err)
|
|
}
|
|
|
|
// Patch scripts/args to use /opt/zlh/runtime/java instead of plain "java"
|
|
if err := patchForgeJavaCalls(dir); err != nil {
|
|
return fmt.Errorf("patch java calls: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|