first commit

This commit is contained in:
ALEX 2024-05-10 19:48:59 +00:00
commit 49003a8a80
12 changed files with 377 additions and 0 deletions

View File

@ -0,0 +1,5 @@
{
"Origin": "craserver.xfcloud.org:25565",
"America": "server4.xfcloud.org:25565",
"Common": "115.238.185.57:26000"
}

Binary file not shown.

View File

@ -0,0 +1,5 @@
{
"mods-version": "v1.0",
"mods-version-update": "mods-url",
"mods-url": "https://xfcloud.org/mods.zip"
}

3
api/servers.json Normal file
View File

@ -0,0 +1,3 @@
{
"IAts0Hp2MbUGw": "CRA-MC Server MTR"
}

233
cmd/root.go Normal file
View File

@ -0,0 +1,233 @@
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(&params)
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(&params)
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)
}
}

24
cmd/version.go Normal file
View File

@ -0,0 +1,24 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
func versionPrint() {
fmt.Println("CRAAPI static version: v0.2")
}
var versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version number of craapi",
Long: `All software has versions.`,
Run: func(cmd *cobra.Command, args []string) {
versionPrint()
},
}
func init() {
rootCmd.AddCommand(versionCmd)
}

BIN
craapi Executable file

Binary file not shown.

2
craapi.config Normal file
View File

@ -0,0 +1,2 @@
servername:
port: 19999

29
go.mod Normal file
View File

@ -0,0 +1,29 @@
module craapi
go 1.22.2
require (
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.18.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
honnef.co/go/tools v0.4.7 // indirect
)

61
go.sum Normal file
View File

@ -0,0 +1,61 @@
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.4.7 h1:9MDAWxMoSnB6QoSqiVr7P5mtkT9pOc1kSxchzPCnqJs=
honnef.co/go/tools v0.4.7/go.mod h1:+rnGS1THNh8zMwnd2oVOTL9QF6vmfyG6ZXBULae2uc0=

6
info.json Normal file
View File

@ -0,0 +1,6 @@
{
"launcher-version": "v0.0",
"launcher-version-update": "launcher-url",
"launcher-url": "",
"launcher-version-info": ""
}

9
main.go Normal file
View File

@ -0,0 +1,9 @@
package main
import (
"craapi/cmd"
)
func main() {
cmd.Execute()
}