package main import ( "flag" "log" "os" "os/exec" "path/filepath" "syscall" "unsafe" "vrc_osc_go/internal/buildinfo" "vrc_osc_go/internal/common" "vrc_osc_go/internal/update" ) func main() { 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) } base := runtimeBaseDir() exe := filepath.Join(base, "vrc_osc.exe") gui := filepath.Join(base, "vrc_osc_gui.exe") if _, err := os.Stat(exe); err != nil { showError("vrc_osc_launcher", "missing exe: "+err.Error()) log.Fatalf("missing exe: %v", err) } if _, err := os.Stat(gui); err == nil { _ = exec.Command(gui).Start() } args := append([]string{"--no-gui"}, os.Args[1:]...) if err := update.Launch(exe, args); err != nil { showError("vrc_osc_launcher", "launch failed: "+err.Error()) log.Fatalf("launch failed: %v", err) } } 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 }