Add Votifier 1 support, clean up code
This commit is contained in:
2
go.mod
2
go.mod
@@ -5,7 +5,7 @@ go 1.19
|
|||||||
require (
|
require (
|
||||||
github.com/go-redsync/redsync/v4 v4.8.1
|
github.com/go-redsync/redsync/v4 v4.8.1
|
||||||
github.com/gofiber/fiber/v2 v2.48.0
|
github.com/gofiber/fiber/v2 v2.48.0
|
||||||
github.com/mcstatus-io/mcutil v1.3.1
|
github.com/mcstatus-io/mcutil v1.4.0
|
||||||
github.com/redis/go-redis/v9 v9.0.5
|
github.com/redis/go-redis/v9 v9.0.5
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -68,6 +68,8 @@ github.com/mcstatus-io/mcutil v1.3.0 h1:NjvwCQXPqBBuPKs5WLrfyg76y3lpNo/c1KwMWN2k
|
|||||||
github.com/mcstatus-io/mcutil v1.3.0/go.mod h1:VPWRCaYXfQheaTt4XJGYOGFzrp2E+B8g393SQiYO5mA=
|
github.com/mcstatus-io/mcutil v1.3.0/go.mod h1:VPWRCaYXfQheaTt4XJGYOGFzrp2E+B8g393SQiYO5mA=
|
||||||
github.com/mcstatus-io/mcutil v1.3.1 h1:S7k/3xpvFjSmFKNZ6QW260q11HRaPSQCSMCEBqmV5X4=
|
github.com/mcstatus-io/mcutil v1.3.1 h1:S7k/3xpvFjSmFKNZ6QW260q11HRaPSQCSMCEBqmV5X4=
|
||||||
github.com/mcstatus-io/mcutil v1.3.1/go.mod h1:VPWRCaYXfQheaTt4XJGYOGFzrp2E+B8g393SQiYO5mA=
|
github.com/mcstatus-io/mcutil v1.3.1/go.mod h1:VPWRCaYXfQheaTt4XJGYOGFzrp2E+B8g393SQiYO5mA=
|
||||||
|
github.com/mcstatus-io/mcutil v1.4.0 h1:UpEaOm/PGIDcPFQqAXY14uhsgaclM3ZsEf6ojuAXZGE=
|
||||||
|
github.com/mcstatus-io/mcutil v1.4.0/go.mod h1:VPWRCaYXfQheaTt4XJGYOGFzrp2E+B8g393SQiYO5mA=
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
|||||||
@@ -120,7 +120,18 @@ func SendVoteHandler(ctx *fiber.Ctx) error {
|
|||||||
|
|
||||||
switch opts.Version {
|
switch opts.Version {
|
||||||
case 1:
|
case 1:
|
||||||
return ctx.Status(http.StatusNotImplemented).SendString("Votifier version 1 is currently not supported")
|
{
|
||||||
|
if err = mcutil.SendLegacyVote(opts.Host, opts.Port, options.LegacyVote{
|
||||||
|
PublicKey: opts.PublicKey,
|
||||||
|
ServiceName: opts.ServiceName,
|
||||||
|
Username: opts.Username,
|
||||||
|
IPAddress: opts.IPAddress,
|
||||||
|
Timestamp: opts.Timestamp,
|
||||||
|
Timeout: time.Second * 5,
|
||||||
|
}); err != nil {
|
||||||
|
return ctx.Status(http.StatusBadRequest).SendString(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
if err = mcutil.SendVote(opts.Host, opts.Port, options.Vote{
|
if err = mcutil.SendVote(opts.Host, opts.Port, options.Vote{
|
||||||
|
|||||||
204
src/status.go
204
src/status.go
@@ -189,27 +189,22 @@ func GetBedrockStatus(host string, port uint16) (*BedrockStatusResponse, time.Du
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
err error = nil
|
|
||||||
response *BedrockStatusResponse = nil
|
|
||||||
data []byte = nil
|
|
||||||
)
|
|
||||||
|
|
||||||
// Fetch a fresh status from the server itself
|
// Fetch a fresh status from the server itself
|
||||||
{
|
{
|
||||||
response = FetchBedrockStatus(host, port)
|
response := FetchBedrockStatus(host, port)
|
||||||
|
|
||||||
if data, err = json.Marshal(response); err != nil {
|
data, err := json.Marshal(response)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Put the status into the cache for future requests
|
if err = r.Set(fmt.Sprintf("bedrock:%s", cacheKey), data, conf.Cache.BedrockStatusDuration); err != nil {
|
||||||
if err = r.Set(fmt.Sprintf("bedrock:%s", cacheKey), data, conf.Cache.BedrockStatusDuration); err != nil {
|
return nil, 0, err
|
||||||
return nil, 0, err
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return response, 0, nil
|
return &response, 0, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetServerIcon returns the icon image of a Java Edition server, either using cache or fetching a fresh image.
|
// GetServerIcon returns the icon image of a Java Edition server, either using cache or fetching a fresh image.
|
||||||
@@ -303,94 +298,10 @@ func FetchJavaStatus(host string, port uint16, enableQuery bool) JavaStatusRespo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FetchBedrockStatus fetches a fresh status of a Bedrock Edition server.
|
// FetchBedrockStatus fetches a fresh status of a Bedrock Edition server.
|
||||||
func FetchBedrockStatus(host string, port uint16) *BedrockStatusResponse {
|
func FetchBedrockStatus(host string, port uint16) BedrockStatusResponse {
|
||||||
status, err := mcutil.StatusBedrock(host, port)
|
status, _ := mcutil.StatusBedrock(host, port)
|
||||||
|
|
||||||
if err != nil {
|
return BuildBedrockResponse(host, port, status)
|
||||||
return &BedrockStatusResponse{
|
|
||||||
BaseStatus: BaseStatus{
|
|
||||||
Online: false,
|
|
||||||
Host: host,
|
|
||||||
Port: port,
|
|
||||||
EULABlocked: IsBlockedAddress(host),
|
|
||||||
RetrievedAt: time.Now().UnixMilli(),
|
|
||||||
ExpiresAt: time.Now().Add(conf.Cache.BedrockStatusDuration).UnixMilli(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response := &BedrockStatusResponse{
|
|
||||||
BaseStatus: BaseStatus{
|
|
||||||
Online: true,
|
|
||||||
Host: host,
|
|
||||||
Port: port,
|
|
||||||
EULABlocked: IsBlockedAddress(host),
|
|
||||||
RetrievedAt: time.Now().UnixMilli(),
|
|
||||||
ExpiresAt: time.Now().Add(conf.Cache.BedrockStatusDuration).UnixMilli(),
|
|
||||||
},
|
|
||||||
BedrockStatus: &BedrockStatus{
|
|
||||||
Version: nil,
|
|
||||||
Players: nil,
|
|
||||||
MOTD: nil,
|
|
||||||
Gamemode: status.Gamemode,
|
|
||||||
ServerID: status.ServerID,
|
|
||||||
Edition: status.Edition,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if status.Version != nil {
|
|
||||||
if response.Version == nil {
|
|
||||||
response.Version = &BedrockVersion{
|
|
||||||
Name: nil,
|
|
||||||
Protocol: nil,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response.Version.Name = status.Version
|
|
||||||
}
|
|
||||||
|
|
||||||
if status.ProtocolVersion != nil {
|
|
||||||
if response.Version == nil {
|
|
||||||
response.Version = &BedrockVersion{
|
|
||||||
Name: nil,
|
|
||||||
Protocol: nil,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response.Version.Protocol = status.ProtocolVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
if status.OnlinePlayers != nil {
|
|
||||||
if response.Players == nil {
|
|
||||||
response.Players = &BedrockPlayers{
|
|
||||||
Online: nil,
|
|
||||||
Max: nil,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response.Players.Online = status.OnlinePlayers
|
|
||||||
}
|
|
||||||
|
|
||||||
if status.MaxPlayers != nil {
|
|
||||||
if response.Players == nil {
|
|
||||||
response.Players = &BedrockPlayers{
|
|
||||||
Online: nil,
|
|
||||||
Max: nil,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response.Players.Max = status.MaxPlayers
|
|
||||||
}
|
|
||||||
|
|
||||||
if status.MOTD != nil {
|
|
||||||
response.MOTD = &MOTD{
|
|
||||||
Raw: status.MOTD.Raw,
|
|
||||||
Clean: status.MOTD.Clean,
|
|
||||||
HTML: status.MOTD.HTML,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return response
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildJavaResponse builds the response data from the status and query information.
|
// BuildJavaResponse builds the response data from the status and query information.
|
||||||
@@ -580,3 +491,94 @@ func BuildJavaResponse(host string, port uint16, status interface{}, query *resp
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BuildBedrockResponse builds the response data from the status information.
|
||||||
|
func BuildBedrockResponse(host string, port uint16, status interface{}) (result BedrockStatusResponse) {
|
||||||
|
result = BedrockStatusResponse{
|
||||||
|
BaseStatus: BaseStatus{
|
||||||
|
Online: true,
|
||||||
|
Host: host,
|
||||||
|
Port: port,
|
||||||
|
EULABlocked: IsBlockedAddress(host),
|
||||||
|
RetrievedAt: time.Now().UnixMilli(),
|
||||||
|
ExpiresAt: time.Now().Add(conf.Cache.BedrockStatusDuration).UnixMilli(),
|
||||||
|
},
|
||||||
|
BedrockStatus: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
if status == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch s := status.(type) {
|
||||||
|
case *response.BedrockStatus:
|
||||||
|
{
|
||||||
|
result.BedrockStatus = &BedrockStatus{
|
||||||
|
Version: nil,
|
||||||
|
Players: nil,
|
||||||
|
MOTD: nil,
|
||||||
|
Gamemode: s.Gamemode,
|
||||||
|
ServerID: s.ServerID,
|
||||||
|
Edition: s.Edition,
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Version != nil {
|
||||||
|
if result.Version == nil {
|
||||||
|
result.Version = &BedrockVersion{
|
||||||
|
Name: nil,
|
||||||
|
Protocol: nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Version.Name = s.Version
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.ProtocolVersion != nil {
|
||||||
|
if result.Version == nil {
|
||||||
|
result.Version = &BedrockVersion{
|
||||||
|
Name: nil,
|
||||||
|
Protocol: nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Version.Protocol = s.ProtocolVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.OnlinePlayers != nil {
|
||||||
|
if result.Players == nil {
|
||||||
|
result.Players = &BedrockPlayers{
|
||||||
|
Online: nil,
|
||||||
|
Max: nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Players.Online = s.OnlinePlayers
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.MaxPlayers != nil {
|
||||||
|
if result.Players == nil {
|
||||||
|
result.Players = &BedrockPlayers{
|
||||||
|
Online: nil,
|
||||||
|
Max: nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Players.Max = s.MaxPlayers
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.MOTD != nil {
|
||||||
|
result.MOTD = &MOTD{
|
||||||
|
Raw: s.MOTD.Raw,
|
||||||
|
Clean: s.MOTD.Clean,
|
||||||
|
HTML: s.MOTD.HTML,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("unknown status type: %T", status))
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
18
src/util.go
18
src/util.go
@@ -29,12 +29,14 @@ var (
|
|||||||
// VoteOptions is the options provided as query parameters to the vote route.
|
// VoteOptions is the options provided as query parameters to the vote route.
|
||||||
type VoteOptions struct {
|
type VoteOptions struct {
|
||||||
Version int
|
Version int
|
||||||
|
IPAddress string
|
||||||
Host string
|
Host string
|
||||||
Port uint16
|
Port uint16
|
||||||
ServiceName string
|
ServiceName string
|
||||||
Username string
|
Username string
|
||||||
UUID string
|
UUID string
|
||||||
Token string
|
Token string
|
||||||
|
PublicKey string
|
||||||
Timestamp time.Time
|
Timestamp time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,15 +192,29 @@ func ParseVoteOptions(ctx *fiber.Ctx) (*VoteOptions, error) {
|
|||||||
// TODO check for properly formatted UUID
|
// TODO check for properly formatted UUID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Public Key
|
||||||
|
{
|
||||||
|
result.PublicKey = ctx.Query("publickey")
|
||||||
|
|
||||||
|
if result.Version == 1 && len(result.PublicKey) < 1 {
|
||||||
|
return nil, fmt.Errorf("invalid 'publickey' query parameter: %s", result.PublicKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Token
|
// Token
|
||||||
{
|
{
|
||||||
result.Token = ctx.Query("token")
|
result.Token = ctx.Query("token")
|
||||||
|
|
||||||
if len(result.Token) < 1 {
|
if result.Version == 2 && len(result.Token) < 1 {
|
||||||
return nil, fmt.Errorf("invalid 'token' query parameter: %s", result.Token)
|
return nil, fmt.Errorf("invalid 'token' query parameter: %s", result.Token)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IP Address
|
||||||
|
{
|
||||||
|
result.IPAddress = ctx.Query("ip", ctx.IP())
|
||||||
|
}
|
||||||
|
|
||||||
// Timestamp
|
// Timestamp
|
||||||
{
|
{
|
||||||
value := ctx.Query("timestamp")
|
value := ctx.Query("timestamp")
|
||||||
|
|||||||
Reference in New Issue
Block a user