package main import ( "encoding/json" "fmt" "os" "os/exec" "path/filepath" "strings" "sync" ) type PlecConfig struct { UploadUrl string `json:"uploadUrl"` OriginUrl string `json:"originUrl"` PreviewBase string `json:"previewBase"` SkipExistsCheck bool `json:"skipExistsCheck"` } type ApplovinConfig struct { Cookie string `json:"cookie"` } type SendToMobileConfig struct { Port int `json:"port"` } type DailyUpdateConfig struct { LastProject string `json:"lastProject"` } type AppConfig struct { Plec PlecConfig `json:"plec"` Applovin ApplovinConfig `json:"applovin"` SendToMobile SendToMobileConfig `json:"sendToMobile"` DailyUpdate DailyUpdateConfig `json:"dailyUpdate"` } var configMu sync.Mutex func defaultConfig() AppConfig { return AppConfig{ Plec: PlecConfig{ UploadUrl: "http://167.99.227.249/src/upload_HTML_Experimental.php", OriginUrl: "http://167.99.227.249", PreviewBase: "https://playable.applovindemo.com/phaser/", SkipExistsCheck: false, }, Applovin: ApplovinConfig{Cookie: ""}, SendToMobile: SendToMobileConfig{Port: 0}, DailyUpdate: DailyUpdateConfig{LastProject: ""}, } } func appDir() string { exe, err := os.Executable() if err != nil { wd, _ := os.Getwd() return wd } // `go run` puts the exe in a temp dir; fall back to cwd in that case. resolved, err := filepath.EvalSymlinks(exe) if err == nil { exe = resolved } dir := filepath.Dir(exe) if strings.Contains(strings.ToLower(dir), "go-build") { wd, _ := os.Getwd() return wd } return dir } func configPath() string { return filepath.Join(appDir(), "config.json") } func LoadConfig() AppConfig { configMu.Lock() defer configMu.Unlock() cfg := defaultConfig() data, err := os.ReadFile(configPath()) if err != nil { return cfg } _ = json.Unmarshal(data, &cfg) return cfg } func SaveConfig(cfg AppConfig) error { configMu.Lock() defer configMu.Unlock() data, err := json.MarshalIndent(cfg, "", " ") if err != nil { return err } return os.WriteFile(configPath(), data, 0644) } func OpenInBrowser(url string) { // `start` is a cmd builtin. Quoted empty arg is the window title. cmd := exec.Command("cmd", "/c", "start", "", url) _ = cmd.Start() } func CopyToClipboard(text string) error { cmd := exec.Command("clip") cmd.Stdin = strings.NewReader(text) return cmd.Run() } type FileFilter struct { Name string Extensions []string } func psEscape(s string) string { return strings.ReplaceAll(s, "'", "''") } func PickFiles(title string, filters []FileFilter, multi bool, initialDir string) []string { filterStr := "All files|*.*" if len(filters) > 0 { parts := make([]string, 0, len(filters)) for _, f := range filters { exts := make([]string, 0, len(f.Extensions)) for _, e := range f.Extensions { exts = append(exts, "*."+e) } parts = append(parts, fmt.Sprintf("%s|%s", f.Name, strings.Join(exts, ";"))) } filterStr = strings.Join(parts, "|") } multiStr := "false" if multi { multiStr = "true" } script := fmt.Sprintf(` Add-Type -AssemblyName System.Windows.Forms $dlg = New-Object System.Windows.Forms.OpenFileDialog $dlg.Title = '%s' $dlg.Filter = '%s' $dlg.Multiselect = $%s if ('%s'.Length -gt 0) { $dlg.InitialDirectory = '%s' } if ($dlg.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { $dlg.FileNames | ForEach-Object { Write-Output $_ } } `, psEscape(title), psEscape(filterStr), multiStr, psEscape(initialDir), psEscape(initialDir)) out, err := exec.Command("powershell", "-NoProfile", "-NonInteractive", "-STA", "-Command", script).Output() if err != nil { return nil } lines := strings.Split(string(out), "\n") result := make([]string, 0, len(lines)) for _, l := range lines { t := strings.TrimSpace(l) if t != "" { result = append(result, t) } } return result } func PickFolder(title, initialDir string) string { script := fmt.Sprintf(` Add-Type -AssemblyName System.Windows.Forms $dlg = New-Object System.Windows.Forms.FolderBrowserDialog $dlg.Description = '%s' if ('%s'.Length -gt 0) { $dlg.SelectedPath = '%s' } if ($dlg.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { Write-Output $dlg.SelectedPath } `, psEscape(title), psEscape(initialDir), psEscape(initialDir)) out, err := exec.Command("powershell", "-NoProfile", "-NonInteractive", "-STA", "-Command", script).Output() if err != nil { return "" } return strings.TrimSpace(string(out)) }