package main import ( "flag" "log" "os" "os/exec" "path/filepath" "strings" "syscall" "unsafe" "vrc_osc_go/internal/app" "vrc_osc_go/internal/buildinfo" "vrc_osc_go/internal/common" "vrc_osc_go/internal/update" ) func main() { _ = appendLauncherLog("LAUNCHER", "launcher main begin") var baseURL string var ownerRepo string var assetName string flag.StringVar(&baseURL, "base-url", "https://git.vrcworldtour.com", "Gitea base URL") flag.StringVar(&ownerRepo, "repo", "every_holiday/VRCWT-OSC", "owner/repo") flag.StringVar(&assetName, "asset", "vrc_osc-windows.zip", "release asset name") flag.Parse() client := &update.Client{BaseURL: baseURL} mgr := &update.Manager{ Client: client, OwnerRepo: ownerRepo, AssetName: assetName, CurrentLabel: buildinfo.Version, } if _, err := mgr.CheckAndUpdate(); err != nil { log.Printf("auto update skipped: %v", err) _ = appendLauncherLog("LAUNCHER", "auto update skipped: "+err.Error()) } else { _ = appendLauncherLog("LAUNCHER", "auto update ok") } base := runtimeBaseDir() exe := filepath.Join(base, "vrc_osc.exe") gui := filepath.Join(base, "vrc_osc_gui.exe") _ = appendLauncherLog("LAUNCHER", "runtimeBaseDir="+base) if _, err := os.Stat(exe); err != nil { _ = appendLauncherLog("LAUNCHER", "missing runtime exe: "+err.Error()) showError("vrc_osc_launcher", "missing exe: "+err.Error()) log.Fatalf("missing exe: %v", err) } _ = appendLauncherLog("LAUNCHER", "version="+buildinfo.Version+" build="+buildinfo.BuildTime+" base="+base+" exe="+exe+" gui="+gui) if _, err := os.Stat(gui); err == nil { _ = appendLauncherLog("LAUNCHER", "starting gui companion") _ = exec.Command(gui).Start() } else { _ = appendLauncherLog("LAUNCHER", "gui companion missing: "+err.Error()) } args := append([]string{"--no-gui"}, os.Args[1:]...) _ = appendLauncherLog("LAUNCHER", "launching runtime args="+strings.Join(args, " ")) if err := update.Launch(exe, args); err != nil { _ = appendLauncherLog("LAUNCHER", "launch failed: "+err.Error()) showError("vrc_osc_launcher", "launch failed: "+err.Error()) log.Fatalf("launch failed: %v", err) } _ = appendLauncherLog("LAUNCHER", "runtime launch returned") } func showError(title, message string) { user32 := syscall.NewLazyDLL("user32.dll") msgBox := user32.NewProc("MessageBoxW") const mbOK = 0x00000000 const mbIconError = 0x00000010 _, _, _ = msgBox.Call( 0, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(message))), uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(title))), uintptr(mbOK|mbIconError), ) } func runtimeBaseDir() string { root := common.RootDir() if _, err := os.Stat(filepath.Join(root, "vrc_osc.exe")); err == nil { return root } if _, err := os.Stat(filepath.Join(root, "tmp", "vrc_osc.exe")); err == nil { return filepath.Join(root, "tmp") } return root } func appendLauncherLog(title, text string) error { return app.AppendRuntimeLog(title, text) }