package cmd import ( "encoding/json" "fmt" "net/http" "os" "github.com/spf13/cobra" "github.com/spf13/viper" ) func IsExist(f string) bool { _, err := os.Stat(f) return err == nil || os.IsExist(err) } func apirequest_post(w http.ResponseWriter, req *http.Request) { var serverID = req.PathValue("id") if !IsExist("./" + serverID) { w.WriteHeader(403) fmt.Printf("Requesting ServerID: %s does not exist\n", serverID) return } file, err := os.Open("./" + serverID + "/server.json") if err != nil { w.WriteHeader(403) fmt.Printf("Requesting ServerID: %s file does not exist\n", serverID) return } defer file.Close() file_decoder := json.NewDecoder(file) var configs map[string]string file_decoder.Decode(&configs) decoder := json.NewDecoder(req.Body) var params map[string]string var resp string decoder.Decode(¶ms) for key, one := range params { // fmt.Printf("%s key's value %s\n", key, one) if value, ok := configs[key]; ok { if value != one { if addr, ok := configs[key+"-update"]; ok { if resp != "" { resp += "," } resp += "{\"" + key + "\":\"" + value + "\",\"" + addr + "\":\"" + configs[addr] + "\"}" } else { w.WriteHeader(500) fmt.Printf("%s key update not found\n", key) return } } else { // fmt.Printf("%s's request %s equals %s\n", key, one, value) } } else { w.WriteHeader(404) fmt.Printf("Requesting ServerID: %s, key:%s not found\n", serverID, key) return } } w.Write([]byte(resp)) } func apirequest_get(w http.ResponseWriter, req *http.Request) { var serverID = req.PathValue("id") if !IsExist("./" + serverID) { w.WriteHeader(403) fmt.Printf("Requesting ServerID: %s does not exist\n", serverID) return } var fileid = req.PathValue("file") file, err := os.ReadFile("./" + serverID + "/data/" + fileid + ".json") fmt.Printf("requesting %s\n", "./"+serverID+"/data/"+fileid+".json") if err != nil { w.WriteHeader(403) fmt.Printf("Requesting ServerID: %s file %s does not exist\n", serverID, "./"+serverID+"/data/"+fileid+".json") return } w.WriteHeader(http.StatusOK) w.Write(file) } func apirequest_file(w http.ResponseWriter, req *http.Request) { var serverID = req.PathValue("id") if !IsExist("./" + serverID) { w.WriteHeader(403) fmt.Printf("Requesting ServerID: %s does not exist\n", serverID) return } var fileid = req.PathValue("file") file, err := os.ReadFile("./" + serverID + "/files/" + fileid) fmt.Printf("requesting %s\n", "./"+serverID+"/files/"+fileid) if err != nil { w.WriteHeader(403) fmt.Printf("Requesting ServerID: %s file %s does not exist\n", serverID, "./"+serverID+"/files/"+fileid) return } w.WriteHeader(http.StatusOK) w.Write(file) } func apirequest_info_post(w http.ResponseWriter, req *http.Request) { file, err := os.Open("./info.json") if err != nil { w.WriteHeader(403) fmt.Println("Requesting info.json file does not exist") return } defer file.Close() file_decoder := json.NewDecoder(file) var configs map[string]string file_decoder.Decode(&configs) decoder := json.NewDecoder(req.Body) var params map[string]string var resp string decoder.Decode(¶ms) for key, one := range params { // fmt.Printf("%s key's value %s\n", key, one) if value, ok := configs[key]; ok { if value != one { if addr, ok := configs[key+"-update"]; ok { if new_info, ok := configs[key+"-info"]; ok { if resp != "" { resp += "," } resp += "{\"" + key + "\":\"" + value + "\",\"" + addr + "\":\"" + configs[addr] + "\",\"" + key + "-info\":\"" + new_info + "\"}" } else { w.WriteHeader(500) fmt.Printf("info's %s key update not found\n", key) return } } else { w.WriteHeader(500) fmt.Printf("info's %s key update not found\n", key) return } } else { // fmt.Printf("%s's request %s equals %s\n", key, one, value) } } else { w.WriteHeader(404) fmt.Printf("Requesting info key:%s not found\n", key) return } } w.Write([]byte(resp)) } var cfgFile string var v bool var servername string var port string func apirequest_info_get(w http.ResponseWriter, req *http.Request) { var fileid = req.PathValue("request") file, err := os.ReadFile("./api" + fileid + ".json") fmt.Printf("requesting %s\n", "./api"+fileid+".json") if err != nil { w.WriteHeader(403) fmt.Printf("Requesting file %s does not exist\n", "./api"+fileid+".json") return } w.WriteHeader(http.StatusOK) w.Write(file) } func runServer() { if v { versionPrint() os.Exit(0) } fmt.Println("config file:" + cfgFile) if cfgFile != "" { viper.SetConfigFile(cfgFile) viper.SetConfigType("yaml") } else { viper.SetConfigFile("./craapi.config") viper.SetConfigType("yaml") } if err := viper.ReadInConfig(); err != nil { fmt.Println("Can't read config:", err) os.Exit(1) } http.HandleFunc("POST /api/server/{id}", apirequest_post) http.HandleFunc("GET /api/server/{id}/{file}", apirequest_get) http.HandleFunc("/api/file/{id}/{file}", apirequest_file) http.HandleFunc("GET /api/info/{request}", apirequest_info_get) http.HandleFunc("POST /api/info", apirequest_info_post) fmt.Println("API Server is tring to run at:", viper.GetString("servername")+":"+viper.GetString("port")) err := http.ListenAndServe(viper.GetString("servername")+":"+viper.GetString("port"), nil) if err != nil { fmt.Println("HTTP SERVER failed,err:", err) return } fmt.Println("API server started successfully") } var rootCmd = &cobra.Command{ Use: "craapi", Short: "CRA-MC API is a minecraft servers API", Long: `CRA-MC API is a minecraft servers API which can manage mutiple minecraft servers' mods version or files `, Run: func(cmd *cobra.Command, args []string) { runServer() }, } func init() { cobra.OnInitialize(initConfig) rootCmd.Flags().StringVarP(&cfgFile, "config", "c", "./craapi.config", "config file") rootCmd.Flags().StringVarP(&servername, "servername", "s", "", "servername (domain or ip address)") rootCmd.Flags().StringVarP(&port, "port", "p", "", "port number") viper.BindPFlag("servername", rootCmd.Flags().Lookup("servername")) viper.BindPFlag("port", rootCmd.Flags().Lookup("port")) rootCmd.Flags().BoolVarP(&v, "version", "v", false, "version") viper.SetDefault("servername", "") viper.SetDefault("port", "19999") } func initConfig() { } func Execute() { if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) } }