diff --git a/config.example.yml b/config.example.yml index 76ef707..1e2f3a4 100644 --- a/config.example.yml +++ b/config.example.yml @@ -1,3 +1,36 @@ redis: uri: 127.0.0.1:6379 - database: 0 \ No newline at end of file + database: 0 +routes: + face: + default_scale: 4 + min_scale: 1 + max_scale: 64 + head: + default_scale: 4 + min_scale: 1 + max_scale: 64 + full_body: + default_scale: 4 + min_scale: 1 + max_scale: 64 + front_body: + default_scale: 4 + min_scale: 1 + max_scale: 64 + back_body: + default_scale: 4 + min_scale: 1 + max_scale: 64 + left_body: + default_scale: 4 + min_scale: 1 + max_scale: 64 + right_body: + default_scale: 4 + min_scale: 1 + max_scale: 64 +cache: + uuid_cache_duration: 2678400 # 1 week + skin_cache_duration: 86400 # 1 day + render_cache_duration: 86400 # 1 day \ No newline at end of file diff --git a/go.mod b/go.mod index e602a19..531e1f4 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module main +module github.com/mineatar-io/api-server go 1.17 @@ -15,6 +15,6 @@ require ( github.com/andybalholm/brotli v1.0.4 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/klauspost/compress v1.15.0 // indirect + github.com/klauspost/compress v1.15.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect ) diff --git a/go.sum b/go.sum index a64dfdd..4899398 100644 --- a/go.sum +++ b/go.sum @@ -33,6 +33,8 @@ github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U= github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= +github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= diff --git a/src/conf/config.go b/src/conf/config.go new file mode 100644 index 0000000..9c786d3 --- /dev/null +++ b/src/conf/config.go @@ -0,0 +1,66 @@ +package conf + +import ( + "io/ioutil" + + "gopkg.in/yaml.v2" +) + +type Configuration struct { + Redis struct { + URI string `yaml:"uri"` + Database int `yaml:"database"` + } `yaml:"redis"` + Routes struct { + Face struct { + DefaultScale int `yaml:"default_scale"` + MinScale int `yaml:"min_scale"` + MaxScale int `yaml:"max_scale"` + } `yaml:"face"` + Head struct { + DefaultScale int `yaml:"default_scale"` + MinScale int `yaml:"min_scale"` + MaxScale int `yaml:"max_scale"` + } `yaml:"head"` + FullBody struct { + DefaultScale int `yaml:"default_scale"` + MinScale int `yaml:"min_scale"` + MaxScale int `yaml:"max_scale"` + } `yaml:"full_body"` + FrontBody struct { + DefaultScale int `yaml:"default_scale"` + MinScale int `yaml:"min_scale"` + MaxScale int `yaml:"max_scale"` + } `yaml:"front_body"` + BackBody struct { + DefaultScale int `yaml:"default_scale"` + MinScale int `yaml:"min_scale"` + MaxScale int `yaml:"max_scale"` + } `yaml:"back_body"` + LeftBody struct { + DefaultScale int `yaml:"default_scale"` + MinScale int `yaml:"min_scale"` + MaxScale int `yaml:"max_scale"` + } `yaml:"left_body"` + RightBody struct { + DefaultScale int `yaml:"default_scale"` + MinScale int `yaml:"min_scale"` + MaxScale int `yaml:"max_scale"` + } `yaml:"right_body"` + } `yaml:"routes"` + Cache struct { + UUIDCacheDuration int64 `yaml:"uuid_cache_duration"` + SkinCacheDuration int64 `yaml:"skin_cache_duration"` + RenderCacheDuration int64 `yaml:"render_cache_duration"` + } `yaml:"cache"` +} + +func (c *Configuration) ReadFile(file string) error { + data, err := ioutil.ReadFile(file) + + if err != nil { + return err + } + + return yaml.Unmarshal(data, c) +} diff --git a/src/config.go b/src/config.go deleted file mode 100644 index 54e0076..0000000 --- a/src/config.go +++ /dev/null @@ -1,24 +0,0 @@ -package main - -import ( - "io/ioutil" - - "gopkg.in/yaml.v2" -) - -type Configuration struct { - Redis struct { - URI string `yaml:"uri"` - Database int `yaml:"database"` - } `yaml:"redis"` -} - -func (c *Configuration) ReadFile(file string) error { - data, err := ioutil.ReadFile(file) - - if err != nil { - return err - } - - return yaml.Unmarshal(data, c) -} diff --git a/src/main.go b/src/main.go index ddfc709..cf767ad 100644 --- a/src/main.go +++ b/src/main.go @@ -3,22 +3,24 @@ package main import ( "fmt" "log" - "main/src/redis" - "main/src/routes" "os" "strconv" "time" "github.com/buaazp/fasthttprouter" "github.com/joho/godotenv" + "github.com/mineatar-io/api-server/src/conf" + "github.com/mineatar-io/api-server/src/redis" + "github.com/mineatar-io/api-server/src/routes" + "github.com/mineatar-io/api-server/src/util" "github.com/valyala/fasthttp" ) var ( - host string = "127.0.0.1" - port uint16 = 3000 - config *Configuration = &Configuration{} - r *redis.Redis = &redis.Redis{} + host string = "127.0.0.1" + port uint16 = 3000 + config *conf.Configuration = &conf.Configuration{} + r *redis.Redis = &redis.Redis{} ) func init() { @@ -52,7 +54,8 @@ func init() { port = uint16(parsedValue) } - routes.InitRoutes(r) + routes.Init(r, config) + util.Init(r, config) } func main() { diff --git a/src/routes/body.go b/src/routes/body.go index 3b64202..6832cce 100644 --- a/src/routes/body.go +++ b/src/routes/body.go @@ -3,12 +3,11 @@ package routes import ( "fmt" "log" - "main/src/util" - "main/src/util/renders" - "math" "net/http" "time" + "github.com/mineatar-io/api-server/src/util" + "github.com/mineatar-io/api-server/src/util/renders" "github.com/valyala/fasthttp" ) @@ -20,10 +19,10 @@ func FullBodyHandler(ctx *fasthttp.RequestCtx) { scale, err := ctx.QueryArgs().GetUint("scale") if err != nil { - scale = 4 + scale = config.Routes.FullBody.DefaultScale } - scale = int(math.Max(math.Min(float64(scale), MaxScaleFullBody), MinScale)) + scale = util.Clamp(scale, config.Routes.FullBody.MinScale, config.Routes.FullBody.MaxScale) overlay := true @@ -31,7 +30,7 @@ func FullBodyHandler(ctx *fasthttp.RequestCtx) { overlay = ctx.QueryArgs().GetBool("overlay") } - uuid, err := util.GetUUID(r, user) + uuid, err := util.GetUUID(user) if err != nil { log.Println(err) @@ -67,7 +66,7 @@ func FullBodyHandler(ctx *fasthttp.RequestCtx) { return } - skin, slim, err := util.GetPlayerSkin(r, uuid) + skin, slim, err := util.GetPlayerSkin(uuid) if err != nil { log.Println(err) @@ -99,7 +98,7 @@ func FullBodyHandler(ctx *fasthttp.RequestCtx) { return } - if err = r.Set(cacheKey, data, time.Hour*24); err != nil { + if err = r.Set(cacheKey, data, time.Duration(config.Cache.RenderCacheDuration)*time.Second); err != nil { log.Println(err) ctx.SetStatusCode(http.StatusInternalServerError) @@ -125,10 +124,10 @@ func FrontBodyHandler(ctx *fasthttp.RequestCtx) { scale, err := ctx.QueryArgs().GetUint("scale") if err != nil { - scale = 4 + scale = config.Routes.FrontBody.DefaultScale } - scale = int(math.Max(math.Min(float64(scale), MaxScale), MinScale)) + scale = util.Clamp(scale, config.Routes.FrontBody.MinScale, config.Routes.FrontBody.MaxScale) overlay := true @@ -136,7 +135,7 @@ func FrontBodyHandler(ctx *fasthttp.RequestCtx) { overlay = ctx.QueryArgs().GetBool("overlay") } - uuid, err := util.GetUUID(r, user) + uuid, err := util.GetUUID(user) if err != nil { log.Println(err) @@ -172,7 +171,7 @@ func FrontBodyHandler(ctx *fasthttp.RequestCtx) { return } - skin, slim, err := util.GetPlayerSkin(r, uuid) + skin, slim, err := util.GetPlayerSkin(uuid) if err != nil { log.Println(err) @@ -204,7 +203,7 @@ func FrontBodyHandler(ctx *fasthttp.RequestCtx) { return } - if err = r.Set(cacheKey, data, time.Hour*24); err != nil { + if err = r.Set(cacheKey, data, time.Duration(config.Cache.RenderCacheDuration)*time.Second); err != nil { log.Println(err) ctx.SetStatusCode(http.StatusInternalServerError) @@ -230,10 +229,10 @@ func BackBodyHandler(ctx *fasthttp.RequestCtx) { scale, err := ctx.QueryArgs().GetUint("scale") if err != nil { - scale = 4 + scale = config.Routes.BackBody.DefaultScale } - scale = int(math.Max(math.Min(float64(scale), MaxScale), MinScale)) + scale = util.Clamp(scale, config.Routes.BackBody.MinScale, config.Routes.BackBody.MaxScale) overlay := true @@ -241,7 +240,7 @@ func BackBodyHandler(ctx *fasthttp.RequestCtx) { overlay = ctx.QueryArgs().GetBool("overlay") } - uuid, err := util.GetUUID(r, user) + uuid, err := util.GetUUID(user) if err != nil { log.Println(err) @@ -277,7 +276,7 @@ func BackBodyHandler(ctx *fasthttp.RequestCtx) { return } - skin, slim, err := util.GetPlayerSkin(r, uuid) + skin, slim, err := util.GetPlayerSkin(uuid) if err != nil { log.Println(err) @@ -309,7 +308,7 @@ func BackBodyHandler(ctx *fasthttp.RequestCtx) { return } - if err = r.Set(cacheKey, data, time.Hour*24); err != nil { + if err = r.Set(cacheKey, data, time.Duration(config.Cache.RenderCacheDuration)*time.Second); err != nil { log.Println(err) ctx.SetStatusCode(http.StatusInternalServerError) @@ -335,10 +334,10 @@ func LeftBodyHandler(ctx *fasthttp.RequestCtx) { scale, err := ctx.QueryArgs().GetUint("scale") if err != nil { - scale = 4 + scale = config.Routes.LeftBody.DefaultScale } - scale = int(math.Max(math.Min(float64(scale), MaxScale), MinScale)) + scale = util.Clamp(scale, config.Routes.LeftBody.MinScale, config.Routes.LeftBody.MaxScale) overlay := true @@ -346,7 +345,7 @@ func LeftBodyHandler(ctx *fasthttp.RequestCtx) { overlay = ctx.QueryArgs().GetBool("overlay") } - uuid, err := util.GetUUID(r, user) + uuid, err := util.GetUUID(user) if err != nil { log.Println(err) @@ -382,7 +381,7 @@ func LeftBodyHandler(ctx *fasthttp.RequestCtx) { return } - skin, slim, err := util.GetPlayerSkin(r, uuid) + skin, slim, err := util.GetPlayerSkin(uuid) if err != nil { log.Println(err) @@ -414,7 +413,7 @@ func LeftBodyHandler(ctx *fasthttp.RequestCtx) { return } - if err = r.Set(cacheKey, data, time.Hour*24); err != nil { + if err = r.Set(cacheKey, data, time.Duration(config.Cache.RenderCacheDuration)*time.Second); err != nil { log.Println(err) ctx.SetStatusCode(http.StatusInternalServerError) @@ -440,10 +439,10 @@ func RightBodyHandler(ctx *fasthttp.RequestCtx) { scale, err := ctx.QueryArgs().GetUint("scale") if err != nil { - scale = 4 + scale = config.Routes.RightBody.DefaultScale } - scale = int(math.Max(math.Min(float64(scale), MaxScale), MinScale)) + scale = util.Clamp(scale, config.Routes.RightBody.MinScale, config.Routes.RightBody.MaxScale) overlay := true @@ -451,7 +450,7 @@ func RightBodyHandler(ctx *fasthttp.RequestCtx) { overlay = ctx.QueryArgs().GetBool("overlay") } - uuid, err := util.GetUUID(r, user) + uuid, err := util.GetUUID(user) if err != nil { log.Println(err) @@ -487,7 +486,7 @@ func RightBodyHandler(ctx *fasthttp.RequestCtx) { return } - skin, slim, err := util.GetPlayerSkin(r, uuid) + skin, slim, err := util.GetPlayerSkin(uuid) if err != nil { log.Println(err) @@ -519,7 +518,7 @@ func RightBodyHandler(ctx *fasthttp.RequestCtx) { return } - if err = r.Set(cacheKey, data, time.Hour*24); err != nil { + if err = r.Set(cacheKey, data, time.Duration(config.Cache.RenderCacheDuration)*time.Second); err != nil { log.Println(err) ctx.SetStatusCode(http.StatusInternalServerError) diff --git a/src/routes/face.go b/src/routes/face.go index 91e5c2c..835a9fa 100644 --- a/src/routes/face.go +++ b/src/routes/face.go @@ -3,12 +3,11 @@ package routes import ( "fmt" "log" - "main/src/util" - "main/src/util/renders" - "math" "net/http" "time" + "github.com/mineatar-io/api-server/src/util" + "github.com/mineatar-io/api-server/src/util/renders" "github.com/valyala/fasthttp" ) @@ -20,10 +19,10 @@ func FaceHandler(ctx *fasthttp.RequestCtx) { scale, err := ctx.QueryArgs().GetUint("scale") if err != nil { - scale = 4 + scale = config.Routes.Face.DefaultScale } - scale = int(math.Max(math.Min(float64(scale), MaxScale), MinScale)) + scale = util.Clamp(scale, config.Routes.Face.MinScale, config.Routes.Face.MaxScale) overlay := true @@ -31,7 +30,7 @@ func FaceHandler(ctx *fasthttp.RequestCtx) { overlay = ctx.QueryArgs().GetBool("overlay") } - uuid, err := util.GetUUID(r, user) + uuid, err := util.GetUUID(user) if err != nil { log.Println(err) @@ -67,7 +66,7 @@ func FaceHandler(ctx *fasthttp.RequestCtx) { return } - skin, slim, err := util.GetPlayerSkin(r, uuid) + skin, slim, err := util.GetPlayerSkin(uuid) if err != nil { log.Println(err) @@ -99,7 +98,7 @@ func FaceHandler(ctx *fasthttp.RequestCtx) { return } - if err = r.Set(cacheKey, data, time.Hour*24); err != nil { + if err = r.Set(cacheKey, data, time.Duration(config.Cache.RenderCacheDuration)*time.Second); err != nil { log.Println(err) ctx.SetStatusCode(http.StatusInternalServerError) diff --git a/src/routes/head.go b/src/routes/head.go index 0e45c9b..fcf025f 100644 --- a/src/routes/head.go +++ b/src/routes/head.go @@ -3,12 +3,11 @@ package routes import ( "fmt" "log" - "main/src/util" - "main/src/util/renders" - "math" "net/http" "time" + "github.com/mineatar-io/api-server/src/util" + "github.com/mineatar-io/api-server/src/util/renders" "github.com/valyala/fasthttp" ) @@ -20,10 +19,10 @@ func HeadHandler(ctx *fasthttp.RequestCtx) { scale, err := ctx.QueryArgs().GetUint("scale") if err != nil { - scale = 4 + scale = config.Routes.Head.DefaultScale } - scale = int(math.Max(math.Min(float64(scale), MaxScale), MinScale)) + scale = util.Clamp(scale, config.Routes.Head.MinScale, config.Routes.Head.MaxScale) overlay := true @@ -31,7 +30,7 @@ func HeadHandler(ctx *fasthttp.RequestCtx) { overlay = ctx.QueryArgs().GetBool("overlay") } - uuid, err := util.GetUUID(r, user) + uuid, err := util.GetUUID(user) if err != nil { log.Println(err) @@ -67,7 +66,7 @@ func HeadHandler(ctx *fasthttp.RequestCtx) { return } - skin, slim, err := util.GetPlayerSkin(r, uuid) + skin, slim, err := util.GetPlayerSkin(uuid) if err != nil { log.Println(err) @@ -99,7 +98,7 @@ func HeadHandler(ctx *fasthttp.RequestCtx) { return } - if err = r.Set(cacheKey, data, time.Hour*24); err != nil { + if err = r.Set(cacheKey, data, time.Duration(config.Cache.RenderCacheDuration)*time.Second); err != nil { log.Println(err) ctx.SetStatusCode(http.StatusInternalServerError) diff --git a/src/routes/init.go b/src/routes/init.go index 2fdc300..5320951 100644 --- a/src/routes/init.go +++ b/src/routes/init.go @@ -1,17 +1,16 @@ package routes -import "main/src/redis" +import ( + "github.com/mineatar-io/api-server/src/conf" + "github.com/mineatar-io/api-server/src/redis" +) var ( - r *redis.Redis + r *redis.Redis + config *conf.Configuration ) -const ( - MaxScale float64 = 64.0 - MaxScaleFullBody float64 = 32.0 - MinScale float64 = 1.0 -) - -func InitRoutes(red *redis.Redis) { +func Init(red *redis.Redis, c *conf.Configuration) { r = red + config = c } diff --git a/src/routes/skin.go b/src/routes/skin.go index a66af04..35dbe73 100644 --- a/src/routes/skin.go +++ b/src/routes/skin.go @@ -3,9 +3,9 @@ package routes import ( "fmt" "log" - "main/src/util" "net/http" + "github.com/mineatar-io/api-server/src/util" "github.com/valyala/fasthttp" ) @@ -14,7 +14,7 @@ func SkinHandler(ctx *fasthttp.RequestCtx) { download := ctx.QueryArgs().GetBool("download") - uuid, err := util.GetUUID(r, user) + uuid, err := util.GetUUID(user) if err != nil { log.Println(err) @@ -25,7 +25,7 @@ func SkinHandler(ctx *fasthttp.RequestCtx) { return } - skin, slim, err := util.GetPlayerSkin(r, uuid) + skin, slim, err := util.GetPlayerSkin(uuid) if err != nil { log.Println(err) diff --git a/src/routes/uuid.go b/src/routes/uuid.go index fb77541..cca92be 100644 --- a/src/routes/uuid.go +++ b/src/routes/uuid.go @@ -2,16 +2,16 @@ package routes import ( "log" - "main/src/util" "net/http" + "github.com/mineatar-io/api-server/src/util" "github.com/valyala/fasthttp" ) func UUIDHandler(ctx *fasthttp.RequestCtx) { user := ctx.UserValue("user").(string) - uuid, err := util.GetUUID(r, user) + uuid, err := util.GetUUID(user) if err != nil { log.Println(err) diff --git a/src/util/init.go b/src/util/init.go index 033523b..3cdba6e 100644 --- a/src/util/init.go +++ b/src/util/init.go @@ -1,5 +1,19 @@ package util -import "os" +import ( + "os" -var Debug = os.Getenv("DEBUG") == "true" + "github.com/mineatar-io/api-server/src/conf" + "github.com/mineatar-io/api-server/src/redis" +) + +var ( + Debug = os.Getenv("DEBUG") == "true" + config *conf.Configuration + r *redis.Redis +) + +func Init(red *redis.Redis, c *conf.Configuration) { + r = red + config = c +} diff --git a/src/util/limit.go b/src/util/limit.go new file mode 100644 index 0000000..1ea575b --- /dev/null +++ b/src/util/limit.go @@ -0,0 +1,15 @@ +package util + +// This is used instead of `math.Min/Max` because of the +// unnecessary coercion from/to float64. +func Clamp(value, min, max int) int { + if value > max { + return max + } + + if value < min { + return min + } + + return value +} diff --git a/src/util/renders/util.go b/src/util/renders/util.go index aa69cac..03ce5fe 100644 --- a/src/util/renders/util.go +++ b/src/util/renders/util.go @@ -3,10 +3,9 @@ package renders import ( "image" "image/draw" - "main/src/util/renders/matrix" + "github.com/mineatar-io/api-server/src/util/renders/matrix" drw "golang.org/x/image/draw" - "golang.org/x/image/math/f64" ) diff --git a/src/util/uuid.go b/src/util/uuid.go index 2d235f5..c462609 100644 --- a/src/util/uuid.go +++ b/src/util/uuid.go @@ -3,11 +3,11 @@ package util import ( "fmt" "log" - "main/src/redis" "strings" + "time" ) -func GetUUID(r *redis.Redis, value string) (string, error) { +func GetUUID(value string) (string, error) { value = strings.ToLower(strings.ReplaceAll(value, "-", "")) if len(value) == 32 { @@ -38,7 +38,7 @@ func GetUUID(r *redis.Redis, value string) (string, error) { return "", nil } - if err = r.Set(fmt.Sprintf("uuid:%s", value), profile.ID, 0); err != nil { + if err = r.Set(fmt.Sprintf("uuid:%s", value), profile.ID, time.Duration(config.Cache.UUIDCacheDuration)*time.Second); err != nil { return "", err } diff --git a/src/util/yggdrasil.go b/src/util/yggdrasil.go index 349e6ac..03257de 100644 --- a/src/util/yggdrasil.go +++ b/src/util/yggdrasil.go @@ -9,7 +9,6 @@ import ( "image/draw" "io/ioutil" "log" - "main/src/redis" "net/http" "time" ) @@ -102,7 +101,7 @@ func GetPlayerProfile(uuid string) (*Profile, error) { return result, nil } -func GetPlayerSkin(r *redis.Redis, uuid string) (*image.NRGBA, bool, error) { +func GetPlayerSkin(uuid string) (*image.NRGBA, bool, error) { if len(uuid) < 1 { return GetDefaultSkin(false), false, nil } @@ -214,7 +213,7 @@ func GetPlayerSkin(r *redis.Redis, uuid string) (*image.NRGBA, bool, error) { } if slim { - if err = r.Set(fmt.Sprintf("slim:%s", uuid), "true", time.Hour*24); err != nil { + if err = r.Set(fmt.Sprintf("slim:%s", uuid), "true", time.Duration(config.Cache.SkinCacheDuration)*time.Second); err != nil { return nil, false, err } } else { @@ -223,7 +222,7 @@ func GetPlayerSkin(r *redis.Redis, uuid string) (*image.NRGBA, bool, error) { } } - if err = r.Set(fmt.Sprintf("skin:%s", uuid), body, time.Hour*24); err != nil { + if err = r.Set(fmt.Sprintf("skin:%s", uuid), body, time.Duration(config.Cache.SkinCacheDuration)*time.Second); err != nil { return nil, false, err }