Skip to content

Commit

Permalink
Minecraft version 1.19 support (#77)
Browse files Browse the repository at this point in the history
* WIP 1.19 support (#76)

* WIP: more major 1.19 support additions and changes

* WIP: more major 1.19 support additions and changes

* WIP: more major 1.19 support additions and changes

* Working JoinGame 1.19 support; Add ServerResourcePackSendEvent

* Go 1.18 CI

* CI: Go 1.18 only

* Fix register command identifier; Decode debug don't log unknown packets

* Fix Byte argument type; Reintroduce passthroughProperty

* Provide a context.Context to player connection

* Remove unnecessary context.WithCancel

* Correct pem key encoding implementation like in Java

* More FireParallel; Add PlayerChat gob for testing

* Minor changes

* Correct use of zlib.Writer

* Minor changes

* Remove a todo

* Update example
  • Loading branch information
robinbraemer authored Jul 5, 2022
1 parent d93d60b commit 62d5197
Show file tree
Hide file tree
Showing 81 changed files with 4,247 additions and 1,686 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.17
go-version: 1.18
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
fail-fast: false
matrix:
platform: [ubuntu-latest, macos-latest, windows-latest]
go: [ 1.16.x, 1.17.x ]
go: [ 1.18.x ]
runs-on: ${{ matrix.platform }}
steps:
- name: Set up Go
Expand Down
8 changes: 1 addition & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
FROM golang:1.15 AS build

# Health probe client
RUN GRPC_HEALTH_PROBE_VERSION=v0.3.2 && \
wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \
chmod +x /bin/grpc_health_probe
FROM golang:1.18 AS build

WORKDIR /workspace
# Copy the Go Modules manifests
Expand All @@ -25,6 +20,5 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o gate gate.go
# Final image
FROM alpine:latest
WORKDIR /gate
COPY --from=build /bin/grpc_health_probe bin/
COPY --from=build /workspace/gate .
CMD ["./gate"]
207 changes: 110 additions & 97 deletions cmd/gate/root.go
Original file line number Diff line number Diff line change
@@ -1,134 +1,147 @@
/*
Copyright © 2020 Minekube Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package gate

import (
"errors"
"fmt"
"math"
"os"
"strings"

"github.com/go-logr/logr"
"github.com/go-logr/zapr"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/urfave/cli/v2"
"go.minekube.com/gate/pkg/gate"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"

"go.minekube.com/gate/pkg/gate"
)

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "gate",
Short: "Gate is an extensible Minecraft proxy.",
Long: `A high performant & paralleled Minecraft proxy server with
scalability, flexibility & excelled server version support.`,
PreRunE: func(cmd *cobra.Command, args []string) error { return initErr },
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
// Set logger
setLogger := func(devMode bool) error {
zl, err := newZapLogger(devMode)
if err != nil {
return fmt.Errorf("error creating zap logger: %w", err)
}
ctx = logr.NewContext(ctx, zapr.NewLogger(zl))
return nil
}
if err := setLogger(gate.Viper.GetBool("debug")); err != nil {
return err
}

if err := gate.Start(ctx); err != nil {
return fmt.Errorf("error running Gate: %w", err)
}
return nil
},
}

// newZapLogger returns a new zap logger with a modified production
// or development default config to ensure human readability.
func newZapLogger(dev bool) (l *zap.Logger, err error) {
var cfg zap.Config
if dev {
cfg = zap.NewDevelopmentConfig()
} else {
cfg = zap.NewProductionConfig()
}

cfg.Encoding = "console"
cfg.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
cfg.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder

l, err = cfg.Build()
if err != nil {
return nil, err
}
return l, nil
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
// Execute runs App() and calls os.Exit when finished.
func Execute() {
if err := rootCmd.Execute(); err != nil {
if err := App().Run(os.Args); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
os.Exit(0)
}

var initErr error
func App() *cli.App {
app := cli.NewApp()
app.Name = "gate"
app.Usage = "Gate is an extensible Minecraft proxy."
app.Description = `A high performant & paralleled Minecraft proxy server with
scalability, flexibility & excelled server version support.
Visit the website https://minekube.com/gate`

var (
debug bool
configFile string
verbosity int
)
app.Flags = []cli.Flag{
&cli.StringFlag{
Name: "config",
Aliases: []string{"c"},
Usage: `config file (default: ./config.yml)
Supports: yaml/yml, json, toml, hcl, ini, prop/properties/props, env/dotenv`,
EnvVars: []string{"GATE_CONFIG"},
Destination: &configFile,
},
&cli.BoolFlag{
Name: "debug",
Aliases: []string{"d"},
Usage: "Enable debug mode and highest log verbosity",
Destination: &debug,
EnvVars: []string{"GATE_DEBUG"},
},
&cli.IntFlag{
Name: "verbosity",
Aliases: []string{"v"},
Usage: "The higher the verbosity the more logs are shown",
EnvVars: []string{"GATE_VERBOSITY"},
Destination: &verbosity,
},
}
app.Action = func(c *cli.Context) error {
// Init viper
v, err := initViper(c, configFile)
if err != nil {
return cli.Exit(err, 1)
}
// Load config
cfg, err := gate.LoadConfig(v)
if err != nil {
return cli.Exit(err, 1)
}

// Flags overwrite config
debug = debug || cfg.Editions.Java.Config.Debug
cfg.Editions.Java.Config.Debug = debug

func init() {
cobra.OnInitialize(func() { initErr = initConfig() })
if !c.IsSet("verbosity") && debug {
verbosity = math.MaxInt8
}

rootCmd.PersistentFlags().StringP("config", "c", "", `config file (default: ./config.yml)
Supports: yaml/yml, json, toml, hcl, ini, prop/properties/props, env/dotenv`)
rootCmd.PersistentFlags().BoolP("debug", "d", false, "Enable debug mode")
}
// Create logger
log, err := newLogger(debug, verbosity)
if err != nil {
return cli.Exit(fmt.Errorf("error creating zap logger: %w", err), 1)
}
c.Context = logr.NewContext(c.Context, log)

// initConfig binds flags, reads in config file and ENV variables if set.
func initConfig() error {
v := gate.Viper
log.Info("logging verbosity", "verbosity", verbosity)
log.Info("using config file", "config", v.ConfigFileUsed())

_ = v.BindPFlag("config", rootCmd.PersistentFlags().Lookup("config"))
_ = v.BindPFlag("debug", rootCmd.PersistentFlags().Lookup("debug"))
// Start Gate
if err = gate.Start(c.Context, gate.WithConfig(*cfg)); err != nil {
return cli.Exit(fmt.Errorf("error running Gate: %w", err), 1)
}
return nil
}
return app
}

func initViper(c *cli.Context, configFile string) (*viper.Viper, error) {
v := gate.Viper
if c.IsSet("config") {
v.SetConfigFile(configFile)
} else {
v.SetConfigName("config")
v.AddConfigPath(".")
}
// Load Environment Variables
v.SetEnvPrefix("GATE")
v.AutomaticEnv() // read in environment variables that match
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
// Read in config.
if err := v.ReadInConfig(); err != nil {
// A config file is only required to exist when explicit config flag was specified.
if !(errors.As(err, &viper.ConfigFileNotFoundError{}) || os.IsNotExist(err)) || c.IsSet("config") {
return nil, fmt.Errorf("error reading config file %q: %w", v.ConfigFileUsed(), err)
}
}
return v, nil
}

if cfgFile := v.GetString("config"); cfgFile != "" {
v.SetConfigFile(cfgFile)
// newLogger returns a new zap logger with a modified production
// or development default config to ensure human readability.
func newLogger(debug bool, v int) (l logr.Logger, err error) {
var cfg zap.Config
if debug {
cfg = zap.NewDevelopmentConfig()
} else {
v.SetConfigName("config")
v.AddConfigPath(".")
cfg = zap.NewProductionConfig()
}
cfg.Level = zap.NewAtomicLevelAt(zapcore.Level(-v))

// If a config file is found, read it in.
// A config file is not required.
if err := v.ReadInConfig(); err != nil {
if (errors.As(err, &viper.ConfigFileNotFoundError{}) || os.IsNotExist(err)) &&
!rootCmd.PersistentFlags().Changed("config") {
return nil
}
return fmt.Errorf("error reading config file %q: %w", v.ConfigFileUsed(), err)
cfg.Encoding = "console"
cfg.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
cfg.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder

zl, err := cfg.Build()
if err != nil {
return logr.Discard(), err
}
fmt.Println("Using config file:", v.ConfigFileUsed())
return nil
return zapr.NewLogger(zl), nil
}
13 changes: 5 additions & 8 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ editions:
# Declares the proxy commands to 1.13+ clients.
# Default: true
announceProxyCommands: true
# Should the proxy enforce the new public key
# security standard added in Minecraft 1.19?
# Default: true
forceKeyAuthentication: true
# The default disconnect reason to kick player on proxy shutdown when no other reason was given.
# Either in simple legacy '§' format or modern text component '{"text":"...", ...}' json.
shutdownReason: |
Expand Down Expand Up @@ -80,12 +84,6 @@ editions:
mode: legacy
# The secret used if the mode is velocity.
#velocitySecret: secret_here
# The section for health checking when Gate runs in a Kubernetes pod.
# Refer to https://github.com/grpc-ecosystem/grpc-health-probe for more details.
# Gate is also delivered with a docker image where the health check service is enabled by default.
health:
enabled: false
bind: 0.0.0.0:8080
# The quota settings allows rate-limiting IP (last block cut off) for certain operations.
# ops: The allowed operations per second.
# burst: The maximum operations per second (queue like). One burst unit per seconds is refilled.
Expand Down Expand Up @@ -117,8 +115,7 @@ editions:
# Among a lot of other features it even allows players to join locally hosted
# Minecraft servers without having an open port or public IP address.
#
# TODO A link to the documentation will be added when available
# until then please refer to: https://github.com/minekube/connect-java
# Visit https://developers.minekube.com/connect
connect:
# Enabling Connect makes Gate register itself to Connect network.
# This feature is disabled by default, but you are encouraged to
Expand Down
12 changes: 7 additions & 5 deletions examples/extend/simple-proxy/go.mod
Original file line number Diff line number Diff line change
@@ -1,43 +1,45 @@
module simple-proxy

go 1.17
go 1.18

require (
go.minekube.com/brigodier v0.0.1
go.minekube.com/common v0.0.1
go.minekube.com/gate v0.18.3-0.20220603174800-35c9efdd603d
go.minekube.com/gate v0.18.3-0.20220705005751-6a9e47601ab4
)

require (
github.com/agext/levenshtein v1.2.3 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/emirpasic/gods v1.12.0 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/gammazero/deque v0.1.1 // indirect
github.com/gammazero/deque v0.2.0 // indirect
github.com/go-gl/mathgl v1.0.0 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-logr/zapr v1.2.3 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/klauspost/compress v1.15.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/rs/xid v1.3.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sandertv/go-raknet v1.10.2 // indirect
github.com/sandertv/gophertunnel v1.19.1 // indirect
github.com/spf13/afero v1.8.1 // indirect
github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/cobra v1.3.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.10.1 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
github.com/urfave/cli/v2 v2.10.2 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.minekube.com/connect v0.4.2 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
Expand Down
Loading

0 comments on commit 62d5197

Please sign in to comment.