Code cleanup, only fetch stale blocked servers
This commit is contained in:
parent
e9d4b5590e
commit
e7ada7435f
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
bin/
|
||||
config.yml
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
blocked-servers.json
|
||||
14
src/main.go
14
src/main.go
@ -24,18 +24,20 @@ func init() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := r.Connect(config.Redis); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
r.SetEnabled(config.Cache.Enable)
|
||||
|
||||
log.Println("Successfully connected to Redis")
|
||||
if config.Cache.Enable {
|
||||
if err := r.Connect(config.Redis); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println("Successfully connected to Redis")
|
||||
}
|
||||
|
||||
if err := GetBlockedServerList(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println("Successfully retrieved EULA blocked servers")
|
||||
|
||||
if instanceID := os.Getenv("INSTANCE_ID"); len(instanceID) > 0 {
|
||||
value, err := strconv.ParseUint(instanceID, 10, 16)
|
||||
|
||||
|
||||
35
src/redis.go
35
src/redis.go
@ -9,10 +9,19 @@ import (
|
||||
)
|
||||
|
||||
type Redis struct {
|
||||
Client *redis.Client
|
||||
Enabled bool
|
||||
Client *redis.Client
|
||||
}
|
||||
|
||||
func (r *Redis) SetEnabled(value bool) {
|
||||
r.Enabled = value
|
||||
}
|
||||
|
||||
func (r *Redis) Connect(uri string) error {
|
||||
if !r.Enabled {
|
||||
return nil
|
||||
}
|
||||
|
||||
opts, err := redis.ParseURL(uri)
|
||||
|
||||
if err != nil {
|
||||
@ -29,6 +38,10 @@ func (r *Redis) Connect(uri string) error {
|
||||
}
|
||||
|
||||
func (r *Redis) Exists(key string) (bool, error) {
|
||||
if !r.Enabled {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||
|
||||
defer cancel()
|
||||
@ -45,6 +58,10 @@ func (r *Redis) Exists(key string) (bool, error) {
|
||||
}
|
||||
|
||||
func (r *Redis) GetString(key string) (string, error) {
|
||||
if !r.Enabled {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||
|
||||
defer cancel()
|
||||
@ -59,6 +76,10 @@ func (r *Redis) GetString(key string) (string, error) {
|
||||
}
|
||||
|
||||
func (r *Redis) GetBytes(key string) ([]byte, error) {
|
||||
if !r.Enabled {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||
|
||||
defer cancel()
|
||||
@ -73,6 +94,10 @@ func (r *Redis) GetBytes(key string) ([]byte, error) {
|
||||
}
|
||||
|
||||
func (r *Redis) Set(key string, value interface{}, ttl time.Duration) error {
|
||||
if !r.Enabled {
|
||||
return nil
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||
|
||||
defer cancel()
|
||||
@ -81,6 +106,10 @@ func (r *Redis) Set(key string, value interface{}, ttl time.Duration) error {
|
||||
}
|
||||
|
||||
func (r *Redis) SetJSON(key string, value interface{}, ttl time.Duration) error {
|
||||
if !r.Enabled {
|
||||
return nil
|
||||
}
|
||||
|
||||
data, err := json.Marshal(value)
|
||||
|
||||
if err != nil {
|
||||
@ -91,5 +120,9 @@ func (r *Redis) SetJSON(key string, value interface{}, ttl time.Duration) error
|
||||
}
|
||||
|
||||
func (r *Redis) Close() error {
|
||||
if !r.Enabled {
|
||||
return nil
|
||||
}
|
||||
|
||||
return r.Client.Close()
|
||||
}
|
||||
|
||||
142
src/status.go
142
src/status.go
@ -8,7 +8,7 @@ import (
|
||||
"github.com/mcstatus-io/mcutil"
|
||||
)
|
||||
|
||||
type StatusOffline struct {
|
||||
type StatusResponse struct {
|
||||
Online bool `json:"online"`
|
||||
Host string `json:"host"`
|
||||
Port uint16 `json:"port"`
|
||||
@ -16,28 +16,22 @@ type StatusOffline struct {
|
||||
}
|
||||
|
||||
type JavaStatusResponse struct {
|
||||
Online bool `json:"online"`
|
||||
Host string `json:"host"`
|
||||
Port uint16 `json:"port"`
|
||||
EULABlocked bool `json:"eula_blocked"`
|
||||
Version *JavaVersion `json:"version"`
|
||||
Players JavaPlayers `json:"players"`
|
||||
MOTD MOTD `json:"motd"`
|
||||
Icon *string `json:"icon"`
|
||||
Mods []Mod `json:"mods"`
|
||||
StatusResponse
|
||||
Version *JavaVersion `json:"version"`
|
||||
Players JavaPlayers `json:"players"`
|
||||
MOTD MOTD `json:"motd"`
|
||||
Icon *string `json:"icon"`
|
||||
Mods []Mod `json:"mods"`
|
||||
}
|
||||
|
||||
type BedrockStatusResponse struct {
|
||||
Online bool `json:"online"`
|
||||
Host string `json:"host"`
|
||||
Port uint16 `json:"port"`
|
||||
EULABlocked bool `json:"eula_blocked"`
|
||||
Version *BedrockVersion `json:"version"`
|
||||
Players *BedrockPlayers `json:"players"`
|
||||
MOTD *MOTD `json:"motd"`
|
||||
Gamemode *string `json:"gamemode"`
|
||||
ServerID *string `json:"server_id"`
|
||||
Edition *string `json:"edition"`
|
||||
StatusResponse
|
||||
Version *BedrockVersion `json:"version"`
|
||||
Players *BedrockPlayers `json:"players"`
|
||||
MOTD *MOTD `json:"motd"`
|
||||
Gamemode *string `json:"gamemode"`
|
||||
ServerID *string `json:"server_id"`
|
||||
Edition *string `json:"edition"`
|
||||
}
|
||||
|
||||
type JavaVersion struct {
|
||||
@ -84,24 +78,20 @@ type Mod struct {
|
||||
func GetJavaStatus(host string, port uint16) (interface{}, error) {
|
||||
cacheKey := fmt.Sprintf("java:%s-%d", host, port)
|
||||
|
||||
if config.Cache.Enable {
|
||||
exists, err := r.Exists(cacheKey)
|
||||
cacheExists, err := r.Exists(cacheKey)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if exists {
|
||||
return r.GetString(cacheKey)
|
||||
}
|
||||
if cacheExists {
|
||||
return r.GetString(cacheKey)
|
||||
}
|
||||
|
||||
response := FetchJavaStatus(host, port)
|
||||
|
||||
if config.Cache.Enable {
|
||||
if err := r.SetJSON(cacheKey, response, config.Cache.JavaCacheDuration); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := r.SetJSON(cacheKey, response, config.Cache.JavaCacheDuration); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
@ -110,24 +100,20 @@ func GetJavaStatus(host string, port uint16) (interface{}, error) {
|
||||
func GetBedrockStatus(host string, port uint16) (interface{}, error) {
|
||||
cacheKey := fmt.Sprintf("bedrock:%s-%d", host, port)
|
||||
|
||||
if config.Cache.Enable {
|
||||
exists, err := r.Exists(cacheKey)
|
||||
cacheExists, err := r.Exists(cacheKey)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if exists {
|
||||
return r.GetString(cacheKey)
|
||||
}
|
||||
if cacheExists {
|
||||
return r.GetString(cacheKey)
|
||||
}
|
||||
|
||||
response := FetchBedrockStatus(host, port)
|
||||
|
||||
if config.Cache.Enable {
|
||||
if err := r.SetJSON(cacheKey, response, config.Cache.BedrockCacheDuration); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := r.SetJSON(cacheKey, response, config.Cache.BedrockCacheDuration); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
@ -136,16 +122,14 @@ func GetBedrockStatus(host string, port uint16) (interface{}, error) {
|
||||
func GetServerIcon(host string, port uint16) ([]byte, error) {
|
||||
cacheKey := fmt.Sprintf("icon:%s-%d", host, port)
|
||||
|
||||
if config.Cache.Enable {
|
||||
exists, err := r.Exists(cacheKey)
|
||||
cacheExists, err := r.Exists(cacheKey)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if exists {
|
||||
return r.GetBytes(cacheKey)
|
||||
}
|
||||
if cacheExists {
|
||||
return r.GetBytes(cacheKey)
|
||||
}
|
||||
|
||||
icon := defaultIconBytes
|
||||
@ -162,10 +146,8 @@ func GetServerIcon(host string, port uint16) ([]byte, error) {
|
||||
icon = data
|
||||
}
|
||||
|
||||
if config.Cache.Enable {
|
||||
if err := r.Set(cacheKey, icon, config.Cache.IconCacheDuration); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := r.Set(cacheKey, icon, config.Cache.IconCacheDuration); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return icon, nil
|
||||
@ -178,7 +160,7 @@ func FetchJavaStatus(host string, port uint16) interface{} {
|
||||
statusLegacy, err := mcutil.StatusLegacy(host, port)
|
||||
|
||||
if err != nil {
|
||||
return StatusOffline{
|
||||
return StatusResponse{
|
||||
Online: false,
|
||||
Host: host,
|
||||
Port: port,
|
||||
@ -187,11 +169,13 @@ func FetchJavaStatus(host string, port uint16) interface{} {
|
||||
}
|
||||
|
||||
response := JavaStatusResponse{
|
||||
Online: true,
|
||||
Host: host,
|
||||
Port: port,
|
||||
EULABlocked: IsBlockedAddress(host),
|
||||
Version: nil,
|
||||
StatusResponse: StatusResponse{
|
||||
Online: true,
|
||||
Host: host,
|
||||
Port: port,
|
||||
EULABlocked: IsBlockedAddress(host),
|
||||
},
|
||||
Version: nil,
|
||||
Players: JavaPlayers{
|
||||
Online: statusLegacy.Players.Online,
|
||||
Max: statusLegacy.Players.Max,
|
||||
@ -243,10 +227,12 @@ func FetchJavaStatus(host string, port uint16) interface{} {
|
||||
}
|
||||
|
||||
return JavaStatusResponse{
|
||||
Online: true,
|
||||
Host: host,
|
||||
Port: port,
|
||||
EULABlocked: IsBlockedAddress(host),
|
||||
StatusResponse: StatusResponse{
|
||||
Online: true,
|
||||
Host: host,
|
||||
Port: port,
|
||||
EULABlocked: IsBlockedAddress(host),
|
||||
},
|
||||
Version: &JavaVersion{
|
||||
NameRaw: status.Version.NameRaw,
|
||||
NameClean: status.Version.NameClean,
|
||||
@ -272,7 +258,7 @@ func FetchBedrockStatus(host string, port uint16) interface{} {
|
||||
status, err := mcutil.StatusBedrock(host, port)
|
||||
|
||||
if err != nil {
|
||||
return StatusOffline{
|
||||
return StatusResponse{
|
||||
Online: false,
|
||||
Host: host,
|
||||
Port: port,
|
||||
@ -281,16 +267,18 @@ func FetchBedrockStatus(host string, port uint16) interface{} {
|
||||
}
|
||||
|
||||
response := BedrockStatusResponse{
|
||||
Online: true,
|
||||
Host: host,
|
||||
Port: port,
|
||||
EULABlocked: IsBlockedAddress(host),
|
||||
Version: nil,
|
||||
Players: nil,
|
||||
MOTD: nil,
|
||||
Gamemode: status.Gamemode,
|
||||
ServerID: status.ServerID,
|
||||
Edition: status.Edition,
|
||||
StatusResponse: StatusResponse{
|
||||
Online: true,
|
||||
Host: host,
|
||||
Port: port,
|
||||
EULABlocked: IsBlockedAddress(host),
|
||||
},
|
||||
Version: nil,
|
||||
Players: nil,
|
||||
MOTD: nil,
|
||||
Gamemode: status.Gamemode,
|
||||
ServerID: status.ServerID,
|
||||
Edition: status.Edition,
|
||||
}
|
||||
|
||||
if status.Version != nil {
|
||||
|
||||
65
src/util.go
65
src/util.go
@ -4,20 +4,29 @@ import (
|
||||
"crypto/sha1"
|
||||
_ "embed"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed icon.png
|
||||
defaultIconBytes []byte
|
||||
ipAddressRegExp = regexp.MustCompile("^\\d{1,3}(\\.\\d{1,3}){3}$")
|
||||
ipAddressRegExp = regexp.MustCompile(`^\d{1,3}(\.\d{1,3}){3}$`)
|
||||
)
|
||||
|
||||
type BlockedServersFile struct {
|
||||
LastUpdated time.Time `json:"last_updated"`
|
||||
Servers []string `json:"servers"`
|
||||
}
|
||||
|
||||
func Contains[T comparable](arr []T, v T) bool {
|
||||
for _, value := range arr {
|
||||
if v == value {
|
||||
@ -29,6 +38,36 @@ func Contains[T comparable](arr []T, v T) bool {
|
||||
}
|
||||
|
||||
func GetBlockedServerList() error {
|
||||
f, err := os.OpenFile("blocked-servers.json", os.O_CREATE|os.O_RDWR, 0777)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(f)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(data) > 0 {
|
||||
var blockedServersFile BlockedServersFile
|
||||
|
||||
if err = json.Unmarshal(data, &blockedServersFile); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if time.Since(blockedServersFile.LastUpdated).Hours() < 24 {
|
||||
blockedServersMutex.Lock()
|
||||
blockedServers = blockedServersFile.Servers
|
||||
blockedServersMutex.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := http.Get("https://sessionserver.mojang.com/blockedservers")
|
||||
|
||||
if err != nil {
|
||||
@ -39,6 +78,8 @@ func GetBlockedServerList() error {
|
||||
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
log.Println("Successfully retrieved EULA blocked servers")
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
@ -49,9 +90,27 @@ func GetBlockedServerList() error {
|
||||
|
||||
blockedServersMutex.Lock()
|
||||
blockedServers = strings.Split(string(body), "\n")
|
||||
blockedServersMutex.Unlock()
|
||||
|
||||
return nil
|
||||
defer blockedServersMutex.Unlock()
|
||||
|
||||
if data, err = json.Marshal(BlockedServersFile{
|
||||
LastUpdated: time.Now(),
|
||||
Servers: blockedServers,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = f.Truncate(0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = f.Seek(0, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = f.Write(data)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func IsBlockedAddress(address string) bool {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user