diff --git a/Makefile b/Makefile index 2aa50e2..c9d6b27 100644 --- a/Makefile +++ b/Makefile @@ -13,4 +13,4 @@ run: flush-cache: go run src/*.go --flush-cache -all: build \ No newline at end of file +build: build \ No newline at end of file diff --git a/README.md b/README.md index 7a79270..8e86411 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ The REST server that powers the API for mcstatus.io. This repository is open sou - `go get ...` 4. Build the executable - Using GNU make - - `make build` + - `make` - Without GNU make - `go build -o .\bin\main.exe .\src\*.go` (Windows) - `go build -o bin/main src/*.go` (Unix) diff --git a/config.example.yml b/config.example.yml index cabf2d0..2679170 100644 --- a/config.example.yml +++ b/config.example.yml @@ -1,12 +1,8 @@ environment: production host: 127.0.0.1 port: 3001 -redis: - host: 127.0.0.1 - port: 6379 - # username: myuser - # password: mypassword - database: 0 - java_cache_duration: 1m - bedrock_cache_duration: 1m - icon_cache_duration: 15m \ No newline at end of file +redis: redis://username:password@127.0.0.1:6379/0 +cache: + java_status_duration: 1m + bedrock_status_duration: 1m + icon_duration: 15m \ No newline at end of file diff --git a/go.mod b/go.mod index 86fbd2f..ff2f146 100644 --- a/go.mod +++ b/go.mod @@ -4,22 +4,27 @@ go 1.19 require ( github.com/go-redis/redis/v8 v8.11.5 - github.com/gofiber/fiber/v2 v2.40.1 - github.com/mcstatus-io/mcutil v0.0.0-20221217202354-00c1b98e931c + github.com/gofiber/fiber/v2 v2.42.0 + github.com/mcstatus-io/mcutil v0.0.0-20230226191507-0c73abf4a4d2 gopkg.in/yaml.v3 v3.0.1 ) require ( - github.com/andybalholm/brotli v1.0.4 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/andybalholm/brotli v1.0.5 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/klauspost/compress v1.15.9 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/klauspost/compress v1.16.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect - github.com/rivo/uniseg v0.2.0 // indirect + github.com/philhofer/fwd v1.1.1 // indirect + github.com/rivo/uniseg v0.4.4 // indirect + github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 // indirect + github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d // indirect + github.com/tinylib/msgp v1.1.6 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.41.0 // indirect + github.com/valyala/fasthttp v1.44.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect - golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect + golang.org/x/sys v0.5.0 // indirect ) diff --git a/go.sum b/go.sum index 1874fa2..dedfacb 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,11 @@ github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= +github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= @@ -9,43 +13,85 @@ github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/gofiber/fiber/v2 v2.40.1 h1:pc7n9VVpGIqNsvg9IPLQhyFEMJL8gCs1kneH5D1pIl4= github.com/gofiber/fiber/v2 v2.40.1/go.mod h1:Gko04sLksnHbzLSRBFWPFdzM9Ws9pRxvvIaohJK1dsk= +github.com/gofiber/fiber/v2 v2.42.0 h1:Fnp7ybWvS+sjNQsFvkhf4G8OhXswvB6Vee8hM/LyS+8= +github.com/gofiber/fiber/v2 v2.42.0/go.mod h1:3+SGNjqMh5VQH5Vz2Wdi43zTIV16ktlFd3x3R6O1Zlc= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mcstatus-io/mcutil v0.0.0-20221217202354-00c1b98e931c h1:rsklIGzjSrY+V3WEEx8Mc6R9bQ1/v26tMr/fgoKo3tM= -github.com/mcstatus-io/mcutil v0.0.0-20221217202354-00c1b98e931c/go.mod h1:VUB87/x9EYITmQVXZO4eS+egaZOdvxId4IdpU4L5LoA= +github.com/mcstatus-io/mcutil v0.0.0-20230226191507-0c73abf4a4d2 h1:zR0nGnTWJe/SqA+SvMVtLqu+9Owlq3oUEpAQn8lcMCY= +github.com/mcstatus-io/mcutil v0.0.0-20230226191507-0c73abf4a4d2/go.mod h1:VUB87/x9EYITmQVXZO4eS+egaZOdvxId4IdpU4L5LoA= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= +github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 h1:rmMl4fXJhKMNWl+K+r/fq4FbbKI+Ia2m9hYBLm2h4G4= +github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94/go.mod h1:90zrgN3D/WJsDd1iXHT96alCoN2KJo6/4x1DZC3wZs8= +github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d h1:Q+gqLBOPkFGHyCJxXMRqtUgUbTjI8/Ze8vu8GGyNFwo= +github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d/go.mod h1:Gy+0tqhJvgGlqnTF8CVGP0AaGRjwBtXs/a5PA0Y3+A4= +github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw= +github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.41.0 h1:zeR0Z1my1wDHTRiamBCXVglQdbUwgb9uWG3k1HQz6jY= github.com/valyala/fasthttp v1.41.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY= +github.com/valyala/fasthttp v1.44.0 h1:R+gLUhldIsfg1HokMuQjdQ5bh9nuXHPIfvkYUu9eR5Q= +github.com/valyala/fasthttp v1.44.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220906165146-f3363e06e74c h1:yKufUcDwucU5urd+50/Opbt4AYpqthk7wHpHok8f1lo= golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/src/blocked.go b/src/blocked.go deleted file mode 100644 index 897a166..0000000 --- a/src/blocked.go +++ /dev/null @@ -1,48 +0,0 @@ -package main - -import ( - "fmt" - "io" - "log" - "net/http" - "strings" - "time" -) - -func StartBlockedServersGoroutine() { - for { - if err := GetBlockedServerList(); err != nil { - log.Println(err) - } - - time.Sleep(time.Hour) - } -} - -func GetBlockedServerList() error { - resp, err := http.Get("https://sessionserver.mojang.com/blockedservers") - - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("unexpected status code: %d", resp.StatusCode) - } - - defer resp.Body.Close() - - body, err := io.ReadAll(resp.Body) - - if err != nil { - return err - } - - for _, hash := range strings.Split(string(body), "\n") { - if err = r.Set(fmt.Sprintf("blocked:%s", hash), "true", time.Hour*24); err != nil { - return err - } - } - - return nil -} diff --git a/src/config.go b/src/config.go index a2d7cb6..2f51155 100644 --- a/src/config.go +++ b/src/config.go @@ -8,19 +8,15 @@ import ( ) type Config struct { - Environment string `yaml:"environment"` - Host string `yaml:"host"` - Port uint16 `yaml:"port"` - Redis struct { - Host string `yaml:"host"` - Port uint16 `yaml:"port"` - Username string `yaml:"username"` - Password string `yaml:"password"` - Database int `yaml:"database"` - JavaCacheDuration time.Duration `yaml:"java_cache_duration"` - BedrockCacheDuration time.Duration `yaml:"bedrock_cache_duration"` - IconCacheDuration time.Duration `yaml:"icon_cache_duration"` - } `yaml:"redis"` + Environment string `yaml:"environment"` + Host string `yaml:"host"` + Port uint16 `yaml:"port"` + Redis *string `yaml:"redis"` + Cache struct { + JavaStatusDuration time.Duration `yaml:"java_status_duration"` + BedrockStatusDuration time.Duration `yaml:"bedrock_status_duration"` + IconDuration time.Duration `yaml:"icon_duration"` + } `yaml:"cache"` } func (c *Config) ReadFile(file string) error { diff --git a/src/main.go b/src/main.go index 8d2a10e..69672a4 100644 --- a/src/main.go +++ b/src/main.go @@ -29,11 +29,19 @@ func init() { log.Fatal(err) } - if err := r.Connect(); err != nil { + if err := GetBlockedServerList(); err != nil { log.Fatal(err) } - log.Println("Successfully connected to Redis") + log.Println("Successfully retrieved EULA blocked servers") + + if config.Redis != nil { + if err := r.Connect(); err != nil { + log.Fatal(err) + } + + log.Println("Successfully connected to Redis") + } app.Use(recover.New()) @@ -41,11 +49,11 @@ func init() { app.Use(cors.New(cors.Config{ AllowOrigins: "*", AllowMethods: "HEAD,OPTIONS,GET", - ExposeHeaders: "Content-Type,X-Cache-Time-Remaining", + ExposeHeaders: "X-Cache-Time-Remaining", })) app.Use(logger.New(logger.Config{ - Format: "${time} ${ip}:${port} -> ${method} ${path} -> ${status}\n", + Format: "${time} ${ip}:${port} -> ${status}: ${method} ${path} (${latency})\n", TimeFormat: "2006/01/02 15:04:05", })) } @@ -54,8 +62,6 @@ func init() { func main() { defer r.Close() - go StartBlockedServersGoroutine() - log.Printf("Listening on %s:%d\n", config.Host, config.Port) log.Fatal(app.Listen(fmt.Sprintf("%s:%d", config.Host, config.Port))) } diff --git a/src/redis.go b/src/redis.go index 1fdd66e..fc12d08 100644 --- a/src/redis.go +++ b/src/redis.go @@ -2,7 +2,6 @@ package main import ( "context" - "fmt" "time" "github.com/go-redis/redis/v8" @@ -13,12 +12,13 @@ type Redis struct { } func (r *Redis) Connect() error { - r.Client = redis.NewClient(&redis.Options{ - Addr: fmt.Sprintf("%s:%d", config.Redis.Host, config.Redis.Port), - Username: config.Redis.Username, - Password: config.Redis.Password, - DB: config.Redis.Database, - }) + opts, err := redis.ParseURL(*config.Redis) + + if err != nil { + return err + } + + r.Client = redis.NewClient(opts) ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) diff --git a/src/status.go b/src/status.go index 9052455..28d6d28 100644 --- a/src/status.go +++ b/src/status.go @@ -126,7 +126,7 @@ func GetJavaStatus(host string, port uint16) (*JavaStatusResponse, *time.Duratio return nil, nil, err } - if err := r.Set(cacheKey, data, config.Redis.JavaCacheDuration); err != nil { + if err := r.Set(cacheKey, data, config.Cache.JavaStatusDuration); err != nil { return nil, nil, err } @@ -172,7 +172,7 @@ func GetBedrockStatus(host string, port uint16) (*BedrockStatusResponse, *time.D return nil, nil, err } - if err := r.Set(cacheKey, data, config.Redis.BedrockCacheDuration); err != nil { + if err := r.Set(cacheKey, data, config.Cache.BedrockStatusDuration); err != nil { return nil, nil, err } @@ -214,7 +214,7 @@ func GetServerIcon(host string, port uint16) ([]byte, *time.Duration, error) { icon = data } - if err := r.Set(cacheKey, icon, config.Redis.IconCacheDuration); err != nil { + if err := r.Set(cacheKey, icon, config.Cache.IconDuration); err != nil { return nil, nil, err } @@ -222,12 +222,6 @@ func GetServerIcon(host string, port uint16) ([]byte, *time.Duration, error) { } func FetchJavaStatus(host string, port uint16) (*JavaStatusResponse, error) { - isEULABlocked, err := IsBlockedAddress(host) - - if err != nil { - return nil, err - } - status, err := mcutil.Status(host, port) if err != nil { @@ -239,9 +233,9 @@ func FetchJavaStatus(host string, port uint16) (*JavaStatusResponse, error) { Online: false, Host: host, Port: port, - EULABlocked: isEULABlocked, + EULABlocked: IsBlockedAddress(host), RetrievedAt: time.Now().UnixMilli(), - ExpiresAt: time.Now().Add(config.Redis.JavaCacheDuration).UnixMilli(), + ExpiresAt: time.Now().Add(config.Cache.JavaStatusDuration).UnixMilli(), }, }, nil } @@ -251,9 +245,9 @@ func FetchJavaStatus(host string, port uint16) (*JavaStatusResponse, error) { Online: true, Host: host, Port: port, - EULABlocked: isEULABlocked, + EULABlocked: IsBlockedAddress(host), RetrievedAt: time.Now().UnixMilli(), - ExpiresAt: time.Now().Add(config.Redis.JavaCacheDuration).UnixMilli(), + ExpiresAt: time.Now().Add(config.Cache.JavaStatusDuration).UnixMilli(), }, JavaStatus: &JavaStatus{ Version: nil, @@ -313,9 +307,9 @@ func FetchJavaStatus(host string, port uint16) (*JavaStatusResponse, error) { Online: true, Host: host, Port: port, - EULABlocked: isEULABlocked, + EULABlocked: IsBlockedAddress(host), RetrievedAt: time.Now().UnixMilli(), - ExpiresAt: time.Now().Add(config.Redis.JavaCacheDuration).UnixMilli(), + ExpiresAt: time.Now().Add(config.Cache.JavaStatusDuration).UnixMilli(), }, JavaStatus: &JavaStatus{ Version: &JavaVersion{ @@ -341,12 +335,6 @@ func FetchJavaStatus(host string, port uint16) (*JavaStatusResponse, error) { } func FetchBedrockStatus(host string, port uint16) (*BedrockStatusResponse, error) { - isEULABlocked, err := IsBlockedAddress(host) - - if err != nil { - return nil, err - } - status, err := mcutil.StatusBedrock(host, port) if err != nil { @@ -355,9 +343,9 @@ func FetchBedrockStatus(host string, port uint16) (*BedrockStatusResponse, error Online: false, Host: host, Port: port, - EULABlocked: isEULABlocked, + EULABlocked: IsBlockedAddress(host), RetrievedAt: time.Now().UnixMilli(), - ExpiresAt: time.Now().Add(config.Redis.BedrockCacheDuration).UnixMilli(), + ExpiresAt: time.Now().Add(config.Cache.BedrockStatusDuration).UnixMilli(), }, }, nil } @@ -367,9 +355,9 @@ func FetchBedrockStatus(host string, port uint16) (*BedrockStatusResponse, error Online: true, Host: host, Port: port, - EULABlocked: isEULABlocked, + EULABlocked: IsBlockedAddress(host), RetrievedAt: time.Now().UnixMilli(), - ExpiresAt: time.Now().Add(config.Redis.BedrockCacheDuration).UnixMilli(), + ExpiresAt: time.Now().Add(config.Cache.BedrockStatusDuration).UnixMilli(), }, BedrockStatus: &BedrockStatus{ Version: nil, diff --git a/src/util.go b/src/util.go index db816c6..5a78c25 100644 --- a/src/util.go +++ b/src/util.go @@ -5,20 +5,69 @@ import ( _ "embed" "encoding/hex" "fmt" + "io" + "net/http" "regexp" "strconv" "strings" + "sync" ) var ( //go:embed icon.png defaultIcon []byte - ipAddressRegExp *regexp.Regexp = regexp.MustCompile(`^\d{1,3}(\.\d{1,3}){3}$`) + blockedServers *MutexArray[string] = nil + ipAddressRegExp *regexp.Regexp = regexp.MustCompile(`^\d{1,3}(\.\d{1,3}){3}$`) ) -func IsBlockedAddress(address string) (bool, error) { - split := strings.Split(strings.ToLower(address), ".") +type MutexArray[K comparable] struct { + List []K + Mutex *sync.Mutex +} +func (m *MutexArray[K]) Has(value K) bool { + m.Mutex.Lock() + + defer m.Mutex.Unlock() + + for _, v := range m.List { + if v == value { + return true + } + } + + return false +} + +func GetBlockedServerList() error { + resp, err := http.Get("https://sessionserver.mojang.com/blockedservers") + + if err != nil { + return err + } + + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("unexpected status code: %d", resp.StatusCode) + } + + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + + if err != nil { + return err + } + + blockedServers = &MutexArray[string]{ + List: strings.Split(string(body), "\n"), + Mutex: &sync.Mutex{}, + } + + return nil +} + +func IsBlockedAddress(address string) bool { + split := strings.Split(strings.ToLower(address), ".") isIPAddress := ipAddressRegExp.MatchString(address) for k := range split { @@ -44,19 +93,14 @@ func IsBlockedAddress(address string) (bool, error) { } newAddressBytes := sha1.Sum([]byte(newAddress)) + newAddressHash := hex.EncodeToString(newAddressBytes[:]) - exists, err := r.Exists(fmt.Sprintf("blocked:%s", hex.EncodeToString(newAddressBytes[:]))) - - if err != nil { - return false, err - } - - if exists { - return true, nil + if blockedServers.Has(newAddressHash) { + return true } } - return false, nil + return false } func ParseAddress(address string, defaultPort uint16) (string, uint16, error) {