package main import ( "crypto/rand" "embed" "encoding/base64" "flag" "fmt" "io/fs" "log" "net" "net/http" "os" "os/exec" "runtime" "time" ) //go:embed web/* var embeddedWeb embed.FS var version = "dev" func main() { noOpen := flag.Bool("no-open", false, "do not open the browser automatically") showVersion := flag.Bool("version", false, "print version and exit") flag.Parse() if *showVersion { fmt.Println(version) return } listener, err := net.Listen("tcp4", "127.0.0.1:0") if err != nil { log.Fatal(err) } token, err := randomToken() if err != nil { log.Fatal(err) } webFS, err := fs.Sub(embeddedWeb, "web") if err != nil { log.Fatal(err) } baseURL := "http://" + listener.Addr().String() app := newApp(baseURL, token, webFS, newQQClient()) server := &http.Server{ Handler: app.routes(), ReadHeaderTimeout: 5 * time.Second, ReadTimeout: 15 * time.Second, WriteTimeout: 30 * time.Second, IdleTimeout: 60 * time.Second, MaxHeaderBytes: 16 * 1024, } launchURL := baseURL + "/start?t=" + token fmt.Printf("LRC Local %s\n仅监听本机:%s\n关闭此窗口即可停止。\n", version, baseURL) if !*noOpen { go func() { time.Sleep(150 * time.Millisecond) if err := openBrowser(launchURL); err != nil { log.Printf("无法自动打开浏览器,请手动访问:%s", launchURL) } }() } else { fmt.Printf("请访问:%s\n", launchURL) } if err := server.Serve(listener); err != nil && err != http.ErrServerClosed { log.Fatal(err) } } func randomToken() (string, error) { buf := make([]byte, 32) if _, err := rand.Read(buf); err != nil { return "", err } return base64.RawURLEncoding.EncodeToString(buf), nil } func openBrowser(url string) error { var command *exec.Cmd switch runtime.GOOS { case "windows": command = exec.Command("rundll32", "url.dll,FileProtocolHandler", url) case "darwin": command = exec.Command("open", url) default: command = exec.Command("xdg-open", url) } command.Stdout = os.Stdout command.Stderr = os.Stderr return command.Start() }