From f3af48f304a4b0af4f1ff066066dd006305d011d Mon Sep 17 00:00:00 2001 From: Chloe Hutchinson <30171259+chloeruka@users.noreply.github.com> Date: Tue, 20 Sep 2022 22:59:39 +1000 Subject: [PATCH 1/2] Feature: add experimental opt to use @xrjr's mcutils library - Added flag `--use-mc-utils` to enable the mcutils ping behavior - Sprinkle of debug messages as I didn't see integration tests to extend - Confirmed working on a live 1.16.5 modded forge server running Enigmatica 6 v1.5.2 - Duplicated existing pattern for legacy server list ping, but it could be more DRY --- go.mod | 29 ++++++++++++++------------- go.sum | 2 ++ java_status.go | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index 658eb08..98fe37d 100644 --- a/go.mod +++ b/go.mod @@ -4,33 +4,34 @@ go 1.17 require ( github.com/Raqbit/mc-pinger v0.2.2 + github.com/avast/retry-go v3.0.0+incompatible + github.com/google/subcommands v1.2.0 + github.com/itzg/go-flagsfiller v1.5.0 + github.com/itzg/line-protocol-sender v0.1.1 + github.com/itzg/zapconfigs v0.1.0 + github.com/prometheus/client_golang v1.11.0 + github.com/sandertv/go-raknet v1.10.0 + github.com/stretchr/testify v1.7.0 + github.com/xrjr/mcutils v1.3.2 + go.uber.org/zap v1.19.1 +) + +require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/subcommands v1.2.0 github.com/iancoleman/strcase v0.1.3 // indirect github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect - github.com/itzg/go-flagsfiller v1.5.0 - github.com/itzg/line-protocol-sender v0.1.1 - github.com/itzg/zapconfigs v0.1.0 github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/pires/go-proxyproto v0.6.0 // indirect - github.com/prometheus/client_golang v1.11.0 + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.26.0 // indirect github.com/prometheus/procfs v0.6.0 // indirect - github.com/sandertv/go-raknet v1.10.0 - github.com/stretchr/testify v1.7.0 go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.19.1 golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 // indirect google.golang.org/protobuf v1.26.0 // indirect -) - -require ( - github.com/avast/retry-go v3.0.0+incompatible // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index 17822e7..22f986c 100644 --- a/go.sum +++ b/go.sum @@ -125,6 +125,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/xrjr/mcutils v1.3.2 h1:AApQqiVrzNhXyggMIjW82x0EWzsQf4MTRtM0ebFjJ9E= +github.com/xrjr/mcutils v1.3.2/go.mod h1:43n8cyMIHYjiRM2LFZLVH5Ppz2+RvWppz6OgkLP8Lsk= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= diff --git a/java_status.go b/java_status.go index 4effde4..19b36c1 100644 --- a/java_status.go +++ b/java_status.go @@ -15,6 +15,7 @@ import ( mcpinger "github.com/Raqbit/mc-pinger" "github.com/google/subcommands" "github.com/itzg/go-flagsfiller" + "github.com/xrjr/mcutils/pkg/ping" ) type statusCmd struct { @@ -22,6 +23,7 @@ type statusCmd struct { Port int `default:"25565" usage:"port of the Minecraft server" env:"MC_PORT"` UseServerListPing bool `usage:"indicates the legacy, server list ping should be used for pre-1.12"` + UseMcUtils bool `usage:"(experimental) try using mcutils to query the server"` RetryInterval time.Duration `usage:"if retry-limit is non-zero, status will be retried at this interval" default:"10s"` RetryLimit int `usage:"if non-zero, failed status will be retried this many times before exiting"` @@ -60,6 +62,10 @@ func (c *statusCmd) Execute(ctx context.Context, fs *flag.FlagSet, args ...inter return c.ExecuteServerListPing() } + if c.UseMcUtils { + return c.ExecuteMcUtilPing(logger) + } + var options []mcpinger.McPingerOption if c.Timeout > 0 { options = append(options, mcpinger.WithTimeout(c.Timeout)) @@ -143,3 +149,51 @@ func (c *statusCmd) ExecuteServerListPing() subcommands.ExitStatus { // regular output is within Do function return subcommands.ExitSuccess } + +func (c *statusCmd) ExecuteMcUtilPing(logger *zap.Logger) subcommands.ExitStatus { + client := ping.NewClient(c.Host, c.Port) + client.DialTimeout = c.Timeout + client.ReadTimeout = c.Timeout + + err := retry.Do(func() error { + + err := client.Connect() + if err != nil { + logger.Debug("Client failed to connect", zap.Error(err)) + return err + } + + defer client.Disconnect() + + hs, err := client.Handshake() + if err != nil { + logger.Debug("Client failed to handshake", zap.Error(err)) + return err + } + + response := hs.Properties.Infos() + logger.Debug("mcutils ping returned", zap.Any("properties", response)) + + if response.Players.Max == 0 { + return errors.New("server not ready") + } + + if c.ShowPlayerCount { + fmt.Printf("%d\n", response.Players.Online) + } else { + fmt.Printf("%s:%d : version=%s online=%d max=%d motd='%s'\n", + c.Host, c.Port, + response.Version.Name, response.Players.Online, response.Players.Max, response.Description) + } + + return nil + }, retry.Delay(c.RetryInterval), retry.Attempts(uint(c.RetryLimit+1))) + + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "failed to ping %s:%d : %s", c.Host, c.Port, err) + return subcommands.ExitFailure + } + + // regular output is within Do function + return subcommands.ExitSuccess +} From 6ccdfe8ce3089bd0f67b39198fecc139c8a7dd38 Mon Sep 17 00:00:00 2001 From: Chloe Hutchinson <30171259+chloeruka@users.noreply.github.com> Date: Wed, 21 Sep 2022 23:13:22 +1000 Subject: [PATCH 2/2] Add docs for --use-mc-utils workaround --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 82ef159..5c973ce 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,13 @@ docker run -it --rm itzg/mc-monitor status-bedrock --host play.fallentech.io where exit code will be 0 for success or 1 for failure. +### Workarounds for some status errors + +Some Forge servers may cause a `string length out of bounds` error during status messages due to how the [FML2 protocol](https://wiki.vg/Minecraft_Forge_Handshake#FML2_protocol_.281.13_-_Current.29) bundles the entire modlist for client compatibility check. If there are issues with `status` failing when it otherwise should work, you can try out the experimental `--use-mc-utils` flag below (enables the [mcutils](https://github.com/xrjr/mcutils) protocol library): +``` +docker run -it --rm itzg/mc-monitor status --use-mc-utils --host play.fallentech.io +``` + ### Monitoring a server with Telegraf > The following example is provided in [examples/mc-monitor-telegraf](examples/mc-monitor-telegraf)