From 318eb7a63ff161d27fa6cb97cbbc7e5af2c586b0 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Tue, 12 Nov 2024 20:46:39 +0100 Subject: [PATCH 01/32] feat: Initial Gate API --- .examples/extend/simple-proxy/go.mod | 4 +- .examples/extend/simple-proxy/go.sum | 2 + api/minekube/gate/gate_service.proto | 35 +++++++++++ buf.yaml | 11 ++++ config-lite.yml | 12 +++- config.yml | 10 ++++ go.mod | 6 +- go.sum | 12 ++-- pkg/edition/java/config/config.go | 5 +- pkg/edition/java/proto/state/register.go | 2 +- pkg/gate/api.go | 76 ++++++++++++++++++++++++ pkg/gate/config/config.go | 34 ++++++++--- pkg/gate/connect.go | 16 +---- pkg/gate/gate.go | 7 ++- pkg/internal/api/config.go | 32 ++++++++++ pkg/internal/api/convert.go | 14 +++++ pkg/internal/api/server.go | 66 ++++++++++++++++++++ pkg/internal/api/service.go | 57 ++++++++++++++++++ pkg/internal/hashutil/util.go | 16 +++++ 19 files changed, 384 insertions(+), 33 deletions(-) create mode 100644 api/minekube/gate/gate_service.proto create mode 100644 buf.yaml create mode 100644 pkg/gate/api.go create mode 100644 pkg/internal/api/config.go create mode 100644 pkg/internal/api/convert.go create mode 100644 pkg/internal/api/server.go create mode 100644 pkg/internal/api/service.go create mode 100644 pkg/internal/hashutil/util.go diff --git a/.examples/extend/simple-proxy/go.mod b/.examples/extend/simple-proxy/go.mod index 1cc8c85f..12e58f5f 100644 --- a/.examples/extend/simple-proxy/go.mod +++ b/.examples/extend/simple-proxy/go.mod @@ -56,13 +56,13 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect - golang.org/x/sync v0.8.0 // indirect + golang.org/x/sync v0.9.0 // indirect golang.org/x/sys v0.24.0 // indirect golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.7.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/grpc v1.67.1 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/.examples/extend/simple-proxy/go.sum b/.examples/extend/simple-proxy/go.sum index e975418d..1545b149 100644 --- a/.examples/extend/simple-proxy/go.sum +++ b/.examples/extend/simple-proxy/go.sum @@ -324,6 +324,7 @@ golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -422,6 +423,7 @@ google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFW google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/api/minekube/gate/gate_service.proto b/api/minekube/gate/gate_service.proto new file mode 100644 index 00000000..f1247426 --- /dev/null +++ b/api/minekube/gate/gate_service.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; + +package minekube.gate.v1; + +// GateService is the service of a Gate instance. +service GateService { + // GetPlayer returns the player by the given id or username. + // If the player is not online, the rpc fails with a NOT_FOUND error code. + rpc GetPlayer(GetPlayerRequest) returns (GetPlayerResponse); +} + +// GetPlayerRequest is the request for GetPlayer method. +message GetPlayerRequest { + // Gets the player by the given id (Minecraft UUID). + // Optional, if not set the username will be used. + // If both id and username are set, the id will be used. + // + // Format but be a valid Minecraft UUID. + string id = 1; + // Gets the player by the given username. + // Optional, if not set the id will be used. + string username = 2; +} + +// GetPlayerResponse is the response for GetPlayer method. +message GetPlayerResponse { + // The player matching the request. + Player player = 1; +} + +// Player is a Gate player. +message Player { + string id = 1; + string username = 2; +} diff --git a/buf.yaml b/buf.yaml new file mode 100644 index 00000000..4818eed9 --- /dev/null +++ b/buf.yaml @@ -0,0 +1,11 @@ +# For details on buf.yaml configuration, visit https://buf.build/docs/configuration/v2/buf-yaml +version: v2 +modules: + - path: api + name: buf.build/minekube/gate +lint: + use: + - STANDARD +breaking: + use: + - FILE diff --git a/config-lite.yml b/config-lite.yml index 2ec1763b..4759df60 100644 --- a/config-lite.yml +++ b/config-lite.yml @@ -107,4 +107,14 @@ connect: # # It is supported to run multiple Gates on the same endpoint name for load balancing # (use the same connect.json token file from first Gate instance). - #name: your-endpoint-name \ No newline at end of file + #name: your-endpoint-name + +# Gate HTTP API configuration. +# See https://gate.minekube.com/guide/api for more information. +api: + # Whether to enable the API for Gate. + # Default: false + enabled: false + # The bind address to listen for API connections. + # Default: localhost:8080 + bind: localhost:8080 diff --git a/config.yml b/config.yml index 3346b3de..36bbf197 100644 --- a/config.yml +++ b/config.yml @@ -202,3 +202,13 @@ connect: # It is supported to run multiple Gates on the same endpoint name for load balancing # (use the same connect.json token file from first Gate instance). #name: your-endpoint-name + +# Gate HTTP API configuration. +# See https://gate.minekube.com/guide/api for more information. +api: + # Whether to enable the API for Gate. + # Default: false + enabled: false + # The bind address to listen for API connections. + # Default: localhost:8080 + bind: localhost:8080 diff --git a/go.mod b/go.mod index f4d0dab7..edc44e03 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,9 @@ module go.minekube.com/gate go 1.22.2 require ( + buf.build/gen/go/minekube/gate/connectrpc/go v1.17.0-20241112182742-0be6bde74bd2.1 + buf.build/gen/go/minekube/gate/protocolbuffers/go v1.35.1-20241112182742-0be6bde74bd2.1 + connectrpc.com/connect v1.17.0 github.com/Tnze/go-mc v1.20.2 github.com/agext/levenshtein v1.2.3 github.com/coder/websocket v1.8.12 @@ -33,6 +36,7 @@ require ( go.uber.org/atomic v1.11.0 go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 + golang.org/x/net v0.28.0 golang.org/x/sync v0.9.0 golang.org/x/text v0.19.0 golang.org/x/time v0.7.0 @@ -71,6 +75,6 @@ require ( golang.org/x/image v0.11.0 // indirect golang.org/x/sys v0.24.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) diff --git a/go.sum b/go.sum index 3f5d8b97..c4c50347 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,15 @@ buf.build/gen/go/minekube/connect/protocolbuffers/go v1.34.2-20240220124425-904ce30425c9.2 h1:P9rrKBfkybGwL8Rb5UmzCnOa/mkcJtrUrRVEX5An9k8= buf.build/gen/go/minekube/connect/protocolbuffers/go v1.34.2-20240220124425-904ce30425c9.2/go.mod h1:D/wczfxm9oSmKysNIdtRRiwwkOnJUw8xWj8hgDMBko0= +buf.build/gen/go/minekube/gate/connectrpc/go v1.17.0-20241112182742-0be6bde74bd2.1 h1:yTiBLj0Fv8vFUIOPxYjTgX0oCxCvD8Tn4JrZk3dyYY0= +buf.build/gen/go/minekube/gate/connectrpc/go v1.17.0-20241112182742-0be6bde74bd2.1/go.mod h1:uQaxf0RsakV18FiLB5HAEgWkN9p0oWKeIqsrhCZ0AqU= +buf.build/gen/go/minekube/gate/protocolbuffers/go v1.35.1-20241112182742-0be6bde74bd2.1 h1:mlzFWtvq7rpt+Ucgs4cLBnkYImtnjcMPi7b0ilqyT7o= +buf.build/gen/go/minekube/gate/protocolbuffers/go v1.35.1-20241112182742-0be6bde74bd2.1/go.mod h1:sxAilWEY5LK1dRTjcGbCqco292JXujOuJkYW6B5UuK0= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= +connectrpc.com/connect v1.17.0 h1:W0ZqMhtVzn9Zhn2yATuUokDLO5N+gIuBWMOnsQrfmZk= +connectrpc.com/connect v1.17.0/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= @@ -274,8 +280,6 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -334,8 +338,8 @@ google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/pkg/edition/java/config/config.go b/pkg/edition/java/config/config.go index 5018eff0..0e25632b 100644 --- a/pkg/edition/java/config/config.go +++ b/pkg/edition/java/config/config.go @@ -2,6 +2,8 @@ package config import ( "fmt" + "strings" + "time" liteconfig "go.minekube.com/gate/pkg/edition/java/lite/config" "go.minekube.com/gate/pkg/edition/java/proto/version" @@ -9,7 +11,6 @@ import ( "go.minekube.com/gate/pkg/util/configutil" "go.minekube.com/gate/pkg/util/favicon" "go.minekube.com/gate/pkg/util/validation" - "time" ) // DefaultConfig is a default Config. @@ -187,7 +188,7 @@ func (c *Config) Validate() (warns []error, errs []error) { return } - if len(c.Bind) == 0 { + if strings.TrimSpace(c.Bind) == "" { e("Bind is empty") } else { if err := validation.ValidHostPort(c.Bind); err != nil { diff --git a/pkg/edition/java/proto/state/register.go b/pkg/edition/java/proto/state/register.go index d0406cb9..3ca89f0e 100644 --- a/pkg/edition/java/proto/state/register.go +++ b/pkg/edition/java/proto/state/register.go @@ -311,7 +311,7 @@ func init() { m(0x43, version.Minecraft_1_20_2), m(0x45, version.Minecraft_1_20_3), m(0x47, version.Minecraft_1_20_5), - m(0x4C, version.Minecraft_1_21_2), + m(0x4C, version.Minecraft_1_21_2), ) Play.ClientBound.Register(&p.Disconnect{}, m(0x40, version.Minecraft_1_7_2), diff --git a/pkg/gate/api.go b/pkg/gate/api.go new file mode 100644 index 00000000..c4f9cd0d --- /dev/null +++ b/pkg/gate/api.go @@ -0,0 +1,76 @@ +package gate + +import ( + "bytes" + "context" + "sync" + + "github.com/go-logr/logr" + "github.com/robinbraemer/event" + + "go.minekube.com/gate/pkg/edition/java/proxy" + "go.minekube.com/gate/pkg/gate/config" + "go.minekube.com/gate/pkg/internal/api" + "go.minekube.com/gate/pkg/internal/hashutil" + "go.minekube.com/gate/pkg/internal/reload" + "go.minekube.com/gate/pkg/runtime/process" +) + +func setupAPI(cfg *config.Config, eventMgr event.Manager, initialEnable *proxy.Proxy) process.Runnable { + return process.RunnableFunc(func(ctx context.Context) error { + log := logr.FromContextOrDiscard(ctx).WithName("api") + ctx = logr.NewContext(ctx, log) + + var ( + mu sync.Mutex + stop context.CancelFunc + currentConfigHash []byte + ) + trigger := func(c *reload.ConfigUpdateEvent[config.Config]) { + newConfigHash, err := hashutil.JsonHash(c.Config.API) + if err != nil { + log.Error(err, "error hashing API config") + return + } + + mu.Lock() + defer mu.Unlock() + + // check if config changed + if bytes.Equal(newConfigHash, currentConfigHash) { + return // no change + } + currentConfigHash = newConfigHash + + if stop != nil { + stop() + stop = nil + } + + if c.Config.API.Enabled { + svc := api.NewService(initialEnable) + srv := api.NewServer(c.Config.API.Config, svc) + + var runCtx context.Context + runCtx, stop = context.WithCancel(ctx) + go func() { + if err := srv.Start(runCtx); err != nil { + log.Error(err, "failed to start api service") + return + } + log.Info("api service stopped") + }() + } + } + + defer reload.Subscribe(eventMgr, trigger)() + + trigger(&reload.ConfigUpdateEvent[config.Config]{ + Config: cfg, + PrevConfig: cfg, + }) + + <-ctx.Done() + return nil + }) +} diff --git a/pkg/gate/config/config.go b/pkg/gate/config/config.go index 9bff5005..a985ace4 100644 --- a/pkg/gate/config/config.go +++ b/pkg/gate/config/config.go @@ -5,6 +5,7 @@ import ( bconfig "go.minekube.com/gate/pkg/edition/bedrock/config" jconfig "go.minekube.com/gate/pkg/edition/java/config" + "go.minekube.com/gate/pkg/internal/api" connect "go.minekube.com/gate/pkg/util/connectutil/config" "go.minekube.com/gate/pkg/util/validation" ) @@ -27,6 +28,10 @@ var DefaultConfig = Config{ Bind: "0.0.0.0:9090", }, Connect: connect.DefaultConfig, + API: API{ + Enabled: false, + Config: api.DefaultConfig, + }, } // Config is the root configuration of Gate. @@ -40,6 +45,8 @@ type Config struct { HealthService HealthService `json:"healthService,omitempty" yaml:"healthService,omitempty"` // See Connect struct. Connect connect.Config `json:"connect,omitempty" yaml:"connect,omitempty"` + // See API struct. + API API `json:"api,omitempty" yaml:"api,omitempty"` } // Editions provides Minecraft edition specific configs. @@ -58,15 +65,21 @@ type Java struct { // Bedrock edition. type Bedrock struct { - Enabled bool - Config bconfig.Config + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + Config bconfig.Config `json:"config,omitempty" yaml:"config,omitempty"` } // HealthService is a GRPC health probe service for use with Kubernetes pods. // (https://github.com/grpc-ecosystem/grpc-health-probe) type HealthService struct { - Enabled bool - Bind string + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + Bind string `json:"bind,omitempty" yaml:"bind,omitempty"` +} + +// API is the configuration for the Gate API. +type API struct { + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + Config api.Config `json:"config,omitempty" yaml:"config,omitempty"` } // Validate validates a Config and all enabled edition configs (Java / Bedrock). @@ -96,10 +109,15 @@ func (c *Config) Validate() (warns []error, errs []error) { warns = append(warns, prefix("java", warns2)...) errs = append(errs, prefix("java", errs2)...) } - if c.Editions.Bedrock.Enabled { - warns2, errs2 := c.Editions.Java.Config.Validate() - warns = append(warns, prefix("bedrock", warns2)...) - errs = append(errs, prefix("bedrock", errs2)...) + //if c.Editions.Bedrock.Enabled { + // warns2, errs2 := c.Editions.Bedrock.Config.Validate() + // warns = append(warns, prefix("bedrock", warns2)...) + // errs = append(errs, prefix("bedrock", errs2)...) + //} + if c.API.Enabled { + warns2, errs2 := c.API.Config.Validate() + warns = append(warns, prefix("api", warns2)...) + errs = append(errs, prefix("api", errs2)...) } return } diff --git a/pkg/gate/connect.go b/pkg/gate/connect.go index 591bd1e5..e76aac8a 100644 --- a/pkg/gate/connect.go +++ b/pkg/gate/connect.go @@ -3,13 +3,13 @@ package gate import ( "bytes" "context" - "crypto/sha1" - "encoding/json" "sync" "github.com/go-logr/logr" "github.com/robinbraemer/event" + "go.minekube.com/gate/pkg/gate/config" + "go.minekube.com/gate/pkg/internal/hashutil" "go.minekube.com/gate/pkg/internal/reload" "go.minekube.com/gate/pkg/runtime/process" connectcfg "go.minekube.com/gate/pkg/util/connectutil/config" @@ -39,7 +39,7 @@ func setupConnect( return } - newConfigHash, err := jsonHash(connect) + newConfigHash, err := hashutil.JsonHash(connect) if err != nil { log.Error(err, "error hashing Connect config") return @@ -89,13 +89,3 @@ func setupConnect( return nil })) } - -// jsonHash returns the sha1 hash of the JSON representation of v. -func jsonHash(v any) ([]byte, error) { - j, err := json.Marshal(v) - if err != nil { - return nil, err - } - h := sha1.Sum(j) - return h[:], nil -} diff --git a/pkg/gate/gate.go b/pkg/gate/gate.go index 36fdca4d..661128ea 100644 --- a/pkg/gate/gate.go +++ b/pkg/gate/gate.go @@ -14,6 +14,8 @@ import ( "github.com/go-logr/logr" "github.com/robinbraemer/event" "github.com/spf13/viper" + "gopkg.in/yaml.v3" + "go.minekube.com/gate/pkg/bridge" "go.minekube.com/gate/pkg/edition" bproxy "go.minekube.com/gate/pkg/edition/bedrock/proxy" @@ -25,7 +27,6 @@ import ( connectcfg "go.minekube.com/gate/pkg/util/connectutil/config" errorsutil "go.minekube.com/gate/pkg/util/errs" "go.minekube.com/gate/pkg/util/interrupt" - "gopkg.in/yaml.v3" ) // Options are Gate options. @@ -113,6 +114,10 @@ func New(options Options) (gate *Gate, err error) { return nil, err } + if err = gate.proc.Add(setupAPI(c, eventMgr, gate.Java())); err != nil { + return nil, err + } + return gate, nil } diff --git a/pkg/internal/api/config.go b/pkg/internal/api/config.go new file mode 100644 index 00000000..d20894f2 --- /dev/null +++ b/pkg/internal/api/config.go @@ -0,0 +1,32 @@ +package api + +import ( + "errors" + "fmt" + "strings" + + "go.minekube.com/gate/pkg/util/validation" +) + +// DefaultConfig is the default configuration for the Config. +var DefaultConfig = Config{ + Bind: "localhost:8080", +} + +// Config is the configuration for the Gate API. +type Config struct { + // Bind is the address to bind the API server to. + // Using a localhost address is recommended to avoid exposing the API to the public. + Bind string `json:"bind,omitempty" yaml:"bind,omitempty"` +} + +// Validate validates the API configuration. +func (c Config) Validate() (warns []error, errs []error) { + if strings.TrimSpace(c.Bind) == "" { + return nil, []error{errors.New("bind address must not be empty")} + } + if err := validation.ValidHostPort(c.Bind); err != nil { + return nil, []error{fmt.Errorf("invalid bind %q: %v", c.Bind, err)} + } + return nil, nil +} diff --git a/pkg/internal/api/convert.go b/pkg/internal/api/convert.go new file mode 100644 index 00000000..975cd90a --- /dev/null +++ b/pkg/internal/api/convert.go @@ -0,0 +1,14 @@ +package api + +import ( + pb "buf.build/gen/go/minekube/gate/protocolbuffers/go/minekube/gate" + + "go.minekube.com/gate/pkg/edition/java/proxy" +) + +func PlayerToProto(p proxy.Player) *pb.Player { + return &pb.Player{ + Id: p.ID().String(), + Username: p.Username(), + } +} diff --git a/pkg/internal/api/server.go b/pkg/internal/api/server.go new file mode 100644 index 00000000..c21907a0 --- /dev/null +++ b/pkg/internal/api/server.go @@ -0,0 +1,66 @@ +package api + +import ( + "context" + "errors" + "net" + "net/http" + "time" + + "buf.build/gen/go/minekube/gate/connectrpc/go/minekube/gate/gatev1connect" + "github.com/go-logr/logr" + "golang.org/x/net/http2" + "golang.org/x/net/http2/h2c" + "golang.org/x/sync/errgroup" +) + +func NewServer(cfg Config, h Handler) *Server { + return &Server{ + cfg: cfg, + h: h, + } +} + +type Server struct { + cfg Config + h Handler +} + +func (s *Server) Start(ctx context.Context) error { + log := logr.FromContextOrDiscard(ctx) + log.Info("starting api service", "bind", s.cfg.Bind) + + mux := http.NewServeMux() + mux.Handle(gatev1connect.NewGateServiceHandler(s.h)) + + hs := &http.Server{ + Addr: s.cfg.Bind, + Handler: h2c.NewHandler(mux, &http2.Server{ + IdleTimeout: time.Second * 30, + }), + ReadTimeout: time.Second * 5, + ReadHeaderTimeout: time.Second * 5, + WriteTimeout: time.Second * 10, + IdleTimeout: time.Second * 30, + BaseContext: func(net.Listener) context.Context { return ctx }, + } + + eg, ctx := errgroup.WithContext(ctx) + + eg.Go(func() error { + <-ctx.Done() + stopCtx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + return hs.Shutdown(stopCtx) + }) + eg.Go(func() error { return ignoreClosed(hs.ListenAndServe()) }) + + return eg.Wait() +} + +func ignoreClosed(err error) error { + if errors.Is(err, http.ErrServerClosed) { + return nil + } + return err +} diff --git a/pkg/internal/api/service.go b/pkg/internal/api/service.go new file mode 100644 index 00000000..b84740c0 --- /dev/null +++ b/pkg/internal/api/service.go @@ -0,0 +1,57 @@ +package api + +import ( + "context" + "errors" + "fmt" + + pb "buf.build/gen/go/minekube/gate/protocolbuffers/go/minekube/gate" + + "buf.build/gen/go/minekube/gate/connectrpc/go/minekube/gate/gatev1connect" + "connectrpc.com/connect" + + "go.minekube.com/gate/pkg/edition/java/proxy" + "go.minekube.com/gate/pkg/util/uuid" +) + +func NewService(p *proxy.Proxy) *Service { + return &Service{ + p: p, + } +} + +type ( + Handler = gatev1connect.GateServiceHandler + + Service struct { + p *proxy.Proxy + } +) + +func (s *Service) GetPlayer(ctx context.Context, c *connect.Request[pb.GetPlayerRequest]) (*connect.Response[pb.GetPlayerResponse], error) { + req := c.Msg + + var player proxy.Player + switch { + case req.GetId() != "": + id, err := uuid.Parse(req.GetId()) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid player id: %v", err)) + } + player = s.p.Player(id) + case req.GetUsername() != "": + player = s.p.PlayerByName(req.GetUsername()) + default: + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("id or username must be set")) + } + + if player == nil { + return nil, connect.NewError(connect.CodeNotFound, errors.New("player not found")) + } + + return connect.NewResponse(&pb.GetPlayerResponse{ + Player: PlayerToProto(player), + }), nil +} + +var _ Handler = (*Service)(nil) diff --git a/pkg/internal/hashutil/util.go b/pkg/internal/hashutil/util.go new file mode 100644 index 00000000..d85de324 --- /dev/null +++ b/pkg/internal/hashutil/util.go @@ -0,0 +1,16 @@ +package hashutil + +import ( + "crypto/sha1" + "encoding/json" +) + +// JsonHash returns the sha1 hash of the JSON representation of v. +func JsonHash(v any) ([]byte, error) { + j, err := json.Marshal(v) + if err != nil { + return nil, err + } + h := sha1.Sum(j) + return h[:], nil +} From 68f3576e0e443e92d5f12d84652d48c86260dc9f Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Sat, 16 Nov 2024 12:33:02 +0100 Subject: [PATCH 02/32] add gitignore --- .gitignore | 2 ++ .web/.gitignore | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..2210c031 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +.yarn \ No newline at end of file diff --git a/.web/.gitignore b/.web/.gitignore index 6a814c3e..94a5e3f5 100644 --- a/.web/.gitignore +++ b/.web/.gitignore @@ -1,2 +1,5 @@ /docs/.vitepress/dist/ +/docs/.vitepress/cache /node_modules/ +.pnp.* +.yarn \ No newline at end of file From 70249a0c57f528c237612fe0fcc4d3db491c27a2 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Sat, 16 Nov 2024 12:33:17 +0100 Subject: [PATCH 03/32] wip: initial docs --- .web/docs/.vitepress/config.ts | 4 ++++ .web/docs/developers/api/index.md | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 .web/docs/developers/api/index.md diff --git a/.web/docs/.vitepress/config.ts b/.web/docs/.vitepress/config.ts index c9ca97e1..128d8748 100644 --- a/.web/docs/.vitepress/config.ts +++ b/.web/docs/.vitepress/config.ts @@ -133,6 +133,10 @@ export default defineConfig({ text: 'Developers Guide', link: '/developers/', }, + { + text: 'HTTP API', + link: '/developers/api/', + }, { text: 'Compatibility', link: '/guide/compatibility' diff --git a/.web/docs/developers/api/index.md b/.web/docs/developers/api/index.md new file mode 100644 index 00000000..d0da50c5 --- /dev/null +++ b/.web/docs/developers/api/index.md @@ -0,0 +1,25 @@ +# Gate HTTP API + +Gate exposes a gRPC API for automating administrative tasks and extending Gate's functionality in languages other than Go. The API leverages modern technologies like Protocol Buffers, gRPC, and ConnectRPC, with schemas managed through buf.build. The API is primarily designed for: + +- Automating server registration and management +- Extending Gate's functionality in non-Go languages +- Integrating Gate with other systems and tools + +While the native Go library provides the most comprehensive access to Gate's features, the HTTP API offers a language-agnostic alternative for core administrative operations. Note that some advanced features available in the Go library may not be exposed through the API. + +For Go applications, we recommend using Gate's native Go library as it provides the most complete and type-safe access to Gate's functionality. Check out [Introduction](/developers/) for more details. + +## API Technology Glossary + +### Protocol Buffers (Protobuf) +Protocol Buffers is Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data. It provides a more efficient and type-safe alternative to formats like JSON, with built-in schema validation and backwards compatibility support. + +### gRPC +gRPC is a modern, open-source remote procedure call (RPC) framework that can run anywhere. It enables client and server applications to communicate transparently and makes it easier to build connected systems. gRPC uses Protocol Buffers as its interface definition language. + +### ConnectRPC +ConnectRPC is a slim RPC framework that supports both gRPC and HTTP/1.1 JSON, making it ideal for web browsers and HTTP API clients. It provides a more lightweight alternative to full gRPC implementations while maintaining compatibility with gRPC services. + +### buf.build +buf.build is a modern Protocol Buffers ecosystem that provides tools for managing, versioning, and sharing Protocol Buffer schemas. It includes features like linting, breaking change detection, and a schema registry. Gate uses buf.build to maintain its API definitions and generate client libraries. From 966477968aeef60a087038f618849745d254913e Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Mon, 18 Nov 2024 15:29:42 +0100 Subject: [PATCH 04/32] internal: use local buf code gen --- .examples/extend/simple-proxy/go.mod | 12 +- .examples/extend/simple-proxy/go.sum | 5 + api/minekube/gate/{ => v1}/gate_service.proto | 0 buf.gen.yaml | 14 + go.mod | 24 +- go.sum | 90 ++---- pkg/internal/api/convert.go | 3 +- .../gen/minekube/gate/v1/gate_service.pb.go | 278 ++++++++++++++++++ .../v1/gatev1connect/gate_service.connect.go | 116 ++++++++ pkg/internal/api/server.go | 3 +- pkg/internal/api/service.go | 4 +- 11 files changed, 457 insertions(+), 92 deletions(-) rename api/minekube/gate/{ => v1}/gate_service.proto (100%) create mode 100644 buf.gen.yaml create mode 100644 pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go create mode 100644 pkg/internal/api/gen/minekube/gate/v1/gatev1connect/gate_service.connect.go diff --git a/.examples/extend/simple-proxy/go.mod b/.examples/extend/simple-proxy/go.mod index 4cba54a1..e5539a72 100644 --- a/.examples/extend/simple-proxy/go.mod +++ b/.examples/extend/simple-proxy/go.mod @@ -1,6 +1,6 @@ module simple-proxy -go 1.22.2 +go 1.23.2 replace go.minekube.com/gate => ../../../ @@ -57,11 +57,11 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect golang.org/x/sync v0.9.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.19.0 // indirect - golang.org/x/time v0.7.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/grpc v1.67.1 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.20.0 // indirect + golang.org/x/time v0.8.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/grpc v1.68.0 // indirect google.golang.org/protobuf v1.35.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/.examples/extend/simple-proxy/go.sum b/.examples/extend/simple-proxy/go.sum index 577ff31f..93cd82d0 100644 --- a/.examples/extend/simple-proxy/go.sum +++ b/.examples/extend/simple-proxy/go.sum @@ -341,6 +341,7 @@ golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= @@ -355,6 +356,7 @@ golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= @@ -363,6 +365,7 @@ golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -394,6 +397,7 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20240808171019-573a1156607a h1: google.golang.org/genproto/googleapis/rpc v0.0.0-20240808171019-573a1156607a/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -415,6 +419,7 @@ google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= diff --git a/api/minekube/gate/gate_service.proto b/api/minekube/gate/v1/gate_service.proto similarity index 100% rename from api/minekube/gate/gate_service.proto rename to api/minekube/gate/v1/gate_service.proto diff --git a/buf.gen.yaml b/buf.gen.yaml new file mode 100644 index 00000000..478beb16 --- /dev/null +++ b/buf.gen.yaml @@ -0,0 +1,14 @@ +version: v2 +clean: true +managed: + enabled: true + override: + - file_option: go_package_prefix + value: go.minekube.com/gate/pkg/internal/api/gen +plugins: + - remote: buf.build/protocolbuffers/go + out: pkg/internal/api/gen + opt: paths=source_relative + - remote: buf.build/connectrpc/go + out: pkg/internal/api/gen + opt: paths=source_relative diff --git a/go.mod b/go.mod index 497242b7..bcd8a934 100644 --- a/go.mod +++ b/go.mod @@ -1,19 +1,17 @@ module go.minekube.com/gate -go 1.22.7 +go 1.23.2 toolchain go1.23.3 require ( - buf.build/gen/go/minekube/gate/connectrpc/go v1.17.0-20241112182742-0be6bde74bd2.1 - buf.build/gen/go/minekube/gate/protocolbuffers/go v1.35.1-20241112182742-0be6bde74bd2.1 connectrpc.com/connect v1.17.0 github.com/Tnze/go-mc v1.20.2 github.com/agext/levenshtein v1.2.3 github.com/coder/websocket v1.8.12 github.com/dboslee/lru v0.0.1 github.com/edwingeng/deque/v2 v2.1.1 - github.com/gammazero/deque v0.2.1 + github.com/gammazero/deque v1.0.0 github.com/go-faker/faker/v4 v4.5.0 github.com/go-logr/logr v1.4.2 github.com/go-logr/zapr v1.3.0 @@ -37,22 +35,23 @@ require ( go.minekube.com/connect v0.6.2 go.uber.org/atomic v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 - golang.org/x/net v0.28.0 + golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f + golang.org/x/net v0.31.0 golang.org/x/sync v0.9.0 golang.org/x/text v0.20.0 golang.org/x/time v0.8.0 google.golang.org/grpc v1.68.0 + google.golang.org/protobuf v1.35.2 gopkg.in/yaml.v3 v3.0.1 ) require ( - buf.build/gen/go/minekube/connect/protocolbuffers/go v1.34.2-20240220124425-904ce30425c9.2 // indirect + buf.build/gen/go/minekube/connect/protocolbuffers/go v1.35.2-20240220124425-904ce30425c9.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/francoispqt/gojay v1.2.13 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-gl/mathgl v1.1.0 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect @@ -60,7 +59,7 @@ require ( github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 // indirect - github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.6.0 // indirect @@ -74,9 +73,8 @@ require ( github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/image v0.11.0 // indirect - golang.org/x/sys v0.25.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/protobuf v1.34.2 // indirect + golang.org/x/image v0.18.0 // indirect + golang.org/x/sys v0.27.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) diff --git a/go.sum b/go.sum index 01507d0f..4a89eec6 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,5 @@ -buf.build/gen/go/minekube/connect/protocolbuffers/go v1.34.2-20240220124425-904ce30425c9.2 h1:P9rrKBfkybGwL8Rb5UmzCnOa/mkcJtrUrRVEX5An9k8= -buf.build/gen/go/minekube/connect/protocolbuffers/go v1.34.2-20240220124425-904ce30425c9.2/go.mod h1:D/wczfxm9oSmKysNIdtRRiwwkOnJUw8xWj8hgDMBko0= -buf.build/gen/go/minekube/gate/connectrpc/go v1.17.0-20241112182742-0be6bde74bd2.1 h1:yTiBLj0Fv8vFUIOPxYjTgX0oCxCvD8Tn4JrZk3dyYY0= -buf.build/gen/go/minekube/gate/connectrpc/go v1.17.0-20241112182742-0be6bde74bd2.1/go.mod h1:uQaxf0RsakV18FiLB5HAEgWkN9p0oWKeIqsrhCZ0AqU= -buf.build/gen/go/minekube/gate/protocolbuffers/go v1.35.1-20241112182742-0be6bde74bd2.1 h1:mlzFWtvq7rpt+Ucgs4cLBnkYImtnjcMPi7b0ilqyT7o= -buf.build/gen/go/minekube/gate/protocolbuffers/go v1.35.1-20241112182742-0be6bde74bd2.1/go.mod h1:sxAilWEY5LK1dRTjcGbCqco292JXujOuJkYW6B5UuK0= +buf.build/gen/go/minekube/connect/protocolbuffers/go v1.35.2-20240220124425-904ce30425c9.1 h1:RV35ziPOz7DrN6S673Dq70Pydg3sFa3uGsYzaztavlo= +buf.build/gen/go/minekube/connect/protocolbuffers/go v1.35.2-20240220124425-904ce30425c9.1/go.mod h1:96yQVJkVjg/fSbxhL7wpEEz59WDdYZ4M9f7MIcGeMQY= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -48,10 +44,10 @@ github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiD github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/gammazero/deque v0.2.1 h1:qSdsbG6pgp6nL7A0+K/B7s12mcCY/5l5SIUpMOl+dC0= -github.com/gammazero/deque v0.2.1/go.mod h1:LFroj8x4cMYCukHJDbxFCkT+r9AndaJnFMuZDV34tuU= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/gammazero/deque v1.0.0 h1:LTmimT8H7bXkkCy6gZX7zNLtkbz4NdS2z8LZuor3j34= +github.com/gammazero/deque v1.0.0/go.mod h1:iflpYvtGfM3U8S8j+sZEKIak3SAKYpA5/SQewgfXDKo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= @@ -72,6 +68,8 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -130,8 +128,8 @@ github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= -github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= -github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/pires/go-proxyproto v0.8.0 h1:5unRmEAPbHXHuLjDg01CxJWf91cw3lKHc/0xzKpXEe0= github.com/pires/go-proxyproto v0.8.0/go.mod h1:iknsfgnH8EkjrMeMyvfKByp9TiBZCKZM0jx2xmKqnVY= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -197,15 +195,9 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= @@ -219,7 +211,6 @@ github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHg github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zyedidia/generic v1.2.1 h1:Zv5KS/N2m0XZZiuLS82qheRG4X1o5gsWreGb0hR7XDc= github.com/zyedidia/generic v1.2.1/go.mod h1:ly2RBz4mnz1yeuVbQA/VFwGjK3mnHGRj1JuoG336Bis= go.minekube.com/brigodier v0.0.1 h1:v5x+fZNefM24JIi+fYQjQcjZ8rwJbfRSpnnpw4b/x6k= @@ -242,18 +233,15 @@ golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+ golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo= -golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8= +golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ= +golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -262,12 +250,8 @@ golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -277,9 +261,6 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -287,43 +268,20 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/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-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -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/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= -golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= @@ -336,20 +294,16 @@ google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoA google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f h1:C1QccEa9kUwvMgEUORqQD9S17QesQijxjZ84sO82mfo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/pkg/internal/api/convert.go b/pkg/internal/api/convert.go index 975cd90a..0fdd81ec 100644 --- a/pkg/internal/api/convert.go +++ b/pkg/internal/api/convert.go @@ -1,9 +1,8 @@ package api import ( - pb "buf.build/gen/go/minekube/gate/protocolbuffers/go/minekube/gate" - "go.minekube.com/gate/pkg/edition/java/proxy" + pb "go.minekube.com/gate/pkg/internal/api/gen/minekube/gate/v1" ) func PlayerToProto(p proxy.Player) *pb.Player { diff --git a/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go b/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go new file mode 100644 index 00000000..b043b93d --- /dev/null +++ b/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go @@ -0,0 +1,278 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.2 +// protoc (unknown) +// source: minekube/gate/v1/gate_service.proto + +package gatev1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// GetPlayerRequest is the request for GetPlayer method. +type GetPlayerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Gets the player by the given id (Minecraft UUID). + // Optional, if not set the username will be used. + // If both id and username are set, the id will be used. + // + // Format but be a valid Minecraft UUID. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Gets the player by the given username. + // Optional, if not set the id will be used. + Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"` +} + +func (x *GetPlayerRequest) Reset() { + *x = GetPlayerRequest{} + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetPlayerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetPlayerRequest) ProtoMessage() {} + +func (x *GetPlayerRequest) ProtoReflect() protoreflect.Message { + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetPlayerRequest.ProtoReflect.Descriptor instead. +func (*GetPlayerRequest) Descriptor() ([]byte, []int) { + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{0} +} + +func (x *GetPlayerRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *GetPlayerRequest) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +// GetPlayerResponse is the response for GetPlayer method. +type GetPlayerResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The player matching the request. + Player *Player `protobuf:"bytes,1,opt,name=player,proto3" json:"player,omitempty"` +} + +func (x *GetPlayerResponse) Reset() { + *x = GetPlayerResponse{} + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetPlayerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetPlayerResponse) ProtoMessage() {} + +func (x *GetPlayerResponse) ProtoReflect() protoreflect.Message { + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetPlayerResponse.ProtoReflect.Descriptor instead. +func (*GetPlayerResponse) Descriptor() ([]byte, []int) { + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{1} +} + +func (x *GetPlayerResponse) GetPlayer() *Player { + if x != nil { + return x.Player + } + return nil +} + +// Player is a Gate player. +type Player struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"` +} + +func (x *Player) Reset() { + *x = Player{} + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Player) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Player) ProtoMessage() {} + +func (x *Player) ProtoReflect() protoreflect.Message { + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Player.ProtoReflect.Descriptor instead. +func (*Player) Descriptor() ([]byte, []int) { + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{2} +} + +func (x *Player) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Player) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +var File_minekube_gate_v1_gate_service_proto protoreflect.FileDescriptor + +var file_minekube_gate_v1_gate_service_proto_rawDesc = []byte{ + 0x0a, 0x23, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x2f, + 0x76, 0x31, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, + 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x22, 0x3e, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x50, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x45, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x06, + 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, + 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x22, 0x34, + 0x0a, 0x06, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x6e, 0x61, 0x6d, 0x65, 0x32, 0x63, 0x0a, 0x0b, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x54, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x12, 0x22, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, + 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0xcd, 0x01, 0x0a, 0x14, 0x63, 0x6f, + 0x6d, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, + 0x76, 0x31, 0x42, 0x10, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x67, 0x6f, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, + 0x75, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x2f, 0x70, 0x6b, 0x67, + 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, + 0x6e, 0x2f, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x2f, + 0x76, 0x31, 0x3b, 0x67, 0x61, 0x74, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x4d, 0x47, 0x58, 0xaa, + 0x02, 0x10, 0x4d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x2e, + 0x56, 0x31, 0xca, 0x02, 0x10, 0x4d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x5c, 0x47, 0x61, + 0x74, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, 0x4d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, + 0x5c, 0x47, 0x61, 0x74, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x12, 0x4d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x3a, + 0x3a, 0x47, 0x61, 0x74, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_minekube_gate_v1_gate_service_proto_rawDescOnce sync.Once + file_minekube_gate_v1_gate_service_proto_rawDescData = file_minekube_gate_v1_gate_service_proto_rawDesc +) + +func file_minekube_gate_v1_gate_service_proto_rawDescGZIP() []byte { + file_minekube_gate_v1_gate_service_proto_rawDescOnce.Do(func() { + file_minekube_gate_v1_gate_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_minekube_gate_v1_gate_service_proto_rawDescData) + }) + return file_minekube_gate_v1_gate_service_proto_rawDescData +} + +var file_minekube_gate_v1_gate_service_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_minekube_gate_v1_gate_service_proto_goTypes = []any{ + (*GetPlayerRequest)(nil), // 0: minekube.gate.v1.GetPlayerRequest + (*GetPlayerResponse)(nil), // 1: minekube.gate.v1.GetPlayerResponse + (*Player)(nil), // 2: minekube.gate.v1.Player +} +var file_minekube_gate_v1_gate_service_proto_depIdxs = []int32{ + 2, // 0: minekube.gate.v1.GetPlayerResponse.player:type_name -> minekube.gate.v1.Player + 0, // 1: minekube.gate.v1.GateService.GetPlayer:input_type -> minekube.gate.v1.GetPlayerRequest + 1, // 2: minekube.gate.v1.GateService.GetPlayer:output_type -> minekube.gate.v1.GetPlayerResponse + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_minekube_gate_v1_gate_service_proto_init() } +func file_minekube_gate_v1_gate_service_proto_init() { + if File_minekube_gate_v1_gate_service_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_minekube_gate_v1_gate_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_minekube_gate_v1_gate_service_proto_goTypes, + DependencyIndexes: file_minekube_gate_v1_gate_service_proto_depIdxs, + MessageInfos: file_minekube_gate_v1_gate_service_proto_msgTypes, + }.Build() + File_minekube_gate_v1_gate_service_proto = out.File + file_minekube_gate_v1_gate_service_proto_rawDesc = nil + file_minekube_gate_v1_gate_service_proto_goTypes = nil + file_minekube_gate_v1_gate_service_proto_depIdxs = nil +} diff --git a/pkg/internal/api/gen/minekube/gate/v1/gatev1connect/gate_service.connect.go b/pkg/internal/api/gen/minekube/gate/v1/gatev1connect/gate_service.connect.go new file mode 100644 index 00000000..262dd06e --- /dev/null +++ b/pkg/internal/api/gen/minekube/gate/v1/gatev1connect/gate_service.connect.go @@ -0,0 +1,116 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: minekube/gate/v1/gate_service.proto + +package gatev1connect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + v1 "go.minekube.com/gate/pkg/internal/api/gen/minekube/gate/v1" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // GateServiceName is the fully-qualified name of the GateService service. + GateServiceName = "minekube.gate.v1.GateService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // GateServiceGetPlayerProcedure is the fully-qualified name of the GateService's GetPlayer RPC. + GateServiceGetPlayerProcedure = "/minekube.gate.v1.GateService/GetPlayer" +) + +// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. +var ( + gateServiceServiceDescriptor = v1.File_minekube_gate_v1_gate_service_proto.Services().ByName("GateService") + gateServiceGetPlayerMethodDescriptor = gateServiceServiceDescriptor.Methods().ByName("GetPlayer") +) + +// GateServiceClient is a client for the minekube.gate.v1.GateService service. +type GateServiceClient interface { + // GetPlayer returns the player by the given id or username. + // If the player is not online, the rpc fails with a NOT_FOUND error code. + GetPlayer(context.Context, *connect.Request[v1.GetPlayerRequest]) (*connect.Response[v1.GetPlayerResponse], error) +} + +// NewGateServiceClient constructs a client for the minekube.gate.v1.GateService service. By +// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, +// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the +// connect.WithGRPC() or connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewGateServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) GateServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + return &gateServiceClient{ + getPlayer: connect.NewClient[v1.GetPlayerRequest, v1.GetPlayerResponse]( + httpClient, + baseURL+GateServiceGetPlayerProcedure, + connect.WithSchema(gateServiceGetPlayerMethodDescriptor), + connect.WithClientOptions(opts...), + ), + } +} + +// gateServiceClient implements GateServiceClient. +type gateServiceClient struct { + getPlayer *connect.Client[v1.GetPlayerRequest, v1.GetPlayerResponse] +} + +// GetPlayer calls minekube.gate.v1.GateService.GetPlayer. +func (c *gateServiceClient) GetPlayer(ctx context.Context, req *connect.Request[v1.GetPlayerRequest]) (*connect.Response[v1.GetPlayerResponse], error) { + return c.getPlayer.CallUnary(ctx, req) +} + +// GateServiceHandler is an implementation of the minekube.gate.v1.GateService service. +type GateServiceHandler interface { + // GetPlayer returns the player by the given id or username. + // If the player is not online, the rpc fails with a NOT_FOUND error code. + GetPlayer(context.Context, *connect.Request[v1.GetPlayerRequest]) (*connect.Response[v1.GetPlayerResponse], error) +} + +// NewGateServiceHandler builds an HTTP handler from the service implementation. It returns the path +// on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewGateServiceHandler(svc GateServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + gateServiceGetPlayerHandler := connect.NewUnaryHandler( + GateServiceGetPlayerProcedure, + svc.GetPlayer, + connect.WithSchema(gateServiceGetPlayerMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + return "/minekube.gate.v1.GateService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case GateServiceGetPlayerProcedure: + gateServiceGetPlayerHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedGateServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedGateServiceHandler struct{} + +func (UnimplementedGateServiceHandler) GetPlayer(context.Context, *connect.Request[v1.GetPlayerRequest]) (*connect.Response[v1.GetPlayerResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("minekube.gate.v1.GateService.GetPlayer is not implemented")) +} diff --git a/pkg/internal/api/server.go b/pkg/internal/api/server.go index c21907a0..a06b8f68 100644 --- a/pkg/internal/api/server.go +++ b/pkg/internal/api/server.go @@ -7,11 +7,12 @@ import ( "net/http" "time" - "buf.build/gen/go/minekube/gate/connectrpc/go/minekube/gate/gatev1connect" "github.com/go-logr/logr" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" "golang.org/x/sync/errgroup" + + "go.minekube.com/gate/pkg/internal/api/gen/minekube/gate/v1/gatev1connect" ) func NewServer(cfg Config, h Handler) *Server { diff --git a/pkg/internal/api/service.go b/pkg/internal/api/service.go index b84740c0..699536aa 100644 --- a/pkg/internal/api/service.go +++ b/pkg/internal/api/service.go @@ -5,9 +5,9 @@ import ( "errors" "fmt" - pb "buf.build/gen/go/minekube/gate/protocolbuffers/go/minekube/gate" + pb "go.minekube.com/gate/pkg/internal/api/gen/minekube/gate/v1" + "go.minekube.com/gate/pkg/internal/api/gen/minekube/gate/v1/gatev1connect" - "buf.build/gen/go/minekube/gate/connectrpc/go/minekube/gate/gatev1connect" "connectrpc.com/connect" "go.minekube.com/gate/pkg/edition/java/proxy" From 03a26e2f317dd2c8f0b9e20e42647d7a93c76cde Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Mon, 18 Nov 2024 15:53:53 +0100 Subject: [PATCH 05/32] feat: add rpc ListServers --- api/minekube/gate/v1/gate_service.proto | 17 ++ pkg/internal/api/convert.go | 16 ++ .../gen/minekube/gate/v1/gate_service.pb.go | 244 +++++++++++++++--- .../v1/gatev1connect/gate_service.connect.go | 37 ++- pkg/internal/api/service.go | 10 +- 5 files changed, 281 insertions(+), 43 deletions(-) diff --git a/api/minekube/gate/v1/gate_service.proto b/api/minekube/gate/v1/gate_service.proto index f1247426..8a46e58b 100644 --- a/api/minekube/gate/v1/gate_service.proto +++ b/api/minekube/gate/v1/gate_service.proto @@ -7,6 +7,23 @@ service GateService { // GetPlayer returns the player by the given id or username. // If the player is not online, the rpc fails with a NOT_FOUND error code. rpc GetPlayer(GetPlayerRequest) returns (GetPlayerResponse); + // ListServers returns all registered servers. + rpc ListServers(ListServersRequest) returns (ListServersResponse); +} + +// ListServersRequest is the request for ListServers method. +message ListServersRequest { +} +// ListServersResponse is the response for ListServers method. +message ListServersResponse { + repeated Server servers = 1; +} + +// Server is a backend server where Gate can connect players to. +message Server { + string name = 1; + string address = 2; + int32 players = 3; } // GetPlayerRequest is the request for GetPlayer method. diff --git a/pkg/internal/api/convert.go b/pkg/internal/api/convert.go index 0fdd81ec..06c07c3e 100644 --- a/pkg/internal/api/convert.go +++ b/pkg/internal/api/convert.go @@ -11,3 +11,19 @@ func PlayerToProto(p proxy.Player) *pb.Player { Username: p.Username(), } } + +func ServersToProto(s []proxy.RegisteredServer) []*pb.Server { + var servers []*pb.Server + for _, server := range s { + servers = append(servers, ServerToProto(server)) + } + return servers +} + +func ServerToProto(s proxy.RegisteredServer) *pb.Server { + return &pb.Server{ + Name: s.ServerInfo().Name(), + Address: s.ServerInfo().Addr().String(), + Players: int32(s.Players().Len()), + } +} diff --git a/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go b/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go index b043b93d..7130ce99 100644 --- a/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go +++ b/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go @@ -20,6 +20,151 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// ListServersRequest is the request for ListServers method. +type ListServersRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListServersRequest) Reset() { + *x = ListServersRequest{} + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListServersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListServersRequest) ProtoMessage() {} + +func (x *ListServersRequest) ProtoReflect() protoreflect.Message { + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListServersRequest.ProtoReflect.Descriptor instead. +func (*ListServersRequest) Descriptor() ([]byte, []int) { + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{0} +} + +// ListServersResponse is the response for ListServers method. +type ListServersResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Servers []*Server `protobuf:"bytes,1,rep,name=servers,proto3" json:"servers,omitempty"` +} + +func (x *ListServersResponse) Reset() { + *x = ListServersResponse{} + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListServersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListServersResponse) ProtoMessage() {} + +func (x *ListServersResponse) ProtoReflect() protoreflect.Message { + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListServersResponse.ProtoReflect.Descriptor instead. +func (*ListServersResponse) Descriptor() ([]byte, []int) { + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{1} +} + +func (x *ListServersResponse) GetServers() []*Server { + if x != nil { + return x.Servers + } + return nil +} + +// Server is a backend server where Gate can connect players to. +type Server struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` + Players int32 `protobuf:"varint,3,opt,name=players,proto3" json:"players,omitempty"` +} + +func (x *Server) Reset() { + *x = Server{} + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Server) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Server) ProtoMessage() {} + +func (x *Server) ProtoReflect() protoreflect.Message { + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Server.ProtoReflect.Descriptor instead. +func (*Server) Descriptor() ([]byte, []int) { + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{2} +} + +func (x *Server) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Server) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +func (x *Server) GetPlayers() int32 { + if x != nil { + return x.Players + } + return 0 +} + // GetPlayerRequest is the request for GetPlayer method. type GetPlayerRequest struct { state protoimpl.MessageState @@ -39,7 +184,7 @@ type GetPlayerRequest struct { func (x *GetPlayerRequest) Reset() { *x = GetPlayerRequest{} - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[0] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -51,7 +196,7 @@ func (x *GetPlayerRequest) String() string { func (*GetPlayerRequest) ProtoMessage() {} func (x *GetPlayerRequest) ProtoReflect() protoreflect.Message { - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[0] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -64,7 +209,7 @@ func (x *GetPlayerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetPlayerRequest.ProtoReflect.Descriptor instead. func (*GetPlayerRequest) Descriptor() ([]byte, []int) { - return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{0} + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{3} } func (x *GetPlayerRequest) GetId() string { @@ -93,7 +238,7 @@ type GetPlayerResponse struct { func (x *GetPlayerResponse) Reset() { *x = GetPlayerResponse{} - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[1] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -105,7 +250,7 @@ func (x *GetPlayerResponse) String() string { func (*GetPlayerResponse) ProtoMessage() {} func (x *GetPlayerResponse) ProtoReflect() protoreflect.Message { - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[1] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -118,7 +263,7 @@ func (x *GetPlayerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetPlayerResponse.ProtoReflect.Descriptor instead. func (*GetPlayerResponse) Descriptor() ([]byte, []int) { - return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{1} + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{4} } func (x *GetPlayerResponse) GetPlayer() *Player { @@ -140,7 +285,7 @@ type Player struct { func (x *Player) Reset() { *x = Player{} - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[2] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -152,7 +297,7 @@ func (x *Player) String() string { func (*Player) ProtoMessage() {} func (x *Player) ProtoReflect() protoreflect.Message { - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[2] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -165,7 +310,7 @@ func (x *Player) ProtoReflect() protoreflect.Message { // Deprecated: Use Player.ProtoReflect.Descriptor instead. func (*Player) Descriptor() ([]byte, []int) { - return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{2} + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{5} } func (x *Player) GetId() string { @@ -188,25 +333,42 @@ var file_minekube_gate_v1_gate_service_proto_rawDesc = []byte{ 0x0a, 0x23, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, - 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x22, 0x3e, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x50, 0x6c, - 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x22, 0x14, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x49, 0x0a, + 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, + 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, + 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x22, 0x50, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x12, 0x18, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x22, 0x3e, 0x0a, 0x10, 0x47, 0x65, + 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, + 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x45, 0x0a, 0x11, 0x47, 0x65, + 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x30, 0x0a, 0x06, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x79, 0x65, + 0x72, 0x22, 0x34, 0x0a, 0x06, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, - 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x45, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x6c, - 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x06, - 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, - 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x22, 0x34, - 0x0a, 0x06, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, - 0x6e, 0x61, 0x6d, 0x65, 0x32, 0x63, 0x0a, 0x0b, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x54, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, - 0x12, 0x22, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, + 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x32, 0xbf, 0x01, 0x0a, 0x0b, 0x47, 0x61, 0x74, 0x65, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x54, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x50, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x12, 0x22, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, - 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0xcd, 0x01, 0x0a, 0x14, 0x63, 0x6f, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, + 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, + 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, + 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x24, 0x2e, 0x6d, + 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, + 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0xcd, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x67, 0x6f, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, @@ -235,21 +397,27 @@ func file_minekube_gate_v1_gate_service_proto_rawDescGZIP() []byte { return file_minekube_gate_v1_gate_service_proto_rawDescData } -var file_minekube_gate_v1_gate_service_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_minekube_gate_v1_gate_service_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_minekube_gate_v1_gate_service_proto_goTypes = []any{ - (*GetPlayerRequest)(nil), // 0: minekube.gate.v1.GetPlayerRequest - (*GetPlayerResponse)(nil), // 1: minekube.gate.v1.GetPlayerResponse - (*Player)(nil), // 2: minekube.gate.v1.Player + (*ListServersRequest)(nil), // 0: minekube.gate.v1.ListServersRequest + (*ListServersResponse)(nil), // 1: minekube.gate.v1.ListServersResponse + (*Server)(nil), // 2: minekube.gate.v1.Server + (*GetPlayerRequest)(nil), // 3: minekube.gate.v1.GetPlayerRequest + (*GetPlayerResponse)(nil), // 4: minekube.gate.v1.GetPlayerResponse + (*Player)(nil), // 5: minekube.gate.v1.Player } var file_minekube_gate_v1_gate_service_proto_depIdxs = []int32{ - 2, // 0: minekube.gate.v1.GetPlayerResponse.player:type_name -> minekube.gate.v1.Player - 0, // 1: minekube.gate.v1.GateService.GetPlayer:input_type -> minekube.gate.v1.GetPlayerRequest - 1, // 2: minekube.gate.v1.GateService.GetPlayer:output_type -> minekube.gate.v1.GetPlayerResponse - 2, // [2:3] is the sub-list for method output_type - 1, // [1:2] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 2, // 0: minekube.gate.v1.ListServersResponse.servers:type_name -> minekube.gate.v1.Server + 5, // 1: minekube.gate.v1.GetPlayerResponse.player:type_name -> minekube.gate.v1.Player + 3, // 2: minekube.gate.v1.GateService.GetPlayer:input_type -> minekube.gate.v1.GetPlayerRequest + 0, // 3: minekube.gate.v1.GateService.ListServers:input_type -> minekube.gate.v1.ListServersRequest + 4, // 4: minekube.gate.v1.GateService.GetPlayer:output_type -> minekube.gate.v1.GetPlayerResponse + 1, // 5: minekube.gate.v1.GateService.ListServers:output_type -> minekube.gate.v1.ListServersResponse + 4, // [4:6] is the sub-list for method output_type + 2, // [2:4] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_minekube_gate_v1_gate_service_proto_init() } @@ -263,7 +431,7 @@ func file_minekube_gate_v1_gate_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_minekube_gate_v1_gate_service_proto_rawDesc, NumEnums: 0, - NumMessages: 3, + NumMessages: 6, NumExtensions: 0, NumServices: 1, }, diff --git a/pkg/internal/api/gen/minekube/gate/v1/gatev1connect/gate_service.connect.go b/pkg/internal/api/gen/minekube/gate/v1/gatev1connect/gate_service.connect.go index 262dd06e..72d26857 100644 --- a/pkg/internal/api/gen/minekube/gate/v1/gatev1connect/gate_service.connect.go +++ b/pkg/internal/api/gen/minekube/gate/v1/gatev1connect/gate_service.connect.go @@ -35,12 +35,15 @@ const ( const ( // GateServiceGetPlayerProcedure is the fully-qualified name of the GateService's GetPlayer RPC. GateServiceGetPlayerProcedure = "/minekube.gate.v1.GateService/GetPlayer" + // GateServiceListServersProcedure is the fully-qualified name of the GateService's ListServers RPC. + GateServiceListServersProcedure = "/minekube.gate.v1.GateService/ListServers" ) // These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. var ( - gateServiceServiceDescriptor = v1.File_minekube_gate_v1_gate_service_proto.Services().ByName("GateService") - gateServiceGetPlayerMethodDescriptor = gateServiceServiceDescriptor.Methods().ByName("GetPlayer") + gateServiceServiceDescriptor = v1.File_minekube_gate_v1_gate_service_proto.Services().ByName("GateService") + gateServiceGetPlayerMethodDescriptor = gateServiceServiceDescriptor.Methods().ByName("GetPlayer") + gateServiceListServersMethodDescriptor = gateServiceServiceDescriptor.Methods().ByName("ListServers") ) // GateServiceClient is a client for the minekube.gate.v1.GateService service. @@ -48,6 +51,8 @@ type GateServiceClient interface { // GetPlayer returns the player by the given id or username. // If the player is not online, the rpc fails with a NOT_FOUND error code. GetPlayer(context.Context, *connect.Request[v1.GetPlayerRequest]) (*connect.Response[v1.GetPlayerResponse], error) + // ListServers returns all registered servers. + ListServers(context.Context, *connect.Request[v1.ListServersRequest]) (*connect.Response[v1.ListServersResponse], error) } // NewGateServiceClient constructs a client for the minekube.gate.v1.GateService service. By @@ -66,12 +71,19 @@ func NewGateServiceClient(httpClient connect.HTTPClient, baseURL string, opts .. connect.WithSchema(gateServiceGetPlayerMethodDescriptor), connect.WithClientOptions(opts...), ), + listServers: connect.NewClient[v1.ListServersRequest, v1.ListServersResponse]( + httpClient, + baseURL+GateServiceListServersProcedure, + connect.WithSchema(gateServiceListServersMethodDescriptor), + connect.WithClientOptions(opts...), + ), } } // gateServiceClient implements GateServiceClient. type gateServiceClient struct { - getPlayer *connect.Client[v1.GetPlayerRequest, v1.GetPlayerResponse] + getPlayer *connect.Client[v1.GetPlayerRequest, v1.GetPlayerResponse] + listServers *connect.Client[v1.ListServersRequest, v1.ListServersResponse] } // GetPlayer calls minekube.gate.v1.GateService.GetPlayer. @@ -79,11 +91,18 @@ func (c *gateServiceClient) GetPlayer(ctx context.Context, req *connect.Request[ return c.getPlayer.CallUnary(ctx, req) } +// ListServers calls minekube.gate.v1.GateService.ListServers. +func (c *gateServiceClient) ListServers(ctx context.Context, req *connect.Request[v1.ListServersRequest]) (*connect.Response[v1.ListServersResponse], error) { + return c.listServers.CallUnary(ctx, req) +} + // GateServiceHandler is an implementation of the minekube.gate.v1.GateService service. type GateServiceHandler interface { // GetPlayer returns the player by the given id or username. // If the player is not online, the rpc fails with a NOT_FOUND error code. GetPlayer(context.Context, *connect.Request[v1.GetPlayerRequest]) (*connect.Response[v1.GetPlayerResponse], error) + // ListServers returns all registered servers. + ListServers(context.Context, *connect.Request[v1.ListServersRequest]) (*connect.Response[v1.ListServersResponse], error) } // NewGateServiceHandler builds an HTTP handler from the service implementation. It returns the path @@ -98,10 +117,18 @@ func NewGateServiceHandler(svc GateServiceHandler, opts ...connect.HandlerOption connect.WithSchema(gateServiceGetPlayerMethodDescriptor), connect.WithHandlerOptions(opts...), ) + gateServiceListServersHandler := connect.NewUnaryHandler( + GateServiceListServersProcedure, + svc.ListServers, + connect.WithSchema(gateServiceListServersMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) return "/minekube.gate.v1.GateService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case GateServiceGetPlayerProcedure: gateServiceGetPlayerHandler.ServeHTTP(w, r) + case GateServiceListServersProcedure: + gateServiceListServersHandler.ServeHTTP(w, r) default: http.NotFound(w, r) } @@ -114,3 +141,7 @@ type UnimplementedGateServiceHandler struct{} func (UnimplementedGateServiceHandler) GetPlayer(context.Context, *connect.Request[v1.GetPlayerRequest]) (*connect.Response[v1.GetPlayerResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("minekube.gate.v1.GateService.GetPlayer is not implemented")) } + +func (UnimplementedGateServiceHandler) ListServers(context.Context, *connect.Request[v1.ListServersRequest]) (*connect.Response[v1.ListServersResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("minekube.gate.v1.GateService.ListServers is not implemented")) +} diff --git a/pkg/internal/api/service.go b/pkg/internal/api/service.go index 699536aa..66935e06 100644 --- a/pkg/internal/api/service.go +++ b/pkg/internal/api/service.go @@ -28,6 +28,14 @@ type ( } ) +var _ Handler = (*Service)(nil) + +func (s *Service) ListServers(ctx context.Context, c *connect.Request[pb.ListServersRequest]) (*connect.Response[pb.ListServersResponse], error) { + return connect.NewResponse(&pb.ListServersResponse{ + Servers: ServersToProto(s.p.Servers()), + }), nil +} + func (s *Service) GetPlayer(ctx context.Context, c *connect.Request[pb.GetPlayerRequest]) (*connect.Response[pb.GetPlayerResponse], error) { req := c.Msg @@ -53,5 +61,3 @@ func (s *Service) GetPlayer(ctx context.Context, c *connect.Request[pb.GetPlayer Player: PlayerToProto(player), }), nil } - -var _ Handler = (*Service)(nil) From 691146a80247a2b76fe4176923d6689661a6fcfe Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Mon, 18 Nov 2024 18:27:10 +0100 Subject: [PATCH 06/32] docs: typescript runtimes --- .examples/extend/simple-proxy/go.mod | 16 +- .examples/extend/simple-proxy/go.sum | 8 + .web/docs/.vitepress/config.ts | 436 ++++++++++-------- .web/docs/developers/api/glossary.md | 19 + .web/docs/developers/api/index.md | 197 +++++++- .web/docs/developers/api/typescript/README.md | 15 + .../developers/api/typescript/bun/.gitignore | 175 +++++++ .../developers/api/typescript/bun/bun.lockb | Bin 0 -> 9352 bytes .../developers/api/typescript/bun/bunfig.toml | 2 + .../developers/api/typescript/bun/index.md | 73 +++ .../developers/api/typescript/bun/index.ts | 15 + .../api/typescript/bun/package.json | 12 + .../api/typescript/bun/tsconfig.json | 27 ++ .web/docs/developers/api/typescript/index.md | 122 +++++ .../developers/api/typescript/node/.npmrc | 1 + .../developers/api/typescript/node/index.md | 89 ++++ .../developers/api/typescript/node/index.ts | 15 + .../api/typescript/node/package.json | 16 + .../api/typescript/node/pnpm-lock.yaml | 179 +++++++ .../docs/developers/api/typescript/web/.npmrc | 1 + .../developers/api/typescript/web/index.md | 89 ++++ .../developers/api/typescript/web/index.ts | 14 + .../api/typescript/web/package.json | 15 + .../api/typescript/web/pnpm-lock.yaml | 163 +++++++ buf.gen.yaml | 2 +- config.yml | 2 +- 26 files changed, 1479 insertions(+), 224 deletions(-) create mode 100644 .web/docs/developers/api/glossary.md create mode 100644 .web/docs/developers/api/typescript/README.md create mode 100644 .web/docs/developers/api/typescript/bun/.gitignore create mode 100755 .web/docs/developers/api/typescript/bun/bun.lockb create mode 100644 .web/docs/developers/api/typescript/bun/bunfig.toml create mode 100644 .web/docs/developers/api/typescript/bun/index.md create mode 100644 .web/docs/developers/api/typescript/bun/index.ts create mode 100644 .web/docs/developers/api/typescript/bun/package.json create mode 100644 .web/docs/developers/api/typescript/bun/tsconfig.json create mode 100644 .web/docs/developers/api/typescript/index.md create mode 100644 .web/docs/developers/api/typescript/node/.npmrc create mode 100644 .web/docs/developers/api/typescript/node/index.md create mode 100644 .web/docs/developers/api/typescript/node/index.ts create mode 100644 .web/docs/developers/api/typescript/node/package.json create mode 100644 .web/docs/developers/api/typescript/node/pnpm-lock.yaml create mode 100644 .web/docs/developers/api/typescript/web/.npmrc create mode 100644 .web/docs/developers/api/typescript/web/index.md create mode 100644 .web/docs/developers/api/typescript/web/index.ts create mode 100644 .web/docs/developers/api/typescript/web/package.json create mode 100644 .web/docs/developers/api/typescript/web/pnpm-lock.yaml diff --git a/.examples/extend/simple-proxy/go.mod b/.examples/extend/simple-proxy/go.mod index e5539a72..91208918 100644 --- a/.examples/extend/simple-proxy/go.mod +++ b/.examples/extend/simple-proxy/go.mod @@ -12,7 +12,7 @@ require ( ) require ( - buf.build/gen/go/minekube/connect/protocolbuffers/go v1.34.2-20240220124425-904ce30425c9.2 // indirect + buf.build/gen/go/minekube/connect/protocolbuffers/go v1.35.2-20240220124425-904ce30425c9.1 // indirect github.com/Tnze/go-mc v1.20.2 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/coder/websocket v1.8.12 // indirect @@ -21,8 +21,8 @@ require ( github.com/edwingeng/deque/v2 v2.1.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/francoispqt/gojay v1.2.13 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gammazero/deque v0.2.1 // indirect + github.com/fsnotify/fsnotify v1.8.0 // indirect + github.com/gammazero/deque v1.0.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect @@ -35,7 +35,7 @@ require ( github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 // indirect github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect - github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pires/go-proxyproto v0.8.0 // indirect github.com/rs/xid v1.6.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect @@ -55,14 +55,14 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect + golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect golang.org/x/sync v0.9.0 // indirect - golang.org/x/sys v0.25.0 // indirect + golang.org/x/sys v0.27.0 // indirect golang.org/x/text v0.20.0 // indirect golang.org/x/time v0.8.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f // indirect google.golang.org/grpc v1.68.0 // indirect - google.golang.org/protobuf v1.35.1 // indirect + google.golang.org/protobuf v1.35.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/.examples/extend/simple-proxy/go.sum b/.examples/extend/simple-proxy/go.sum index 93cd82d0..3ee31afe 100644 --- a/.examples/extend/simple-proxy/go.sum +++ b/.examples/extend/simple-proxy/go.sum @@ -4,6 +4,7 @@ buf.build/gen/go/minekube/connect/protocolbuffers/go v1.34.1-20240220124425-904c buf.build/gen/go/minekube/connect/protocolbuffers/go v1.34.1-20240220124425-904ce30425c9.1/go.mod h1:6hSa70osNsHkE8luMasPFGzmsajsvzcBXHilLjBOWUw= buf.build/gen/go/minekube/connect/protocolbuffers/go v1.34.2-20240220124425-904ce30425c9.2 h1:P9rrKBfkybGwL8Rb5UmzCnOa/mkcJtrUrRVEX5An9k8= buf.build/gen/go/minekube/connect/protocolbuffers/go v1.34.2-20240220124425-904ce30425c9.2/go.mod h1:D/wczfxm9oSmKysNIdtRRiwwkOnJUw8xWj8hgDMBko0= +buf.build/gen/go/minekube/connect/protocolbuffers/go v1.35.2-20240220124425-904ce30425c9.1/go.mod h1:96yQVJkVjg/fSbxhL7wpEEz59WDdYZ4M9f7MIcGeMQY= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -54,8 +55,10 @@ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/gammazero/deque v0.2.1 h1:qSdsbG6pgp6nL7A0+K/B7s12mcCY/5l5SIUpMOl+dC0= github.com/gammazero/deque v0.2.1/go.mod h1:LFroj8x4cMYCukHJDbxFCkT+r9AndaJnFMuZDV34tuU= +github.com/gammazero/deque v1.0.0/go.mod h1:iflpYvtGfM3U8S8j+sZEKIak3SAKYpA5/SQewgfXDKo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= @@ -149,6 +152,7 @@ github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOS github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs= github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4= github.com/pires/go-proxyproto v0.7.1-0.20231012122632-e5b291b295b4 h1:VM7Tse0I0kTEaO/Rk7BPjmDqfiUcpv+RWtiwIY04pgI= @@ -294,6 +298,7 @@ golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDT golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -342,6 +347,7 @@ golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= @@ -398,6 +404,7 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20240808171019-573a1156607a/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -430,6 +437,7 @@ google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHh google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/.web/docs/.vitepress/config.ts b/.web/docs/.vitepress/config.ts index 9f316140..8b9fc346 100644 --- a/.web/docs/.vitepress/config.ts +++ b/.web/docs/.vitepress/config.ts @@ -1,224 +1,262 @@ -import {defineConfig} from 'vitepress' +import { defineConfig } from 'vitepress'; -import {additionalTitle, commitRef, discordLink, editLink, gitHubLink} from '../shared/' +import { + additionalTitle, + commitRef, + discordLink, + editLink, + gitHubLink, +} from '../shared/'; -const ogUrl = 'https://gate.minekube.com' -const ogImage = `${ogUrl}/og-image.png` -const ogTitle = 'Gate Proxy' -const ogDescription = 'Next Generation Minecraft Proxy' +const ogUrl = 'https://gate.minekube.com'; +const ogImage = `${ogUrl}/og-image.png`; +const ogTitle = 'Gate Proxy'; +const ogDescription = 'Next Generation Minecraft Proxy'; export default defineConfig({ - title: `Gate Proxy${additionalTitle}`, - description: ogDescription, - appearance: 'dark', + title: `Gate Proxy${additionalTitle}`, + description: ogDescription, + appearance: 'dark', - sitemap: { - hostname: ogUrl, - }, + sitemap: { + hostname: ogUrl, + }, - head: [ - ['link', {rel: 'icon', type: 'image/png', href: '/favicon.png'}], - ['meta', {property: 'og:type', content: 'website'}], - ['meta', {property: 'og:title', content: ogTitle}], - ['meta', {property: 'og:image', content: ogImage}], - ['meta', {property: 'og:url', content: ogUrl}], - ['meta', {property: 'og:description', content: ogDescription}], - ['meta', {name: 'theme-color', content: '#646cff'}], - // [ - // 'script', - // { - // src: 'https://cdn.usefathom.com/script.js', - // 'data-site': 'CBDFBSLI', - // 'data-spa': 'auto', - // defer: '' - // } - // ] - [ - 'script', - {}, - `!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.async=!0,p.src=s.api_host+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys onSessionId".split(" "),n=0;n +
+
🚀 Independent Updates
+
Ship updates without restarting Gate or disconnecting players
+
+
+
🌐 Cross-Language Support
+
Access Gate's core functionality from any programming language
+
+
+
🔌 Plugin Development
+
Build extensions and plugins in your preferred language
+
+
+
🤖 Automation
+
Automate server registration and management tasks
+
+
+
🎮 Custom Tools
+
Create administrative interfaces and management tools
+
+
+
🔄 Integration
+
Connect Gate with external systems and services
+
+ -### buf.build -buf.build is a modern Protocol Buffers ecosystem that provides tools for managing, versioning, and sharing Protocol Buffer schemas. It includes features like linting, breaking change detection, and a schema registry. Gate uses buf.build to maintain its API definitions and generate client libraries. +## Getting Started + +::: warning Go Applications +While Go applications can use this HTTP API as well, we recommend using Gate's native Go library as it provides the most complete and type-safe access to Gate's functionality, unless you need out-of-process execution or want to iterate and deploy updates independently from your proxy. +::: + +Gate's API definitions are hosted on [buf.build/minekube/gate](https://buf.build/minekube/gate/sdks), where you can directly pull client libraries using your preferred language's package manager: + + + +::: tip Learn More +To understand the key technologies used in Gate's API, check out the [Glossary](/developers/api/glossary). +::: + + diff --git a/.web/docs/developers/api/typescript/README.md b/.web/docs/developers/api/typescript/README.md new file mode 100644 index 00000000..58a6e275 --- /dev/null +++ b/.web/docs/developers/api/typescript/README.md @@ -0,0 +1,15 @@ +# bun + +To install dependencies: + +```bash +bun install +``` + +To run: + +```bash +bun run index.ts +``` + +This project was created using `bun init` in bun v1.1.26. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. diff --git a/.web/docs/developers/api/typescript/bun/.gitignore b/.web/docs/developers/api/typescript/bun/.gitignore new file mode 100644 index 00000000..9b1ee42e --- /dev/null +++ b/.web/docs/developers/api/typescript/bun/.gitignore @@ -0,0 +1,175 @@ +# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore + +# Logs + +logs +_.log +npm-debug.log_ +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Caches + +.cache + +# Diagnostic reports (https://nodejs.org/api/report.html) + +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover + +lib-cov + +# Coverage directory used by tools like istanbul + +coverage +*.lcov + +# nyc test coverage + +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release + +# Dependency directories + +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +*.tsbuildinfo + +# Optional npm cache directory + +.npm + +# Optional eslint cache + +.eslintcache + +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +*.tgz + +# Yarn Integrity file + +.yarn-integrity + +# dotenv environment variable files + +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) + +.parcel-cache + +# Next.js build output + +.next +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + +# Stores VSCode versions used for testing VSCode extensions + +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/.web/docs/developers/api/typescript/bun/bun.lockb b/.web/docs/developers/api/typescript/bun/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..f6fbe44911ecf8ab055e6594949918163a7fba45 GIT binary patch literal 9352 zcmeHN3s{U$2Unkwr|hq0F_rl(1n*Nnw@HWu}Ij$;>oeP~)p?RumymY$QuA zpv>&pYpFUYAX3pJ(@bp8Y@1^ncIg|NCFwbN=VN=VWQY zjh4%}!D0zlC{eP4qa}LqV@F6sW{JcRLbgaMiwsh*l{`Hyf*=g7M){6>-pjkrf9%!g zOOiS*{>FKZ!PgJVH%&dgX=1TFrO6UH0d-R|LgyW>qRMW#0|Cm&IuZQsP7o?z;GY8@ z2HXUAv?Np*$(OrfWH89z5sp;xEb&hRJn*MX94dC^@+d{t`K++;HDtY z0+EWY?&RV&#D)nm&^tAQ^V z)wl0nNtHxDiXC?2<;i~yJTR6wzj4m}u<}%s`o2rK{)?^lxH{`fha9W($=;WDYE|6Y znHR)szf=vfNf8D^*g8ZIHj)zHuP4L-;X$Z~w&G&>lOQv^1M>Qya0Dff-dS4->-PqE zdywx8g1z9!Y$E`c&jfi_kVj?YJNmVSu>2r+aHj0%f*`K{7zXZV(up8^Iv^hc^5Z%n zzq5n-84&P}==TEoi5;*%59GZ&ApaQTAvclZzdi3S7zSPvB~PC}9#C%%^>x=W`{w!v zN}>??RLB+a_tvIJbv9IvC_p{)N0s z7=EJs9FQLd@@W1-9w!iQ3t{{BgFLJqDzqXY*-!QV703^v^rQC&)1l1-q6GRO8T9T@ z{9%nD32{_LF+qel>I-WiN$ugt=dSQWxM-n89M(uO=fIjtmQf55A&%N%t!$zHFMD4b zy+#iFnFM$YLXAs@W*V7wy82n?<{z5B_{CDIa?Zq(;LwW8R%wr)>H~592;LID} zkW+uRqHFE>T^DtK$jo~B@VZ}7q0Qyy^*K{&wP?6_Tq3iX1CM*^U-PSBT~vCmy^y=F zL@PdDac0!B)CV!EgXf*`wDh09uEO8S&o94A6659b{%OlHXYBXr5!iQMX?_)RM?f! z*X6;-^@<*)+O6OCq%hFLJDzSYq`wwoHiUW*_9^+BmrKJ%*-yOm*FWD>F;zRapu#po zU}Hbp-GB1NVqW5)bv>UXHN@$r4j=H_G-bW=%k%*L?`2u%o>kNArO#vL{%+nimGZg2 zPAg#6MsDx1Ia@#3yQ)#?V%{U)=~?nPZIj`5lP#@0dxc%zx6QS5)<~PIBSzUvcg=VZ zH$KlPVfRiNE}Em5nE#&SoWUC4lAe8kPMNf3taFw2*XK6e3Y)AP6L&pP*Uar+_^)@4 z4EWYOw#)Q-e=`ftwamFEetPNP;8C#r`%!v(cf!kJ!0a&wKr}ZnF_SJ7Y`9kzt4#Eh zHcD3xUwAt^ujtK`1&X=9r;IscaB=5zqKRo}GP3URW1rHRex)_Xe`IA;l%Ms^icaqN z`tsuuq`icW3IOp=8DTTWY%)JsRCUdG#J9?eijh4lUz>WCS?eC_{mQkAaj|s7noeui zJKha^QB5Yq<0&>qNKz%i_E3kuL^%x zEyE(SOIGGb<*Z=5CdL-juKJGx88+FT%xn5gE;_omJ6vzfZ!?fr|{%Pc-W0 zC#I~Z-W8A+WWRF5?ZK7@%F`Av+a4KWH|~kdw&LnpkxdyZK|Ux{TsZhb)aWN)|JXp; zi^eX_uOzPcTwmu+hQk`VuYP7W#G>!k%B`-qmacN~sC2S+4ZUu}*=V-AZd9>nzoby( zv1u_ry@`QYYi$j`j}tYj3JzRhxl#5aT>3h~Y)Hx3Hl?win|-G9^rE>p=M_00o^;S@ zSJ|3HRdyMZ%(oQHYQ8paYcDJJ$15Ti_?^F38abx*NF z^5>&O!-a3CKaXg*=-pvrT8HvScklYmz<3Xvob3~ii6(TLcRkd4W5I>FExlccMyE$=o= z^*%_$g>TCiViuk#tGy(iF*N#Etj#d3V;SBh6ACX4b^J~k9+YO9eO=Qe)HhiuA;j54K!S|Z^Fb} zUp9394BsL7+LMpo@%ptko_W6SsiSpiR*7retj_guF?6Y{id06LFQ3(P#3sHcvr7~^ z%dfuSEAPe#J>#eY85uNOv`@gqT;OPOC4Bn60mW0KI{p=BAC#1Bi(FIeAj!0@D6ra| zJ9}}Gxk-a#@1b5*(F=7?9I~lh=jCJTU0&3Ged^*HFP?4%+`o$O`b5wBf0ZqNcfBZ9 zC{8$L?XmYSeAVqS_aB*mBJfWH{`3f_(B~!4a*FE>k;_6jVu@T46cNF}hsYd1nNaA) z67X1ZalB9}8pN_=1x1L%BvKK%jePw^O$Z6CN2L^+Df(yy(i;+OD{up$4~vuEujqRU zefyxChQ29KenT*5Jw|&!v`<5ODzyJWdlj^=KzjhRpGRuojF{YeqVHpOO7FHd=tuS< zJcNyOA{&q`C_f@wa2auY?ttt;`&{Ha+MlDnKe7YahW$YHp*0`bhf);%C ztku#2CnzYADtxM~#hAwD*g0|p=xl~OugB-$WDBXs7h1pr6+S7~w1}Vuoz3I3bh5>P z!zT!Q>W@#;p~apfaN^j#rw9DubNEQnyLyZnd=3fLiVVJ0z^C<~N1%=lzAwP%@Jv7> z9VPIM0zRqNwBS1je3q|i!M76lv|rPL?=AAF`v6S~zS+Px2AURp_kr&eG%fg61K$>C zG48^k>jyD@KROUMGCc3TIZZ_Iod~{b(1IB7Ikqqe@T~~GZO~#QIC1RZJrMZ*1m8t=A`X4Cc5xKbxr`xH_1zKWIwG|$U{i{(wC+`$d+fA zB79V5RGl~Eq513*g6n9wHM*Dcs3Na7N+|4sj#J65*`qVBz#In9ZCJsYD_SQOKe~rVHh$Jvdq% z5sEz56ryBOg%s6jI&-PV4^*)w(okWzLJ=h&%;n02VPd&L7RQl9Mb4CSq_QyXABk|; z7?ea{lcSHL2#fzTEE-Ik5L#TuUIGAq1RGH1_=pkeTm)k32evv9At85BkX#`a#X&gb z!P2*IghkpE!VVKk*kCd{SSAdb1)~`aqd#bRr#eC`QGB2`s&37& zmiWK}X_g40f)X9+Aib3x8YGJmOV~lONC!L3=t0&}EwS&`gYxKDc2JNkB>clo?@53H zTfv7^s2kqvPic@vDjnPEC7UKgc}%OJdEaKh7TYMemU8>S$RNK3N7l3lQ0*KlM8Q0sqn)!e zhmT)B3~-J*Yr^E@LZag;`P`4CT5zP5L<}at(#vjDJ(_>&{M35C4_Ja{Eu{QUb%G}P zo(r@#Z~$e_)-6LGVErFjC|cGn@~uk{CWmi}q|kq$kgctVxAdW;$^ImUtsR-W)bKHK zYJL3JvZd~hdI2C};2hew@JTc(_kYYNdN+Wf7ty-m0DGi11tmrf(lK&2xv5fzgxpW4 c_Ykc_g*1@d765>z0LmRWB#wG_@%Q`tKl_GGt^fc4 literal 0 HcmV?d00001 diff --git a/.web/docs/developers/api/typescript/bun/bunfig.toml b/.web/docs/developers/api/typescript/bun/bunfig.toml new file mode 100644 index 00000000..ab7b9d5d --- /dev/null +++ b/.web/docs/developers/api/typescript/bun/bunfig.toml @@ -0,0 +1,2 @@ +[install.scopes] +"@buf" = "https://buf.build/gen/npm/v1/" diff --git a/.web/docs/developers/api/typescript/bun/index.md b/.web/docs/developers/api/typescript/bun/index.md new file mode 100644 index 00000000..c60a1d95 --- /dev/null +++ b/.web/docs/developers/api/typescript/bun/index.md @@ -0,0 +1,73 @@ +# bun + +You can use the following `bunfig.toml` to install the dependencies from the `buf.build` registry. + +::: code-group + +```toml [bunfig.toml] + +``` + +::: + +To install dependencies: + +```bash +bun add @buf/minekube_gate.connectrpc_es@latest +``` + +Refer to the [ConnectRPC](https://connectrpc.com/docs/node/using-clients) documentation for more information on how to use ConnectRPC with TypeScript on server side. + +::: tip Browser support + +To use the Gate API in the browser, check out the [Web](/developers/api/typescript/web/) documentation. + +::: + +::: code-group + +```ts [index.ts] + +``` + +::: + +## Sample project + +This sample project is located in the [`docs/developers/api/typescript/bun`](https://github.com/minekube/gate/tree/main/.web/docs/developers/api/typescript/bun) directory. + +To install dependencies: + +```bash +bun install +``` + +To run: + +```bash +bun run index.ts +[ + { + "name": "server1", + "address": "localhost:25566", + "players": 0 + }, + { + "name": "server2", + "address": "localhost:25567", + "players": 0 + }, + { + "name": "server3", + "address": "localhost:25568", + "players": 0 + }, + { + "name": "server4", + "address": "localhost:25569", + "players": 0 + } +] +``` + +This project was created using `bun init` in bun v1.1.26. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. diff --git a/.web/docs/developers/api/typescript/bun/index.ts b/.web/docs/developers/api/typescript/bun/index.ts new file mode 100644 index 00000000..25df2dbe --- /dev/null +++ b/.web/docs/developers/api/typescript/bun/index.ts @@ -0,0 +1,15 @@ +import { createClient } from '@connectrpc/connect'; +import { createConnectTransport } from '@connectrpc/connect-node'; +import { GateService } from '@buf/minekube_gate.connectrpc_es/minekube/gate/v1/gate_service_connect'; + +const transport = createConnectTransport({ + httpVersion: '1.1', + baseUrl: 'http://localhost:8080', +}); + +async function main() { + const client = createClient(GateService, transport); + const res = await client.listServers({}); + console.log(JSON.stringify(res.servers, null, 2)); +} +void main(); diff --git a/.web/docs/developers/api/typescript/bun/package.json b/.web/docs/developers/api/typescript/bun/package.json new file mode 100644 index 00000000..a0d676bc --- /dev/null +++ b/.web/docs/developers/api/typescript/bun/package.json @@ -0,0 +1,12 @@ +{ + "name": "bun", + "module": "index.ts", + "type": "module", + "devDependencies": { + "@types/bun": "latest" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "dependencies": { "@buf/minekube_gate.connectrpc_es": "^1.6.1-20241118150055-50fffb007499.1", "@bufbuild/buf": "^1.47.2", "@bufbuild/protobuf": "^1.0.0", "@connectrpc/connect": "^1.0.0", "@connectrpc/connect-node": "^1.6.1" } +} diff --git a/.web/docs/developers/api/typescript/bun/tsconfig.json b/.web/docs/developers/api/typescript/bun/tsconfig.json new file mode 100644 index 00000000..238655f2 --- /dev/null +++ b/.web/docs/developers/api/typescript/bun/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + // Enable latest features + "lib": ["ESNext", "DOM"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +} diff --git a/.web/docs/developers/api/typescript/index.md b/.web/docs/developers/api/typescript/index.md new file mode 100644 index 00000000..77a94d7f --- /dev/null +++ b/.web/docs/developers/api/typescript/index.md @@ -0,0 +1,122 @@ +# TypeScript/JavaScript Guide + +Gate's TypeScript/JavaScript client libraries allow you to interact with Gate's API using your preferred runtime environment. This guide covers installation and usage across different JavaScript runtimes. + +## Installation + +Choose your preferred runtime environment: + + + +## Quick Example + +Here's a simple example of using the Gate client to list servers: + +```typescript +import { createGateClient } from '@buf/minekube_gate.connect-web/minekube/gate/v1/gate_service_connect'; +import { createConnectTransport } from '@connectrpc/connect-web'; + +// Create a client +const transport = createConnectTransport({ + baseUrl: 'http://localhost:8080', +}); +const client = createGateClient(transport); + +// List all servers +const response = await client.listServers({}); +console.log('Servers:', response.servers); + +// Get a player by username +const player = await client.getPlayer({ username: 'Notch' }); +console.log('Player:', player); +``` + +## Features + +- **Type Safety**: Full TypeScript support with generated types +- **Modern APIs**: Promise-based async/await API +- **Cross-Platform**: Works in Node.js, Deno, Bun, and browsers +- **Efficient**: Uses Protocol Buffers for efficient data transfer +- **Secure**: HTTPS support with customizable transport options + +## Common Use Cases + +- Building admin panels and dashboards +- Creating Discord bots +- Automating server management +- Developing custom monitoring tools +- Integration with existing TypeScript/JavaScript applications + + diff --git a/.web/docs/developers/api/typescript/node/.npmrc b/.web/docs/developers/api/typescript/node/.npmrc new file mode 100644 index 00000000..c599297d --- /dev/null +++ b/.web/docs/developers/api/typescript/node/.npmrc @@ -0,0 +1 @@ +@buf:registry=https://buf.build/gen/npm/v1/ diff --git a/.web/docs/developers/api/typescript/node/index.md b/.web/docs/developers/api/typescript/node/index.md new file mode 100644 index 00000000..4a80c1ae --- /dev/null +++ b/.web/docs/developers/api/typescript/node/index.md @@ -0,0 +1,89 @@ +# Node.js + +You can use the following `.npmrc` to install the dependencies from the `buf.build` registry. + +::: code-group + +```toml [.npmrc] + +``` + +::: + +or using `pnpm`: + +```bash +pnpm config set @buf:registry https://buf.build/gen/npm/v1/ +``` + +To install dependencies: + +```bash +bun add @buf/minekube_gate.connectrpc_es@latest +``` + +Refer to the [ConnectRPC](https://connectrpc.com/docs/node/using-clients) documentation for more information on how to use ConnectRPC with TypeScript on server side. + +::: tip Browser support + +To use the Gate API in the browser, check out the [Web](/developers/api/typescript/web/) documentation. + +::: + +::: code-group + +```ts [index.js] + +``` + +::: + +::: warning + +Note that we had to append `.js` to the import path in line 3 due Node.js requiring `.js` for CommonJS modules, other than in [Bun](/developers/api/typescript/bun/). + +```ts +import { GateService } from '@buf/minekube_gate.connectrpc_es/minekube/gate/v1/gate_service_connect.js'; +``` + +::: + +## Sample project + +This sample project is located in the [`docs/developers/api/typescript/node`](https://github.com/minekube/gate/tree/main/.web/docs/developers/api/typescript/node) directory. + +To install dependencies: + +```bash +pnpm install +``` + +To run: + +```bash +node --experimental-strip-types index.ts +[ + { + "name": "server1", + "address": "localhost:25566", + "players": 0 + }, + { + "name": "server2", + "address": "localhost:25567", + "players": 0 + }, + { + "name": "server3", + "address": "localhost:25568", + "players": 0 + }, + { + "name": "server4", + "address": "localhost:25569", + "players": 0 + } +] +``` + +This project was created using `pnpm init` in pnpm v9.5.0. [pnpm](https://pnpm.io) is a fast, disk space efficient package manager. diff --git a/.web/docs/developers/api/typescript/node/index.ts b/.web/docs/developers/api/typescript/node/index.ts new file mode 100644 index 00000000..9a210e90 --- /dev/null +++ b/.web/docs/developers/api/typescript/node/index.ts @@ -0,0 +1,15 @@ +import { createClient } from '@connectrpc/connect'; +import { createConnectTransport } from '@connectrpc/connect-node'; +import { GateService } from '@buf/minekube_gate.connectrpc_es/minekube/gate/v1/gate_service_connect.js'; + +const transport = createConnectTransport({ + httpVersion: '1.1', + baseUrl: 'http://localhost:8080', +}); + +async function main() { + const client = createClient(GateService, transport); + const res = await client.listServers({}); + console.log(JSON.stringify(res.servers, null, 2)); +} +void main(); diff --git a/.web/docs/developers/api/typescript/node/package.json b/.web/docs/developers/api/typescript/node/package.json new file mode 100644 index 00000000..a3f69863 --- /dev/null +++ b/.web/docs/developers/api/typescript/node/package.json @@ -0,0 +1,16 @@ +{ + "name": "node", + "module": "index.ts", + "type": "module", + "devDependencies": {}, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "dependencies": { + "@buf/minekube_gate.connectrpc_es": "^1.6.1-20241118150055-50fffb007499.1", + "@bufbuild/buf": "^1.47.2", + "@bufbuild/protobuf": "^1.0.0", + "@connectrpc/connect": "^1.0.0", + "@connectrpc/connect-node": "^1.6.1" + } +} diff --git a/.web/docs/developers/api/typescript/node/pnpm-lock.yaml b/.web/docs/developers/api/typescript/node/pnpm-lock.yaml new file mode 100644 index 00000000..35a63ec8 --- /dev/null +++ b/.web/docs/developers/api/typescript/node/pnpm-lock.yaml @@ -0,0 +1,179 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@buf/minekube_gate.connectrpc_es': + specifier: ^1.6.1-20241118150055-50fffb007499.1 + version: 1.6.1-20241118150055-50fffb007499.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.6.1(@bufbuild/protobuf@1.10.0)) + '@bufbuild/buf': + specifier: ^1.47.2 + version: 1.47.2 + '@bufbuild/protobuf': + specifier: ^1.0.0 + version: 1.10.0 + '@connectrpc/connect': + specifier: ^1.0.0 + version: 1.6.1(@bufbuild/protobuf@1.10.0) + '@connectrpc/connect-node': + specifier: ^1.6.1 + version: 1.6.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.6.1(@bufbuild/protobuf@1.10.0)) + typescript: + specifier: ^5.0.0 + version: 5.6.3 + +packages: + + '@buf/minekube_gate.bufbuild_es@1.10.0-20241118150055-50fffb007499.1': + resolution: {tarball: https://buf.build/gen/npm/v1/@buf/minekube_gate.bufbuild_es/-/minekube_gate.bufbuild_es-1.10.0-20241118150055-50fffb007499.1.tgz} + peerDependencies: + '@bufbuild/protobuf': ^1.10.0 + + '@buf/minekube_gate.connectrpc_es@1.6.1-20241118150055-50fffb007499.1': + resolution: {tarball: https://buf.build/gen/npm/v1/@buf/minekube_gate.connectrpc_es/-/minekube_gate.connectrpc_es-1.6.1-20241118150055-50fffb007499.1.tgz} + peerDependencies: + '@connectrpc/connect': ^1.6.1 + + '@bufbuild/buf-darwin-arm64@1.47.2': + resolution: {integrity: sha512-74WerFn06y+azgVfsnzhfbI5wla/OLPDnIvaNJBWHaqya/3bfascJkDylW2GVNHmwG1K/cscpmcc/RJPaO7ntQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@bufbuild/buf-darwin-x64@1.47.2': + resolution: {integrity: sha512-adAiOacOQe8Ym/YXPCEiq9mrPeKRmDtF2TgqPWTcDy6mF7TqR7hMJINkEEuMd1EeACmXnzMOnXlm9ICtvdYgPg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@bufbuild/buf-linux-aarch64@1.47.2': + resolution: {integrity: sha512-52vY+Owffr5diw2PyfQJqH+Fld6zW6NhNZak4zojvc2MjZKubWM0TfNyM9jXz2YrwyB+cyxkabE60nBI80m37w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@bufbuild/buf-linux-armv7@1.47.2': + resolution: {integrity: sha512-g9KtpObDeHZ/VG/0b5ZCieOao7L/WYZ0fPqFSs4N07D3APgEDhJG6vLyUcDgJMDgyLcgkNjNz0+XdYQb/tXyQw==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@bufbuild/buf-linux-x64@1.47.2': + resolution: {integrity: sha512-MODCK2BzD1Mgoyr+5Sp8xA8qMNdytj8hYheyhA5NnCGTkQf8sfqAjpBSAAmKk6Zar8HOlVXML6tzE/ioDFFGwQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@bufbuild/buf-win32-arm64@1.47.2': + resolution: {integrity: sha512-563YKYWJl3LrCY3G3+zuhb8HwOs6DzWslwGPFkKV2hwHyWyvd1DR1JjiLvw9zX64IKNctQ0HempSqc3kcboaqQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@bufbuild/buf-win32-x64@1.47.2': + resolution: {integrity: sha512-Sqcdv7La2xBDh3bTdEYb2f4UTMMqCcYe/D0RELhvQ5wDn6I35V3/2YT1OF5fRuf0BZLCo0OdO37S9L47uHSz2g==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@bufbuild/buf@1.47.2': + resolution: {integrity: sha512-glY5kCAoO4+a7HvDb+BLOdoHSdCk4mdXdkp53H8JFz7maOnkxCiHHXgRX+taFyEu25N8ybn7NjZFrZSdRwq2sA==} + engines: {node: '>=12'} + hasBin: true + + '@bufbuild/protobuf@1.10.0': + resolution: {integrity: sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==} + + '@connectrpc/connect-node@1.6.1': + resolution: {integrity: sha512-DxcD1wsF/aX9GegjAtl7VbpiZNjVJozy87VbaFoN6AF0Ln1Q757r5dgV59Gz0wmlk5f17txUsrEr1f2inlnnAg==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@bufbuild/protobuf': ^1.10.0 + '@connectrpc/connect': 1.6.1 + + '@connectrpc/connect@1.6.1': + resolution: {integrity: sha512-KchMDNtU4CDTdkyf0qG7ugJ6qHTOR/aI7XebYn3OTCNagaDYWiZUVKgRgwH79yeMkpNgvEUaXSK7wKjaBK9b/Q==} + peerDependencies: + '@bufbuild/protobuf': ^1.10.0 + + '@fastify/busboy@2.1.1': + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} + + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + engines: {node: '>=14.17'} + hasBin: true + + undici@5.28.4: + resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} + engines: {node: '>=14.0'} + +snapshots: + + '@buf/minekube_gate.bufbuild_es@1.10.0-20241118150055-50fffb007499.1(@bufbuild/protobuf@1.10.0)': + dependencies: + '@bufbuild/protobuf': 1.10.0 + + '@buf/minekube_gate.connectrpc_es@1.6.1-20241118150055-50fffb007499.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.6.1(@bufbuild/protobuf@1.10.0))': + dependencies: + '@buf/minekube_gate.bufbuild_es': 1.10.0-20241118150055-50fffb007499.1(@bufbuild/protobuf@1.10.0) + '@connectrpc/connect': 1.6.1(@bufbuild/protobuf@1.10.0) + transitivePeerDependencies: + - '@bufbuild/protobuf' + + '@bufbuild/buf-darwin-arm64@1.47.2': + optional: true + + '@bufbuild/buf-darwin-x64@1.47.2': + optional: true + + '@bufbuild/buf-linux-aarch64@1.47.2': + optional: true + + '@bufbuild/buf-linux-armv7@1.47.2': + optional: true + + '@bufbuild/buf-linux-x64@1.47.2': + optional: true + + '@bufbuild/buf-win32-arm64@1.47.2': + optional: true + + '@bufbuild/buf-win32-x64@1.47.2': + optional: true + + '@bufbuild/buf@1.47.2': + optionalDependencies: + '@bufbuild/buf-darwin-arm64': 1.47.2 + '@bufbuild/buf-darwin-x64': 1.47.2 + '@bufbuild/buf-linux-aarch64': 1.47.2 + '@bufbuild/buf-linux-armv7': 1.47.2 + '@bufbuild/buf-linux-x64': 1.47.2 + '@bufbuild/buf-win32-arm64': 1.47.2 + '@bufbuild/buf-win32-x64': 1.47.2 + + '@bufbuild/protobuf@1.10.0': {} + + '@connectrpc/connect-node@1.6.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.6.1(@bufbuild/protobuf@1.10.0))': + dependencies: + '@bufbuild/protobuf': 1.10.0 + '@connectrpc/connect': 1.6.1(@bufbuild/protobuf@1.10.0) + undici: 5.28.4 + + '@connectrpc/connect@1.6.1(@bufbuild/protobuf@1.10.0)': + dependencies: + '@bufbuild/protobuf': 1.10.0 + + '@fastify/busboy@2.1.1': {} + + typescript@5.6.3: {} + + undici@5.28.4: + dependencies: + '@fastify/busboy': 2.1.1 diff --git a/.web/docs/developers/api/typescript/web/.npmrc b/.web/docs/developers/api/typescript/web/.npmrc new file mode 100644 index 00000000..c599297d --- /dev/null +++ b/.web/docs/developers/api/typescript/web/.npmrc @@ -0,0 +1 @@ +@buf:registry=https://buf.build/gen/npm/v1/ diff --git a/.web/docs/developers/api/typescript/web/index.md b/.web/docs/developers/api/typescript/web/index.md new file mode 100644 index 00000000..38b8f0b3 --- /dev/null +++ b/.web/docs/developers/api/typescript/web/index.md @@ -0,0 +1,89 @@ +# Web + +You can use the following `.npmrc` to install the dependencies from the `buf.build` registry. + +::: code-group + +```toml [.npmrc] + +``` + +::: + +or using `pnpm`: + +```bash +pnpm config set @buf:registry https://buf.build/gen/npm/v1/ +``` + +To install dependencies: + +```bash +bun add @buf/minekube_gate.connectrpc_es@latest +``` + +Refer to the [ConnectRPC](https://connectrpc.com/docs/web/using-clients) documentation for more information on how to use ConnectRPC with TypeScript on browser side. + +::: tip Browser support + +To use the Gate API in the browser, check out the [Web](/developers/api/typescript/web/) documentation. + +::: + +::: code-group + +```ts [index.js] + +``` + +::: + +::: warning + +Note that we had to append `.js` to the import path in line 3 due Node.js requiring `.js` for CommonJS modules, other than in [Bun](/developers/api/typescript/bun/). + +```ts +import { GateService } from '@buf/minekube_gate.connectrpc_es/minekube/gate/v1/gate_service_connect.js'; +``` + +::: + +## Sample project + +This sample project is located in the [`docs/developers/api/typescript/node`](https://github.com/minekube/gate/tree/main/.web/docs/developers/api/typescript/node) directory. + +To install dependencies: + +```bash +pnpm install +``` + +To run: + +```bash +node --experimental-strip-types index.ts +[ + { + "name": "server1", + "address": "localhost:25566", + "players": 0 + }, + { + "name": "server2", + "address": "localhost:25567", + "players": 0 + }, + { + "name": "server3", + "address": "localhost:25568", + "players": 0 + }, + { + "name": "server4", + "address": "localhost:25569", + "players": 0 + } +] +``` + +This project was created using `pnpm init` in pnpm v9.5.0. [pnpm](https://pnpm.io) is a fast, disk space efficient package manager. diff --git a/.web/docs/developers/api/typescript/web/index.ts b/.web/docs/developers/api/typescript/web/index.ts new file mode 100644 index 00000000..2c19af6e --- /dev/null +++ b/.web/docs/developers/api/typescript/web/index.ts @@ -0,0 +1,14 @@ +import { createClient } from '@connectrpc/connect'; +import { createConnectTransport } from '@connectrpc/connect-web'; +import { GateService } from '@buf/minekube_gate.connectrpc_es/minekube/gate/v1/gate_service_connect.js'; + +const transport = createConnectTransport({ + baseUrl: 'http://localhost:8080', +}); + +async function main() { + const client = createClient(GateService, transport); + const res = await client.listServers({}); + console.log(JSON.stringify(res.servers, null, 2)); +} +void main(); diff --git a/.web/docs/developers/api/typescript/web/package.json b/.web/docs/developers/api/typescript/web/package.json new file mode 100644 index 00000000..09ea406e --- /dev/null +++ b/.web/docs/developers/api/typescript/web/package.json @@ -0,0 +1,15 @@ +{ + "name": "node", + "module": "index.ts", + "type": "module", + "peerDependencies": { + "typescript": "^5.0.0" + }, + "dependencies": { + "@buf/minekube_gate.connectrpc_es": "^1.6.1-20241118150055-50fffb007499.1", + "@bufbuild/buf": "^1.47.2", + "@bufbuild/protobuf": "^1.0.0", + "@connectrpc/connect": "^1.0.0", + "@connectrpc/connect-web": "^1.6.1" + } +} diff --git a/.web/docs/developers/api/typescript/web/pnpm-lock.yaml b/.web/docs/developers/api/typescript/web/pnpm-lock.yaml new file mode 100644 index 00000000..6ca63b7b --- /dev/null +++ b/.web/docs/developers/api/typescript/web/pnpm-lock.yaml @@ -0,0 +1,163 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@buf/minekube_gate.connectrpc_es': + specifier: ^1.6.1-20241118150055-50fffb007499.1 + version: 1.6.1-20241118150055-50fffb007499.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.6.1(@bufbuild/protobuf@1.10.0)) + '@bufbuild/buf': + specifier: ^1.47.2 + version: 1.47.2 + '@bufbuild/protobuf': + specifier: ^1.0.0 + version: 1.10.0 + '@connectrpc/connect': + specifier: ^1.0.0 + version: 1.6.1(@bufbuild/protobuf@1.10.0) + '@connectrpc/connect-web': + specifier: ^1.6.1 + version: 1.6.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.6.1(@bufbuild/protobuf@1.10.0)) + typescript: + specifier: ^5.0.0 + version: 5.6.3 + +packages: + + '@buf/minekube_gate.bufbuild_es@1.10.0-20241118150055-50fffb007499.1': + resolution: {tarball: https://buf.build/gen/npm/v1/@buf/minekube_gate.bufbuild_es/-/minekube_gate.bufbuild_es-1.10.0-20241118150055-50fffb007499.1.tgz} + peerDependencies: + '@bufbuild/protobuf': ^1.10.0 + + '@buf/minekube_gate.connectrpc_es@1.6.1-20241118150055-50fffb007499.1': + resolution: {tarball: https://buf.build/gen/npm/v1/@buf/minekube_gate.connectrpc_es/-/minekube_gate.connectrpc_es-1.6.1-20241118150055-50fffb007499.1.tgz} + peerDependencies: + '@connectrpc/connect': ^1.6.1 + + '@bufbuild/buf-darwin-arm64@1.47.2': + resolution: {integrity: sha512-74WerFn06y+azgVfsnzhfbI5wla/OLPDnIvaNJBWHaqya/3bfascJkDylW2GVNHmwG1K/cscpmcc/RJPaO7ntQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@bufbuild/buf-darwin-x64@1.47.2': + resolution: {integrity: sha512-adAiOacOQe8Ym/YXPCEiq9mrPeKRmDtF2TgqPWTcDy6mF7TqR7hMJINkEEuMd1EeACmXnzMOnXlm9ICtvdYgPg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@bufbuild/buf-linux-aarch64@1.47.2': + resolution: {integrity: sha512-52vY+Owffr5diw2PyfQJqH+Fld6zW6NhNZak4zojvc2MjZKubWM0TfNyM9jXz2YrwyB+cyxkabE60nBI80m37w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@bufbuild/buf-linux-armv7@1.47.2': + resolution: {integrity: sha512-g9KtpObDeHZ/VG/0b5ZCieOao7L/WYZ0fPqFSs4N07D3APgEDhJG6vLyUcDgJMDgyLcgkNjNz0+XdYQb/tXyQw==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@bufbuild/buf-linux-x64@1.47.2': + resolution: {integrity: sha512-MODCK2BzD1Mgoyr+5Sp8xA8qMNdytj8hYheyhA5NnCGTkQf8sfqAjpBSAAmKk6Zar8HOlVXML6tzE/ioDFFGwQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@bufbuild/buf-win32-arm64@1.47.2': + resolution: {integrity: sha512-563YKYWJl3LrCY3G3+zuhb8HwOs6DzWslwGPFkKV2hwHyWyvd1DR1JjiLvw9zX64IKNctQ0HempSqc3kcboaqQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@bufbuild/buf-win32-x64@1.47.2': + resolution: {integrity: sha512-Sqcdv7La2xBDh3bTdEYb2f4UTMMqCcYe/D0RELhvQ5wDn6I35V3/2YT1OF5fRuf0BZLCo0OdO37S9L47uHSz2g==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@bufbuild/buf@1.47.2': + resolution: {integrity: sha512-glY5kCAoO4+a7HvDb+BLOdoHSdCk4mdXdkp53H8JFz7maOnkxCiHHXgRX+taFyEu25N8ybn7NjZFrZSdRwq2sA==} + engines: {node: '>=12'} + hasBin: true + + '@bufbuild/protobuf@1.10.0': + resolution: {integrity: sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==} + + '@connectrpc/connect-web@1.6.1': + resolution: {integrity: sha512-GVfxQOmt3TtgTaKeXLS/EA2IHa3nHxwe2BCHT7X0Q/0hohM+nP5DDnIItGEjGrGdt3LTTqWqE4s70N4h+qIMlQ==} + peerDependencies: + '@bufbuild/protobuf': ^1.10.0 + '@connectrpc/connect': 1.6.1 + + '@connectrpc/connect@1.6.1': + resolution: {integrity: sha512-KchMDNtU4CDTdkyf0qG7ugJ6qHTOR/aI7XebYn3OTCNagaDYWiZUVKgRgwH79yeMkpNgvEUaXSK7wKjaBK9b/Q==} + peerDependencies: + '@bufbuild/protobuf': ^1.10.0 + + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + engines: {node: '>=14.17'} + hasBin: true + +snapshots: + + '@buf/minekube_gate.bufbuild_es@1.10.0-20241118150055-50fffb007499.1(@bufbuild/protobuf@1.10.0)': + dependencies: + '@bufbuild/protobuf': 1.10.0 + + '@buf/minekube_gate.connectrpc_es@1.6.1-20241118150055-50fffb007499.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.6.1(@bufbuild/protobuf@1.10.0))': + dependencies: + '@buf/minekube_gate.bufbuild_es': 1.10.0-20241118150055-50fffb007499.1(@bufbuild/protobuf@1.10.0) + '@connectrpc/connect': 1.6.1(@bufbuild/protobuf@1.10.0) + transitivePeerDependencies: + - '@bufbuild/protobuf' + + '@bufbuild/buf-darwin-arm64@1.47.2': + optional: true + + '@bufbuild/buf-darwin-x64@1.47.2': + optional: true + + '@bufbuild/buf-linux-aarch64@1.47.2': + optional: true + + '@bufbuild/buf-linux-armv7@1.47.2': + optional: true + + '@bufbuild/buf-linux-x64@1.47.2': + optional: true + + '@bufbuild/buf-win32-arm64@1.47.2': + optional: true + + '@bufbuild/buf-win32-x64@1.47.2': + optional: true + + '@bufbuild/buf@1.47.2': + optionalDependencies: + '@bufbuild/buf-darwin-arm64': 1.47.2 + '@bufbuild/buf-darwin-x64': 1.47.2 + '@bufbuild/buf-linux-aarch64': 1.47.2 + '@bufbuild/buf-linux-armv7': 1.47.2 + '@bufbuild/buf-linux-x64': 1.47.2 + '@bufbuild/buf-win32-arm64': 1.47.2 + '@bufbuild/buf-win32-x64': 1.47.2 + + '@bufbuild/protobuf@1.10.0': {} + + '@connectrpc/connect-web@1.6.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.6.1(@bufbuild/protobuf@1.10.0))': + dependencies: + '@bufbuild/protobuf': 1.10.0 + '@connectrpc/connect': 1.6.1(@bufbuild/protobuf@1.10.0) + + '@connectrpc/connect@1.6.1(@bufbuild/protobuf@1.10.0)': + dependencies: + '@bufbuild/protobuf': 1.10.0 + + typescript@5.6.3: {} diff --git a/buf.gen.yaml b/buf.gen.yaml index 478beb16..35ff7542 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -11,4 +11,4 @@ plugins: opt: paths=source_relative - remote: buf.build/connectrpc/go out: pkg/internal/api/gen - opt: paths=source_relative + opt: paths=source_relative \ No newline at end of file diff --git a/config.yml b/config.yml index 36bbf197..0391afd2 100644 --- a/config.yml +++ b/config.yml @@ -208,7 +208,7 @@ connect: api: # Whether to enable the API for Gate. # Default: false - enabled: false + enabled: true # The bind address to listen for API connections. # Default: localhost:8080 bind: localhost:8080 From c0430bcbcdc2b5e1dc6832a4fc93a3bb3702873a Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Mon, 18 Nov 2024 18:28:29 +0100 Subject: [PATCH 07/32] docs: remove wrong sample --- .web/docs/developers/api/typescript/index.md | 25 +------------------- 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/.web/docs/developers/api/typescript/index.md b/.web/docs/developers/api/typescript/index.md index 77a94d7f..32aab4fe 100644 --- a/.web/docs/developers/api/typescript/index.md +++ b/.web/docs/developers/api/typescript/index.md @@ -36,34 +36,11 @@ Choose your preferred runtime environment: -## Quick Example - -Here's a simple example of using the Gate client to list servers: - -```typescript -import { createGateClient } from '@buf/minekube_gate.connect-web/minekube/gate/v1/gate_service_connect'; -import { createConnectTransport } from '@connectrpc/connect-web'; - -// Create a client -const transport = createConnectTransport({ - baseUrl: 'http://localhost:8080', -}); -const client = createGateClient(transport); - -// List all servers -const response = await client.listServers({}); -console.log('Servers:', response.servers); - -// Get a player by username -const player = await client.getPlayer({ username: 'Notch' }); -console.log('Player:', player); -``` - ## Features - **Type Safety**: Full TypeScript support with generated types - **Modern APIs**: Promise-based async/await API -- **Cross-Platform**: Works in Node.js, Deno, Bun, and browsers +- **Cross-Platform**: Works in Node.js, Bun, and web browsers - **Efficient**: Uses Protocol Buffers for efficient data transfer - **Secure**: HTTPS support with customizable transport options From 899715298cbef212bd30d58eeb796524af8c7668 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Mon, 18 Nov 2024 18:29:34 +0100 Subject: [PATCH 08/32] api false by default --- config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.yml b/config.yml index 0391afd2..36bbf197 100644 --- a/config.yml +++ b/config.yml @@ -208,7 +208,7 @@ connect: api: # Whether to enable the API for Gate. # Default: false - enabled: true + enabled: false # The bind address to listen for API connections. # Default: localhost:8080 bind: localhost:8080 From 18db542eeea72e6d64754d64f16a724d7055fbb5 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Mon, 18 Nov 2024 18:31:21 +0100 Subject: [PATCH 09/32] fix cmd --- .web/docs/developers/api/typescript/web/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.web/docs/developers/api/typescript/web/index.md b/.web/docs/developers/api/typescript/web/index.md index 38b8f0b3..c3b5731a 100644 --- a/.web/docs/developers/api/typescript/web/index.md +++ b/.web/docs/developers/api/typescript/web/index.md @@ -19,7 +19,7 @@ pnpm config set @buf:registry https://buf.build/gen/npm/v1/ To install dependencies: ```bash -bun add @buf/minekube_gate.connectrpc_es@latest +pnpm add @buf/minekube_gate.connectrpc_es@latest ``` Refer to the [ConnectRPC](https://connectrpc.com/docs/web/using-clients) documentation for more information on how to use ConnectRPC with TypeScript on browser side. From ec70a3f8fabf4c77a2ca2cf3299db9d54a01858a Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Mon, 18 Nov 2024 18:34:25 +0100 Subject: [PATCH 10/32] docs: different install clis --- .../developers/api/typescript/node/index.md | 18 +++++++++++++++++- .../developers/api/typescript/web/index.md | 18 +++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/.web/docs/developers/api/typescript/node/index.md b/.web/docs/developers/api/typescript/node/index.md index 4a80c1ae..fcee8f7d 100644 --- a/.web/docs/developers/api/typescript/node/index.md +++ b/.web/docs/developers/api/typescript/node/index.md @@ -18,10 +18,26 @@ pnpm config set @buf:registry https://buf.build/gen/npm/v1/ To install dependencies: -```bash +::: code-group + +```bash [pnpm] +pnpm add @buf/minekube_gate.connectrpc_es@latest +``` + +```bash [bun] bun add @buf/minekube_gate.connectrpc_es@latest ``` +```bash [npm] +npm install @buf/minekube_gate.connectrpc_es@latest +``` + +```bash [yarn] +yarn add @buf/minekube_gate.connectrpc_es@latest +``` + +::: + Refer to the [ConnectRPC](https://connectrpc.com/docs/node/using-clients) documentation for more information on how to use ConnectRPC with TypeScript on server side. ::: tip Browser support diff --git a/.web/docs/developers/api/typescript/web/index.md b/.web/docs/developers/api/typescript/web/index.md index c3b5731a..2b59e36c 100644 --- a/.web/docs/developers/api/typescript/web/index.md +++ b/.web/docs/developers/api/typescript/web/index.md @@ -18,10 +18,26 @@ pnpm config set @buf:registry https://buf.build/gen/npm/v1/ To install dependencies: -```bash +::: code-group + +```bash [pnpm] pnpm add @buf/minekube_gate.connectrpc_es@latest ``` +```bash [bun] +bun add @buf/minekube_gate.connectrpc_es@latest +``` + +```bash [npm] +npm install @buf/minekube_gate.connectrpc_es@latest +``` + +```bash [yarn] +yarn add @buf/minekube_gate.connectrpc_es@latest +``` + +::: + Refer to the [ConnectRPC](https://connectrpc.com/docs/web/using-clients) documentation for more information on how to use ConnectRPC with TypeScript on browser side. ::: tip Browser support From 99f6eb100fe69d00ff7f5a6afba4d4550ee09146 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Mon, 18 Nov 2024 18:39:04 +0100 Subject: [PATCH 11/32] docs improve --- .web/docs/.vitepress/config.ts | 4 ++ .web/docs/developers/api/go/index.md | 5 ++ .web/docs/developers/api/index.md | 70 +++++++++++++--------------- .web/docs/developers/index.md | 6 ++- 4 files changed, 47 insertions(+), 38 deletions(-) create mode 100644 .web/docs/developers/api/go/index.md diff --git a/.web/docs/.vitepress/config.ts b/.web/docs/.vitepress/config.ts index 8b9fc346..197f264b 100644 --- a/.web/docs/.vitepress/config.ts +++ b/.web/docs/.vitepress/config.ts @@ -227,6 +227,10 @@ export default defineConfig({ }, ], }, + { + text: 'Go', + link: '/developers/api/go/', + }, { text: 'Glossary', link: '/developers/api/glossary', diff --git a/.web/docs/developers/api/go/index.md b/.web/docs/developers/api/go/index.md new file mode 100644 index 00000000..74d0e0d9 --- /dev/null +++ b/.web/docs/developers/api/go/index.md @@ -0,0 +1,5 @@ +# Go + +::: warning Go Applications +While Go applications can use this HTTP API as well, we recommend using Gate's native Go library (see [Introduction](/developers/)) as it provides the most complete and type-safe access to Gate's functionality, unless you need out-of-process execution or want to iterate and deploy updates independently from your proxy. +::: diff --git a/.web/docs/developers/api/index.md b/.web/docs/developers/api/index.md index 40a3c968..ced68651 100644 --- a/.web/docs/developers/api/index.md +++ b/.web/docs/developers/api/index.md @@ -16,45 +16,8 @@ api: ::: -## Features - -::: info Why Gate API? -The HTTP API enables you to build and deploy functionality independently from your proxy - perfect for rapid iteration without disrupting your players. -::: - -
-
-
🚀 Independent Updates
-
Ship updates without restarting Gate or disconnecting players
-
-
-
🌐 Cross-Language Support
-
Access Gate's core functionality from any programming language
-
-
-
🔌 Plugin Development
-
Build extensions and plugins in your preferred language
-
-
-
🤖 Automation
-
Automate server registration and management tasks
-
-
-
🎮 Custom Tools
-
Create administrative interfaces and management tools
-
-
-
🔄 Integration
-
Connect Gate with external systems and services
-
-
- ## Getting Started -::: warning Go Applications -While Go applications can use this HTTP API as well, we recommend using Gate's native Go library as it provides the most complete and type-safe access to Gate's functionality, unless you need out-of-process execution or want to iterate and deploy updates independently from your proxy. -::: - Gate's API definitions are hosted on [buf.build/minekube/gate](https://buf.build/minekube/gate/sdks), where you can directly pull client libraries using your preferred language's package manager:
@@ -114,6 +77,39 @@ Gate's API definitions are hosted on [buf.build/minekube/gate](https://buf.build
+## Features + +::: info Why Gate API? +The HTTP API enables you to build and deploy functionality independently from your proxy - perfect for rapid iteration without disrupting your players. +::: + +
+
+
🚀 Independent Updates
+
Ship updates without restarting Gate or disconnecting players
+
+
+
🌐 Cross-Language Support
+
Access Gate's core functionality from any programming language
+
+
+
🔌 Plugin Development
+
Build extensions and plugins in your preferred language
+
+
+
🤖 Automation
+
Automate server registration and management tasks
+
+
+
🎮 Custom Tools
+
Create administrative interfaces and management tools
+
+
+
🔄 Integration
+
Connect Gate with external systems and services
+
+
+ ::: tip Learn More To understand the key technologies used in Gate's API, check out the [Glossary](/developers/api/glossary). ::: diff --git a/.web/docs/developers/index.md b/.web/docs/developers/index.md index d54427ca..a12ebd94 100644 --- a/.web/docs/developers/index.md +++ b/.web/docs/developers/index.md @@ -9,6 +9,10 @@ _If you want to learn how to extend Gate with your own code, you are in the righ The starter template is designed to help you get started with your own Gate powered project. Fork it! 🚀 - [minekube/gate-plugin-template](https://github.com/minekube/gate-plugin-template) +## Any Language + +Go to the [API](/developers/api/) section to learn how to use Gate's API from any programming language. + ## Getting Started Gate is designed with developers in mind. @@ -35,7 +39,7 @@ func main() { return newSimpleProxy(proxy).init() // see code examples }, }) - + // Execute Gate entrypoint and block until shutdown. // We could also run gate.Start if we don't need Gate's command-line. gate.Execute() From 172efc64f52f9474b6420be1eee7c5824db1f69a Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Tue, 19 Nov 2024 14:33:22 +0100 Subject: [PATCH 12/32] docs(api): add Go --- .web/docs/.vitepress/config.ts | 50 ++++---- .web/docs/developers/api/go/go.mod | 11 ++ .web/docs/developers/api/go/go.sum | 14 +++ .web/docs/developers/api/go/index.md | 67 +++++++++- .../developers/api/go/integration-options.md | 119 ++++++++++++++++++ .web/docs/developers/api/go/main.go | 31 +++++ .web/docs/developers/api/index.md | 18 +-- .../developers/api/typescript/bun/index.md | 34 ++++- .web/docs/developers/api/typescript/index.md | 19 ++- .../developers/api/typescript/node/index.md | 2 +- .../developers/api/typescript/web/index.md | 2 +- .web/docs/developers/index.md | 6 +- 12 files changed, 326 insertions(+), 47 deletions(-) create mode 100644 .web/docs/developers/api/go/go.mod create mode 100644 .web/docs/developers/api/go/go.sum create mode 100644 .web/docs/developers/api/go/integration-options.md create mode 100644 .web/docs/developers/api/go/main.go diff --git a/.web/docs/.vitepress/config.ts b/.web/docs/.vitepress/config.ts index 197f264b..e2f889ec 100644 --- a/.web/docs/.vitepress/config.ts +++ b/.web/docs/.vitepress/config.ts @@ -201,42 +201,42 @@ export default defineConfig({ text: 'Events', link: '/developers/events', }, + ], + }, + { + text: 'HTTP API', + link: '/developers/api/', + items: [ { - text: 'HTTP API', + text: 'Getting Started', link: '/developers/api/', + }, + { + text: 'TypeScript', + link: '/developers/api/typescript/', items: [ { - text: 'Getting Started', - link: '/developers/api/', + text: 'Bun', + link: '/developers/api/typescript/bun/', }, { - text: 'TypeScript', - link: '/developers/api/typescript/', - items: [ - { - text: 'Bun', - link: '/developers/api/typescript/bun/', - }, - { - text: 'Node.js', - link: '/developers/api/typescript/node/', - }, - { - text: 'Web', - link: '/developers/api/typescript/web/', - }, - ], + text: 'Node.js', + link: '/developers/api/typescript/node/', }, { - text: 'Go', - link: '/developers/api/go/', - }, - { - text: 'Glossary', - link: '/developers/api/glossary', + text: 'Web', + link: '/developers/api/typescript/web/', }, ], }, + { + text: 'Go', + link: '/developers/api/go/', + }, + { + text: 'Glossary', + link: '/developers/api/glossary', + }, ], }, { diff --git a/.web/docs/developers/api/go/go.mod b/.web/docs/developers/api/go/go.mod new file mode 100644 index 00000000..dbffa1b0 --- /dev/null +++ b/.web/docs/developers/api/go/go.mod @@ -0,0 +1,11 @@ +module example + +go 1.23.2 + +require ( + buf.build/gen/go/minekube/gate/connectrpc/go v1.17.0-20241118150055-50fffb007499.1 + buf.build/gen/go/minekube/gate/protocolbuffers/go v1.35.2-20241118150055-50fffb007499.1 + connectrpc.com/connect v1.17.0 +) + +require google.golang.org/protobuf v1.35.2 // indirect diff --git a/.web/docs/developers/api/go/go.sum b/.web/docs/developers/api/go/go.sum new file mode 100644 index 00000000..27f9a811 --- /dev/null +++ b/.web/docs/developers/api/go/go.sum @@ -0,0 +1,14 @@ +buf.build/gen/go/minekube/gate/connectrpc/go v1.17.0-20241118150055-50fffb007499.1 h1:PuMlOYaWQWlaFIbEHYQf3/BDSP9t9sr4vIPbg6pLBSI= +buf.build/gen/go/minekube/gate/connectrpc/go v1.17.0-20241118150055-50fffb007499.1/go.mod h1:4dsv7Pyg90q6BS9Axo0HpbmoIUaFpI3jCOivdcA+luM= +buf.build/gen/go/minekube/gate/protocolbuffers/go v1.35.2-20241118150055-50fffb007499.1 h1:8PC1CKMQ003wd5wErIm76IsKcXXHbjlXt/MQ81e3P08= +buf.build/gen/go/minekube/gate/protocolbuffers/go v1.35.2-20241118150055-50fffb007499.1/go.mod h1:K6y2JBJAi5uHKdVriZl83y65fmpymf6utjiVR03NA2w= +connectrpc.com/connect v1.17.0 h1:W0ZqMhtVzn9Zhn2yATuUokDLO5N+gIuBWMOnsQrfmZk= +connectrpc.com/connect v1.17.0/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= diff --git a/.web/docs/developers/api/go/index.md b/.web/docs/developers/api/go/index.md index 74d0e0d9..37840271 100644 --- a/.web/docs/developers/api/go/index.md +++ b/.web/docs/developers/api/go/index.md @@ -1,5 +1,66 @@ -# Go +# Go Go Client -::: warning Go Applications -While Go applications can use this HTTP API as well, we recommend using Gate's native Go library (see [Introduction](/developers/)) as it provides the most complete and type-safe access to Gate's functionality, unless you need out-of-process execution or want to iterate and deploy updates independently from your proxy. +Gate offers two powerful approaches to integrate with Go applications: + + + +If you choose to use the HTTP API Client, follow along below. + +## HTTP API Client + +1. Install the required packages: + +```bash +go get buf.build/gen/go/minekube/gate/connectrpc/go@latest +go get buf.build/gen/go/minekube/gate/protocolbuffers/go@latest +``` + +2. Example usage: + +```go + +``` + +3. Run the example: + +```bash +go run . +{ + "servers": [ + { + "name": "server2", + "address": "localhost:25567" + }, + { + "name": "server3", + "address": "localhost:25568" + }, + { + "name": "server4", + "address": "localhost:25569" + }, + { + "name": "server1", + "address": "localhost:25566" + } + ] +} +``` + +This example project is located in the [`docs/developers/api/go`](https://github.com/minekube/gate/tree/main/.web/docs/developers/api/go) directory. + +::: info Learn More +For more details on using ConnectRPC with Go, check out the [ConnectRPC Documentation](https://connectrpc.com/docs/go/getting-started#make-requests). ::: + + diff --git a/.web/docs/developers/api/go/integration-options.md b/.web/docs/developers/api/go/integration-options.md new file mode 100644 index 00000000..e9b752ef --- /dev/null +++ b/.web/docs/developers/api/go/integration-options.md @@ -0,0 +1,119 @@ + + + diff --git a/.web/docs/developers/api/go/main.go b/.web/docs/developers/api/go/main.go new file mode 100644 index 00000000..e5466081 --- /dev/null +++ b/.web/docs/developers/api/go/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "context" + "encoding/json" + "log" + "net/http" + + "buf.build/gen/go/minekube/gate/connectrpc/go/minekube/gate/v1/gatev1connect" + gatev1 "buf.build/gen/go/minekube/gate/protocolbuffers/go/minekube/gate/v1" + "connectrpc.com/connect" +) + +// main is an example of how to use the ListServers method. +func main() { + ctx := context.Background() + + client := gatev1connect.NewGateServiceClient( + http.DefaultClient, + "http://localhost:8080", + ) + + req := connect.NewRequest(&gatev1.ListServersRequest{}) + res, err := client.ListServers(ctx, req) + if err != nil { + log.Fatalln("make sure Gate is running with the API enabled", err) + } + + j, _ := json.MarshalIndent(res.Msg, "", " ") + println(string(j)) +} diff --git a/.web/docs/developers/api/index.md b/.web/docs/developers/api/index.md index ced68651..d9ea764d 100644 --- a/.web/docs/developers/api/index.md +++ b/.web/docs/developers/api/index.md @@ -2,9 +2,9 @@ Gate provides a powerful API that exposes its functionality to a wide ecosystem of languages and tools. Using modern technologies like Protocol Buffers, gRPC, and ConnectRPC with schemas managed through buf.build. -::: tip Quick Start +## Quick Start + Simply enable the API in Gate's configuration, choose your preferred language's client library, and start building! -::: ::: code-group @@ -16,13 +16,13 @@ api: ::: -## Getting Started +## Official SDKs Gate's API definitions are hosted on [buf.build/minekube/gate](https://buf.build/minekube/gate/sdks), where you can directly pull client libraries using your preferred language's package manager:
- +
- +
- +
- +
- +
- +
Kotlin Kotlin diff --git a/.web/docs/developers/api/typescript/bun/index.md b/.web/docs/developers/api/typescript/bun/index.md index c60a1d95..0149d856 100644 --- a/.web/docs/developers/api/typescript/bun/index.md +++ b/.web/docs/developers/api/typescript/bun/index.md @@ -1,4 +1,4 @@ -# bun +# Bun Bun You can use the following `bunfig.toml` to install the dependencies from the `buf.build` registry. @@ -12,10 +12,28 @@ You can use the following `bunfig.toml` to install the dependencies from the `bu To install dependencies: -```bash +To install dependencies: + +::: code-group + +```bash [bun] bun add @buf/minekube_gate.connectrpc_es@latest ``` +```bash [pnpm] +pnpm add @buf/minekube_gate.connectrpc_es@latest +``` + +```bash [npm] +npm install @buf/minekube_gate.connectrpc_es@latest +``` + +```bash [yarn] +yarn add @buf/minekube_gate.connectrpc_es@latest +``` + +::: + Refer to the [ConnectRPC](https://connectrpc.com/docs/node/using-clients) documentation for more information on how to use ConnectRPC with TypeScript on server side. ::: tip Browser support @@ -71,3 +89,15 @@ bun run index.ts ``` This project was created using `bun init` in bun v1.1.26. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. + + diff --git a/.web/docs/developers/api/typescript/index.md b/.web/docs/developers/api/typescript/index.md index 32aab4fe..d2e99ca4 100644 --- a/.web/docs/developers/api/typescript/index.md +++ b/.web/docs/developers/api/typescript/index.md @@ -1,4 +1,4 @@ -# TypeScript/JavaScript Guide +# TypeScript TypeScript Guide Gate's TypeScript/JavaScript client libraries allow you to interact with Gate's API using your preferred runtime environment. This guide covers installation and usage across different JavaScript runtimes. @@ -17,7 +17,7 @@ Choose your preferred runtime environment:
- +
- +
Web Web @@ -90,10 +90,19 @@ Choose your preferred runtime environment: } .tech-icon { - width: 24px; - height: 24px; + width: 32px; + height: 32px; display: inline-block; vertical-align: middle; + margin-right: 12px; + position: relative; + top: -2px; +} + +.vp-feature-small .tech-icon { + width: 24px; + height: 24px; margin-right: 8px; + top: 0; } diff --git a/.web/docs/developers/api/typescript/node/index.md b/.web/docs/developers/api/typescript/node/index.md index fcee8f7d..3d1d10e3 100644 --- a/.web/docs/developers/api/typescript/node/index.md +++ b/.web/docs/developers/api/typescript/node/index.md @@ -1,4 +1,4 @@ -# Node.js +# Node.js Node.js You can use the following `.npmrc` to install the dependencies from the `buf.build` registry. diff --git a/.web/docs/developers/api/typescript/web/index.md b/.web/docs/developers/api/typescript/web/index.md index 2b59e36c..cec11e11 100644 --- a/.web/docs/developers/api/typescript/web/index.md +++ b/.web/docs/developers/api/typescript/web/index.md @@ -1,4 +1,4 @@ -# Web +# Web Web You can use the following `.npmrc` to install the dependencies from the `buf.build` registry. diff --git a/.web/docs/developers/index.md b/.web/docs/developers/index.md index a12ebd94..65432562 100644 --- a/.web/docs/developers/index.md +++ b/.web/docs/developers/index.md @@ -11,7 +11,11 @@ Fork it! 🚀 - [minekube/gate-plugin-template](https://github.com/minekube/gate ## Any Language -Go to the [API](/developers/api/) section to learn how to use Gate's API from any programming language. +Go to the [API](/developers/api/) 🌐 section to learn how to use Gate's API from any programming language. + +## Integration Options + + ## Getting Started From aed2a09129a3c4ae88e8a74ae869e6eb0f521221 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Tue, 19 Nov 2024 15:08:30 +0100 Subject: [PATCH 13/32] docs(api): add java --- .web/docs/.vitepress/config.ts | 4 + .web/docs/developers/api/java/index.md | 140 ++++++++++++++++++ .web/docs/developers/api/java/pom.xml | 66 +++++++++ .../java/src/main/java/com/example/Main.java | 32 ++++ 4 files changed, 242 insertions(+) create mode 100644 .web/docs/developers/api/java/index.md create mode 100644 .web/docs/developers/api/java/pom.xml create mode 100644 .web/docs/developers/api/java/src/main/java/com/example/Main.java diff --git a/.web/docs/.vitepress/config.ts b/.web/docs/.vitepress/config.ts index e2f889ec..cebf8772 100644 --- a/.web/docs/.vitepress/config.ts +++ b/.web/docs/.vitepress/config.ts @@ -233,6 +233,10 @@ export default defineConfig({ text: 'Go', link: '/developers/api/go/', }, + { + text: 'Java', + link: '/developers/api/java/', + }, { text: 'Glossary', link: '/developers/api/glossary', diff --git a/.web/docs/developers/api/java/index.md b/.web/docs/developers/api/java/index.md new file mode 100644 index 00000000..a3cac6d6 --- /dev/null +++ b/.web/docs/developers/api/java/index.md @@ -0,0 +1,140 @@ +# Java Java + +Gate provides a Java API for integrating with your Java applications using gRPC. You can use the API to interact with Gate programmatically. + +## Installation + +First, configure your package manager to add the Buf registry. You only need to do this once: + +::: code-group + +```xml [Maven] + + + + Buf Maven Repository + buf + https://buf.build/gen/maven + + true + + + false + + + +``` + +```kotlin [Gradle (Kotlin)] +// build.gradle.kts +repositories { + mavenCentral() + maven { + name = "buf" + url = uri("https://buf.build/gen/maven") + } +} +``` + +```groovy [Gradle (Groovy)] +// build.gradle +repositories { + mavenCentral() + maven { + name = 'buf' + url 'https://buf.build/gen/maven' + } +} +``` + +::: + +Then add the dependencies: + +::: warning Latest Version Check +Make sure to check [buf.build/minekube/gate/sdks](https://buf.build/minekube/gate/sdks) for the latest versions of the dependencies. +::: + +::: code-group + +```xml [Maven] + + + + build.buf.gen + minekube_gate_protocolbuffers_java + 28.3.0.2.20241118150055.50fffb007499 + + + build.buf.gen + minekube_gate_grpc_java + 1.68.1.1.20241118150055.50fffb007499 + + +``` + +```kotlin [Gradle (Kotlin)] +dependencies { + // Check latest version at https://buf.build/minekube/gate/sdks + implementation("build.buf.gen:minekube_gate_protocolbuffers_java:28.3.0.2.20241118150055.50fffb007499") + implementation("build.buf.gen:minekube_gate_grpc_java:1.68.1.1.20241118150055.50fffb007499") +} +``` + +```groovy [Gradle (Groovy)] +dependencies { + // Check latest version at https://buf.build/minekube/gate/sdks + implementation 'build.buf.gen:minekube_gate_protocolbuffers_java:28.3.0.2.20241118150055.50fffb007499' + implementation 'build.buf.gen:minekube_gate_grpc_java:1.68.1.1.20241118150055.50fffb007499' +} +``` + +::: + +## Usage Example + +Here's a basic example of using the Gate Java API to connect to Gate and list servers: + +```java + +``` + +## Running the Example + +1. Run Gate with the API enabled +2. Navigate to the [docs/developers/api/java](https://github.com/minekube/gate/tree/main/.web/docs/developers/api/java) directory +3. Run the following commands: + +```bash +mvn compile +mvn exec:java -Dexec.mainClass="com.example.Main" + +servers { + name: "server3" + address: "localhost:25568" +} +servers { + name: "server4" + address: "localhost:25569" +} +servers { + name: "server1" + address: "localhost:25566" +} +servers { + name: "server2" + address: "localhost:25567" +} +``` + + diff --git a/.web/docs/developers/api/java/pom.xml b/.web/docs/developers/api/java/pom.xml new file mode 100644 index 00000000..4b94d635 --- /dev/null +++ b/.web/docs/developers/api/java/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + com.example + gate-example + 1.0-SNAPSHOT + + + 11 + 11 + UTF-8 + + + + + Buf Maven Repository + buf + https://buf.build/gen/maven + + true + + + false + + + + + + + + build.buf.gen + minekube_gate_protocolbuffers_java + 28.3.0.2.20241118150055.50fffb007499 + + + build.buf.gen + minekube_gate_grpc_java + 1.68.1.1.20241118150055.50fffb007499 + + + + io.grpc + grpc-netty-shaded + 1.68.1 + + + io.grpc + grpc-protobuf + 1.68.1 + + + io.grpc + grpc-stub + 1.68.1 + + + + com.google.protobuf + protobuf-java + 4.28.3 + + + \ No newline at end of file diff --git a/.web/docs/developers/api/java/src/main/java/com/example/Main.java b/.web/docs/developers/api/java/src/main/java/com/example/Main.java new file mode 100644 index 00000000..99b8d174 --- /dev/null +++ b/.web/docs/developers/api/java/src/main/java/com/example/Main.java @@ -0,0 +1,32 @@ +package com.example; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import build.buf.gen.minekube.gate.v1.*; + +public class Main { + public static void main(String[] args) { + try { + // Create a gRPC channel + ManagedChannel channel = ManagedChannelBuilder + .forAddress("localhost", 8080) + .usePlaintext() + .build(); + + // Create a blocking stub + GateServiceGrpc.GateServiceBlockingStub stub = GateServiceGrpc.newBlockingStub(channel); + + // List all servers + ListServersResponse response = stub.listServers(ListServersRequest.getDefaultInstance()); + + // Print protobuf response + System.out.println(response); + + // Shutdown the channel + channel.shutdown(); + } catch (Exception e) { + System.err.println("Make sure Gate is running with the API enabled"); + e.printStackTrace(); + } + } +} From 99a4e9403f3dabfd96f9c07bae7954adba9085a9 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Tue, 19 Nov 2024 15:54:55 +0100 Subject: [PATCH 14/32] docs(api): add kotllin --- .web/docs/.vitepress/config.ts | 4 + .../developers/api/kotlin/build.gradle.kts | 51 +++++ .web/docs/developers/api/kotlin/index.md | 207 ++++++++++++++++++ .../developers/api/kotlin/settings.gradle.kts | 1 + .../com/example/connect/ConnectExample.kt | 38 ++++ .../kotlin/com/example/grpc/GrpcExample.kt | 30 +++ 6 files changed, 331 insertions(+) create mode 100644 .web/docs/developers/api/kotlin/build.gradle.kts create mode 100644 .web/docs/developers/api/kotlin/index.md create mode 100644 .web/docs/developers/api/kotlin/settings.gradle.kts create mode 100644 .web/docs/developers/api/kotlin/src/main/kotlin/com/example/connect/ConnectExample.kt create mode 100644 .web/docs/developers/api/kotlin/src/main/kotlin/com/example/grpc/GrpcExample.kt diff --git a/.web/docs/.vitepress/config.ts b/.web/docs/.vitepress/config.ts index cebf8772..b3e046f4 100644 --- a/.web/docs/.vitepress/config.ts +++ b/.web/docs/.vitepress/config.ts @@ -237,6 +237,10 @@ export default defineConfig({ text: 'Java', link: '/developers/api/java/', }, + { + text: 'Kotlin', + link: '/developers/api/kotlin/', + }, { text: 'Glossary', link: '/developers/api/glossary', diff --git a/.web/docs/developers/api/kotlin/build.gradle.kts b/.web/docs/developers/api/kotlin/build.gradle.kts new file mode 100644 index 00000000..bf10bc3b --- /dev/null +++ b/.web/docs/developers/api/kotlin/build.gradle.kts @@ -0,0 +1,51 @@ +plugins { + kotlin("jvm") version "1.9.21" + application +} + +repositories { + mavenCentral() + maven { + name = "buf" + url = uri("https://buf.build/gen/maven") + } +} + +val grpcVersion = "1.68.1" +val grpcKotlinVersion = "1.4.1" +val connectVersion = "0.7.1" +val protobufVersion = "4.28.3" + +dependencies { + // Kotlin + implementation(kotlin("stdlib")) + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") + + // Connect-RPC + implementation("build.buf.gen:minekube_gate_connectrpc_kotlin:${connectVersion}.1.20241118150055.50fffb007499") + + // gRPC + implementation("build.buf.gen:minekube_gate_grpc_kotlin:${grpcKotlinVersion}.1.20241118150055.50fffb007499") + implementation("io.grpc:grpc-kotlin-stub:$grpcKotlinVersion") + implementation("io.grpc:grpc-protobuf:$grpcVersion") + implementation("io.grpc:grpc-netty-shaded:$grpcVersion") + + // Protobuf + implementation("com.google.protobuf:protobuf-java:$protobufVersion") +} + +// Configure multiple main classes +application { + mainClass.set("com.example.ConnectExampleKt") // Default main class +} + +// Create tasks for running each example +tasks.register("runConnect") { + classpath = sourceSets["main"].runtimeClasspath + mainClass.set("com.example.connect.ConnectExampleKt") +} + +tasks.register("runGrpc") { + classpath = sourceSets["main"].runtimeClasspath + mainClass.set("com.example.grpc.GrpcExampleKt") +} diff --git a/.web/docs/developers/api/kotlin/index.md b/.web/docs/developers/api/kotlin/index.md new file mode 100644 index 00000000..e57335b5 --- /dev/null +++ b/.web/docs/developers/api/kotlin/index.md @@ -0,0 +1,207 @@ +# Kotlin Kotlin + +Gate provides a Kotlin API for integrating with your Kotlin applications using either Connect-RPC or gRPC. You can use the API to interact with Gate programmatically. + +## Installation + +First, configure your package manager to add the Buf registry. You only need to do this once: + +::: code-group + +```kotlin [Gradle (Kotlin)] +// build.gradle.kts +repositories { + mavenCentral() + maven { + name = "buf" + url = uri("https://buf.build/gen/maven") + } +} +``` + +```groovy [Gradle (Groovy)] +// build.gradle +repositories { + mavenCentral() + maven { + name = 'buf' + url 'https://buf.build/gen/maven' + } +} +``` + +```xml [Maven] + + + + Buf Maven Repository + buf + https://buf.build/gen/maven + + true + + + false + + + +``` + +::: + +Then add the dependencies. You can choose between Connect-RPC (recommended) or gRPC: + +::: warning Latest Version Check +Make sure to check [buf.build/minekube/gate/sdks](https://buf.build/minekube/gate/sdks) for the latest versions of the dependencies. +::: + +::: code-group + +```kotlin [Gradle (Kotlin) - Connect] +dependencies { + // Connect-RPC for Kotlin (Recommended) + implementation("build.buf.gen:minekube_gate_connectrpc_kotlin:0.7.1.1.20241118150055.50fffb007499") + implementation("com.connectrpc:connect-kotlin:0.7.1") +} +``` + +```groovy [Gradle (Groovy) - Connect] +dependencies { + // Connect-RPC for Kotlin (Recommended) + implementation 'build.buf.gen:minekube_gate_connectrpc_kotlin:0.7.1.1.20241118150055.50fffb007499' + implementation 'com.connectrpc:connect-kotlin:0.7.1' +} +``` + +```xml [Maven - Connect] + + + + build.buf.gen + minekube_gate_connectrpc_kotlin + 0.7.1.1.20241118150055.50fffb007499 + + + com.connectrpc + connect-kotlin + 0.7.1 + + +``` + +```kotlin [Gradle (Kotlin) - gRPC] +dependencies { + // gRPC for Kotlin + implementation("build.buf.gen:minekube_gate_grpc_kotlin:1.4.1.1.20241118150055.50fffb007499") + implementation("io.grpc:grpc-kotlin-stub:1.4.1") + implementation("io.grpc:grpc-protobuf:1.68.1") + implementation("io.grpc:grpc-netty-shaded:1.68.1") +} +``` + +```groovy [Gradle (Groovy) - gRPC] +dependencies { + // gRPC for Kotlin + implementation 'build.buf.gen:minekube_gate_grpc_kotlin:1.4.1.1.20241118150055.50fffb007499' + implementation 'io.grpc:grpc-kotlin-stub:1.4.1' + implementation 'io.grpc:grpc-protobuf:1.68.1' + implementation 'io.grpc:grpc-netty-shaded:1.68.1' +} +``` + +```xml [Maven - gRPC] + + + + build.buf.gen + minekube_gate_grpc_kotlin + 1.4.1.1.20241118150055.50fffb007499 + + + io.grpc + grpc-kotlin-stub + 1.4.1 + + + io.grpc + grpc-protobuf + 1.68.1 + + + io.grpc + grpc-netty-shaded + 1.68.1 + + +``` + +::: + +## Usage Example + +Here's a basic example of using the Gate Kotlin API to connect to Gate and list servers: + +::: code-group + +```kotlin [Connect] + +``` + +```kotlin [gRPC] + +``` + +::: + +## Running the Example + +1. Run Gate with the API enabled +2. Navigate to the [docs/developers/api/kotlin](https://github.com/minekube/gate/tree/main/.web/docs/developers/api/kotlin) directory +3. Initialize the Gradle wrapper (only needed once): +```bash +gradle wrapper +``` + +4. Run one of the following commands: +```bash +# For Connect example (recommended) +./gradlew runConnect + +# For gRPC example +./gradlew runGrpc + +# Example output: +servers { + name: "server3" + address: "localhost:25568" +} +servers { + name: "server4" + address: "localhost:25569" +} +servers { + name: "server1" + address: "localhost:25566" +} +servers { + name: "server2" + address: "localhost:25567" +} +``` + +::: info Learn More +For more details on using ConnectRPC with Kotlin, check out the [ConnectRPC Documentation](https://connectrpc.com/docs/kotlin/using-clients). +::: + + + diff --git a/.web/docs/developers/api/kotlin/settings.gradle.kts b/.web/docs/developers/api/kotlin/settings.gradle.kts new file mode 100644 index 00000000..7ac6dce1 --- /dev/null +++ b/.web/docs/developers/api/kotlin/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "gate-example" \ No newline at end of file diff --git a/.web/docs/developers/api/kotlin/src/main/kotlin/com/example/connect/ConnectExample.kt b/.web/docs/developers/api/kotlin/src/main/kotlin/com/example/connect/ConnectExample.kt new file mode 100644 index 00000000..a767297b --- /dev/null +++ b/.web/docs/developers/api/kotlin/src/main/kotlin/com/example/connect/ConnectExample.kt @@ -0,0 +1,38 @@ +package com.example.connect + +import build.buf.gen.minekube.gate.v1.GateServiceClient +import build.buf.gen.minekube.gate.v1.ListServersRequest +import com.connectrpc.ConnectException +import com.connectrpc.ProtocolClientConfig +import com.connectrpc.extensions.GoogleJavaProtobufStrategy +import com.connectrpc.impl.ProtocolClient +import com.connectrpc.okhttp.ConnectOkHttpClient +import com.connectrpc.protocols.NetworkProtocol +import kotlinx.coroutines.runBlocking +import okhttp3.OkHttpClient + +fun main() = runBlocking { + try { + // Create a Connect client + val client = ProtocolClient( + httpClient = ConnectOkHttpClient(OkHttpClient()), + ProtocolClientConfig( + host = "http://localhost:8080", + serializationStrategy = GoogleJavaProtobufStrategy(), + networkProtocol = NetworkProtocol.CONNECT, + ), + ) + + // Create the service client + val gateService = GateServiceClient(client) + + // List all servers + val request = ListServersRequest.newBuilder().build() + val response = gateService.listServers(request) + println(response.toString()) + + } catch (e: ConnectException) { + System.err.println("Make sure Gate is running with the API enabled") + e.printStackTrace() + } +} diff --git a/.web/docs/developers/api/kotlin/src/main/kotlin/com/example/grpc/GrpcExample.kt b/.web/docs/developers/api/kotlin/src/main/kotlin/com/example/grpc/GrpcExample.kt new file mode 100644 index 00000000..a54f0576 --- /dev/null +++ b/.web/docs/developers/api/kotlin/src/main/kotlin/com/example/grpc/GrpcExample.kt @@ -0,0 +1,30 @@ +package com.example.grpc + +import io.grpc.ManagedChannelBuilder +import build.buf.gen.minekube.gate.v1.GateServiceGrpcKt +import build.buf.gen.minekube.gate.v1.ListServersRequest +import kotlinx.coroutines.runBlocking + +fun main(): Unit = runBlocking { + try { + // Create a gRPC channel + val channel = ManagedChannelBuilder + .forAddress("localhost", 8080) + .usePlaintext() + .build() + + // Create the service client + val stub = GateServiceGrpcKt.GateServiceCoroutineStub(channel) + + // List all servers + val response = stub.listServers(ListServersRequest.getDefaultInstance()) + println(response) + + // Shutdown the channel + channel.shutdown() + + } catch (e: Exception) { + System.err.println("Make sure Gate is running with the API enabled") + e.printStackTrace() + } +} From 58df013b6f551a4baa26565693e6dae16f4f3aef Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Tue, 19 Nov 2024 16:42:35 +0100 Subject: [PATCH 15/32] docs(api): add python --- .web/docs/.vitepress/config.ts | 4 + .web/docs/developers/api/java/index.md | 4 + .web/docs/developers/api/python/index.md | 148 ++++++++++++++++++ .web/docs/developers/api/python/main.py | 30 ++++ .../docs/developers/api/python/pyproject.toml | 13 ++ .web/docs/developers/api/python/uv.lock | 93 +++++++++++ 6 files changed, 292 insertions(+) create mode 100644 .web/docs/developers/api/python/index.md create mode 100644 .web/docs/developers/api/python/main.py create mode 100644 .web/docs/developers/api/python/pyproject.toml create mode 100644 .web/docs/developers/api/python/uv.lock diff --git a/.web/docs/.vitepress/config.ts b/.web/docs/.vitepress/config.ts index b3e046f4..3295aa84 100644 --- a/.web/docs/.vitepress/config.ts +++ b/.web/docs/.vitepress/config.ts @@ -229,6 +229,10 @@ export default defineConfig({ }, ], }, + { + text: 'Python', + link: '/developers/api/python/', + }, { text: 'Go', link: '/developers/api/go/', diff --git a/.web/docs/developers/api/java/index.md b/.web/docs/developers/api/java/index.md index a3cac6d6..06f24bd3 100644 --- a/.web/docs/developers/api/java/index.md +++ b/.web/docs/developers/api/java/index.md @@ -127,6 +127,10 @@ servers { } ``` +::: info Learn More +For more details on using gRPC with Java, check out the [gRPC Java Documentation](https://grpc.io/docs/languages/java/basics/). +::: + diff --git a/.web/docs/developers/api/python/main.py b/.web/docs/developers/api/python/main.py new file mode 100644 index 00000000..83e2968a --- /dev/null +++ b/.web/docs/developers/api/python/main.py @@ -0,0 +1,30 @@ +import grpc +import json +from google.protobuf import json_format +from minekube.gate.v1 import gate_service_pb2 as gatepb +from minekube.gate.v1 import gate_service_pb2_grpc as gateapi + + +def main(): + # Create a gRPC channel + channel = grpc.insecure_channel('localhost:8080') + + # Create a stub (client) + stub = gateapi.GateServiceStub(channel) + + try: + # List servers + response = stub.ListServers(gatepb.ListServersRequest()) + # Convert to JSON and print + json_response = json_format.MessageToDict(response) + print(json.dumps(json_response, indent=2)) + + except grpc.RpcError as e: + print(f"RPC failed: {e}") + + finally: + channel.close() + + +if __name__ == '__main__': + main() diff --git a/.web/docs/developers/api/python/pyproject.toml b/.web/docs/developers/api/python/pyproject.toml new file mode 100644 index 00000000..03e5dac3 --- /dev/null +++ b/.web/docs/developers/api/python/pyproject.toml @@ -0,0 +1,13 @@ +[project] +name = "python" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.13" +dependencies = [ + "minekube-gate-grpc-python>=1.68.0.1.20241118150055", + "minekube-gate-protocolbuffers-python>=28.3.0.2.20241118150055", +] + +[[tool.uv.index]] +url = "https://buf.build/gen/python" diff --git a/.web/docs/developers/api/python/uv.lock b/.web/docs/developers/api/python/uv.lock new file mode 100644 index 00000000..c729673e --- /dev/null +++ b/.web/docs/developers/api/python/uv.lock @@ -0,0 +1,93 @@ +version = 1 +requires-python = ">=3.13" + +[[package]] +name = "grpcio" +version = "1.68.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d5/da/132615afbfc722df4bba963844843a205aa298fd5f9a03fa2995e8dddf11/grpcio-1.68.0.tar.gz", hash = "sha256:7e7483d39b4a4fddb9906671e9ea21aaad4f031cdfc349fec76bdfa1e404543a", size = 12682655 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/2d/d9cbdb75dc99141705f08474e97b181034c2e53a345d94b58e3c55f4dd92/grpcio-1.68.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:fc05759ffbd7875e0ff2bd877be1438dfe97c9312bbc558c8284a9afa1d0f40e", size = 5149697 }, + { url = "https://files.pythonhosted.org/packages/6f/37/a848871a5adba8cd571fa89e8aabc40ca0c475bd78b2e645e1649b20e095/grpcio-1.68.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:15fa1fe25d365a13bc6d52fcac0e3ee1f9baebdde2c9b3b2425f8a4979fccea1", size = 11084394 }, + { url = "https://files.pythonhosted.org/packages/1f/52/b09374aab9c9c2f66627ce7de39eef41d73670aa0f75286d91dcc22a2dd8/grpcio-1.68.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:32a9cb4686eb2e89d97022ecb9e1606d132f85c444354c17a7dbde4a455e4a3b", size = 5645417 }, + { url = "https://files.pythonhosted.org/packages/01/78/ec5ad7c44d7adaf0b932fd41ce8c59a95177a8c79c947c77204600b652db/grpcio-1.68.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dba037ff8d284c8e7ea9a510c8ae0f5b016004f13c3648f72411c464b67ff2fb", size = 6291062 }, + { url = "https://files.pythonhosted.org/packages/f7/7f/7f5a1a8dc63a42b78ca930d195eb0c97aa7a09e8553bb3a07b7cf37f6bc1/grpcio-1.68.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0efbbd849867e0e569af09e165363ade75cf84f5229b2698d53cf22c7a4f9e21", size = 5906505 }, + { url = "https://files.pythonhosted.org/packages/41/7b/0b048b8ad1a09fab5f4567fba2a569fb9106c4c1bb473c009c25659542cb/grpcio-1.68.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:4e300e6978df0b65cc2d100c54e097c10dfc7018b9bd890bbbf08022d47f766d", size = 6635069 }, + { url = "https://files.pythonhosted.org/packages/5e/c5/9f0ebc9cfba8309a15a9786c953ce99eaf4e1ca2df402b3c5ecf42493bd4/grpcio-1.68.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:6f9c7ad1a23e1047f827385f4713b5b8c6c7d325705be1dd3e31fb00dcb2f665", size = 6200683 }, + { url = "https://files.pythonhosted.org/packages/ce/e1/d3eba05299d5acdae6c11d056308b885f1d1be0b328baa8233d5d139ec1d/grpcio-1.68.0-cp313-cp313-win32.whl", hash = "sha256:3ac7f10850fd0487fcce169c3c55509101c3bde2a3b454869639df2176b60a03", size = 3637301 }, + { url = "https://files.pythonhosted.org/packages/3c/c1/decb2b368a54c00a6ee815c3f610903f36432e3cb591d43369319826b05e/grpcio-1.68.0-cp313-cp313-win_amd64.whl", hash = "sha256:afbf45a62ba85a720491bfe9b2642f8761ff348006f5ef67e4622621f116b04a", size = 4390939 }, +] + +[[package]] +name = "minekube-gate-grpc-python" +version = "1.68.0.1.20241118150055+50fffb007499" +source = { registry = "https://buf.build/gen/python" } +dependencies = [ + { name = "grpcio" }, + { name = "minekube-gate-protocolbuffers-python" }, +] +wheels = [ + { url = "https://buf.build/gen/python/minekube-gate-grpc-python/minekube_gate_grpc_python-1.68.0.1.20241118150055+50fffb007499-py3-none-any.whl" }, +] + +[[package]] +name = "minekube-gate-protocolbuffers-pyi" +version = "28.3.0.2.20241118150055+50fffb007499" +source = { registry = "https://buf.build/gen/python" } +dependencies = [ + { name = "protobuf" }, + { name = "types-protobuf" }, +] +wheels = [ + { url = "https://buf.build/gen/python/minekube-gate-protocolbuffers-pyi/minekube_gate_protocolbuffers_pyi-28.3.0.2.20241118150055+50fffb007499-py3-none-any.whl" }, +] + +[[package]] +name = "minekube-gate-protocolbuffers-python" +version = "28.3.0.2.20241118150055+50fffb007499" +source = { registry = "https://buf.build/gen/python" } +dependencies = [ + { name = "minekube-gate-protocolbuffers-pyi" }, + { name = "protobuf" }, +] +wheels = [ + { url = "https://buf.build/gen/python/minekube-gate-protocolbuffers-python/minekube_gate_protocolbuffers_python-28.3.0.2.20241118150055+50fffb007499-py3-none-any.whl" }, +] + +[[package]] +name = "protobuf" +version = "5.28.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/74/6e/e69eb906fddcb38f8530a12f4b410699972ab7ced4e21524ece9d546ac27/protobuf-5.28.3.tar.gz", hash = "sha256:64badbc49180a5e401f373f9ce7ab1d18b63f7dd4a9cdc43c92b9f0b481cef7b", size = 422479 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/c5/05163fad52d7c43e124a545f1372d18266db36036377ad29de4271134a6a/protobuf-5.28.3-cp310-abi3-win32.whl", hash = "sha256:0c4eec6f987338617072592b97943fdbe30d019c56126493111cf24344c1cc24", size = 419624 }, + { url = "https://files.pythonhosted.org/packages/9c/4c/4563ebe001ff30dca9d7ed12e471fa098d9759712980cde1fd03a3a44fb7/protobuf-5.28.3-cp310-abi3-win_amd64.whl", hash = "sha256:91fba8f445723fcf400fdbe9ca796b19d3b1242cd873907979b9ed71e4afe868", size = 431464 }, + { url = "https://files.pythonhosted.org/packages/1c/f2/baf397f3dd1d3e4af7e3f5a0382b868d25ac068eefe1ebde05132333436c/protobuf-5.28.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a3f6857551e53ce35e60b403b8a27b0295f7d6eb63d10484f12bc6879c715687", size = 414743 }, + { url = "https://files.pythonhosted.org/packages/85/50/cd61a358ba1601f40e7d38bcfba22e053f40ef2c50d55b55926aecc8fec7/protobuf-5.28.3-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:3fa2de6b8b29d12c61911505d893afe7320ce7ccba4df913e2971461fa36d584", size = 316511 }, + { url = "https://files.pythonhosted.org/packages/5d/ae/3257b09328c0b4e59535e497b0c7537d4954038bdd53a2f0d2f49d15a7c4/protobuf-5.28.3-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:712319fbdddb46f21abb66cd33cb9e491a5763b2febd8f228251add221981135", size = 316624 }, + { url = "https://files.pythonhosted.org/packages/ad/c3/2377c159e28ea89a91cf1ca223f827ae8deccb2c9c401e5ca233cd73002f/protobuf-5.28.3-py3-none-any.whl", hash = "sha256:cee1757663fa32a1ee673434fcf3bf24dd54763c79690201208bafec62f19eed", size = 169511 }, +] + +[[package]] +name = "python" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "minekube-gate-grpc-python" }, + { name = "minekube-gate-protocolbuffers-python" }, +] + +[package.metadata] +requires-dist = [ + { name = "minekube-gate-grpc-python", specifier = ">=1.68.0.1.20241118150055" }, + { name = "minekube-gate-protocolbuffers-python", specifier = ">=28.3.0.2.20241118150055" }, +] + +[[package]] +name = "types-protobuf" +version = "5.28.3.20241030" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c8/d4/d186e43cfb38ecefc91315ee9193d5722a88d7a3c8eac34a3ed603377407/types-protobuf-5.28.3.20241030.tar.gz", hash = "sha256:f7e6b45845d75393fb41c0b3ce82c46d775f9771fae2097414a1dbfe5b51a988", size = 54665 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/da/c261bb44799d3f4455fc881ca342c14f5b5b23878bef568a1cdcd324e62f/types_protobuf-5.28.3.20241030-py3-none-any.whl", hash = "sha256:f3dae16adf342d4fb5bb3673cabb22549a6252e5dd66fc52d8310b1a39c64ba9", size = 68781 }, +] From cddfbcb7f7e3b24daca1c86829774fb9cbd0eb47 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Tue, 19 Nov 2024 17:10:56 +0100 Subject: [PATCH 16/32] docs(api): add rust --- .web/docs/.vitepress/config.ts | 4 + .web/docs/developers/api/rust/Cargo.lock | 976 ++++++++++++++++++++++ .web/docs/developers/api/rust/Cargo.toml | 10 + .web/docs/developers/api/rust/index.md | 106 +++ .web/docs/developers/api/rust/src/main.rs | 25 + 5 files changed, 1121 insertions(+) create mode 100644 .web/docs/developers/api/rust/Cargo.lock create mode 100644 .web/docs/developers/api/rust/Cargo.toml create mode 100644 .web/docs/developers/api/rust/index.md create mode 100644 .web/docs/developers/api/rust/src/main.rs diff --git a/.web/docs/.vitepress/config.ts b/.web/docs/.vitepress/config.ts index 3295aa84..ba80aef6 100644 --- a/.web/docs/.vitepress/config.ts +++ b/.web/docs/.vitepress/config.ts @@ -237,6 +237,10 @@ export default defineConfig({ text: 'Go', link: '/developers/api/go/', }, + { + text: 'Rust', + link: '/developers/api/rust/', + }, { text: 'Java', link: '/developers/api/java/', diff --git a/.web/docs/developers/api/rust/Cargo.lock b/.web/docs/developers/api/rust/Cargo.lock new file mode 100644 index 00000000..3a7c8323 --- /dev/null +++ b/.web/docs/developers/api/rust/Cargo.lock @@ -0,0 +1,976 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "anyhow" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "axum" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper 1.0.1", + "tower 0.5.1", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper 1.0.1", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "h2" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.6.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown 0.15.1", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "libc" +version = "0.2.164" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minekube_gate_community_neoeinstein-prost" +version = "0.4.0-20241118150055-50fffb007499.1" +source = "sparse+https://buf.build/gen/cargo/" +checksum = "d4687c4eff9beb46b13fb1f408d83e0734d9f6e7d6a19a536f5bc1633df66ec0" +dependencies = [ + "prost", + "prost-types", +] + +[[package]] +name = "minekube_gate_community_neoeinstein-tonic" +version = "0.4.1-20241118150055-50fffb007499.1" +source = "sparse+https://buf.build/gen/cargo/" +checksum = "890525679f6fcadaf589068d49c904143df9820c7dd7cf0bef666bcea82b6555" +dependencies = [ + "minekube_gate_community_neoeinstein-prost", + "tonic", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi", + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "prost-types" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4759aa0d3a6232fb8dbdb97b61de2c20047c68aca932c7ed76da9d788508d670" +dependencies = [ + "prost", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rust" +version = "0.1.0" +dependencies = [ + "minekube_gate_community_neoeinstein-prost", + "minekube_gate_community_neoeinstein-tonic", + "tokio", + "tonic", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + +[[package]] +name = "serde" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "syn" +version = "2.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + +[[package]] +name = "tokio" +version = "1.41.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-stream" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tonic" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64", + "bytes", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "prost", + "socket2", + "tokio", + "tokio-stream", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 0.1.2", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/.web/docs/developers/api/rust/Cargo.toml b/.web/docs/developers/api/rust/Cargo.toml new file mode 100644 index 00000000..876bcc1d --- /dev/null +++ b/.web/docs/developers/api/rust/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "rust" +version = "0.1.0" +edition = "2021" + +[dependencies] +minekube_gate_community_neoeinstein-prost = { version = "0.4.0-20241118150055-50fffb007499.1", registry = "buf" } +minekube_gate_community_neoeinstein-tonic = { version = "0.4.1-20241118150055-50fffb007499.1", registry = "buf" } +tokio = { version = "1.41.1", features = ["macros", "rt-multi-thread"] } +tonic = "0.12.3" diff --git a/.web/docs/developers/api/rust/index.md b/.web/docs/developers/api/rust/index.md new file mode 100644 index 00000000..f932f5b5 --- /dev/null +++ b/.web/docs/developers/api/rust/index.md @@ -0,0 +1,106 @@ +# Rust Rust Client + +Gate provides a Rust API for integrating with your Rust applications. You can use the API to interact with Gate programmatically using gRPC. + +## Environment Setup + +First, make sure you have Rust and Cargo installed. If not, install them using [rustup](https://rustup.rs/): + +```bash +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +``` + +## Registry Configuration + +1. Configure Cargo to use the Buf registry. Add the following to your `~/.cargo/config.toml`: + +```toml +[registries.buf] +index = "sparse+https://buf.build/gen/cargo/" +credential-provider = "cargo:token" +``` + +2. Configure authentication (required even for public repositories): + 1. Go to [Gate SDKs on Buf](https://buf.build/minekube/gate/sdks) + 2. Select the Rust SDK + 3. Scroll down to generate a token + 4. Use the token to authenticate: + ```bash + cargo login --registry buf "Bearer YOUR_TOKEN" + ``` + +## Installation + +Add the Gate SDK to your project: + +```bash +cargo add --registry buf minekube_gate_community_neoeinstein-prost +cargo add --registry buf minekube_gate_community_neoeinstein-tonic +cargo add tonic --features tls-roots # Enable the features we need +cargo add tokio --features macros,rt-multi-thread # Async runtime +``` + +This is the sample `Cargo.toml` file from the [`docs/developers/api/rust`](https://github.com/minekube/gate/tree/main/.web/docs/developers/api/rust) directory: + +```toml + +``` + +## Usage Example + +Here's a basic example of using the Gate Rust API to connect to Gate and list servers: + +::: code-group + +```rust [src/main.rs] + +``` + +::: + +## Running the Example + +1. Make sure Gate is running with the API enabled +2. Run the example: + +```bash +cargo run +[ + Server { + name: "server1", + address: "localhost:25566", + players: 0, + }, + Server { + name: "server2", + address: "localhost:25567", + players: 0, + }, + Server { + name: "server3", + address: "localhost:25568", + players: 0, + }, + Server { + name: "server4", + address: "localhost:25569", + players: 0, + }, +] +``` + +::: info Learn More +Refer to the [Buf Blog](https://buf.build/blog/bsr-generated-sdks-for-rust) for more information about using the generated Rust SDKs. +::: + + diff --git a/.web/docs/developers/api/rust/src/main.rs b/.web/docs/developers/api/rust/src/main.rs new file mode 100644 index 00000000..d5a63b94 --- /dev/null +++ b/.web/docs/developers/api/rust/src/main.rs @@ -0,0 +1,25 @@ +use minekube_gate_community_neoeinstein_prost::minekube::gate::v1::ListServersRequest; +use minekube_gate_community_neoeinstein_tonic::minekube::gate::v1::tonic::gate_service_client::GateServiceClient; + +fn main() -> Result<(), Box> { + // Create a runtime for async operations + let rt = tokio::runtime::Runtime::new()?; + rt.block_on(async { + // Create a gRPC channel + let channel = tonic::transport::Channel::from_static("http://localhost:8080") + .connect() + .await?; + + // Create the client + let mut client = GateServiceClient::new(channel); + + // Make the request + let request = tonic::Request::new(ListServersRequest {}); + let response = client.list_servers(request).await?; + + // Print the response + println!("{:#?}", response.get_ref().servers); + + Ok(()) + }) +} From ae1479d8f298f2baa94def6cef48f6a894fc3cc2 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Tue, 19 Nov 2024 17:23:29 +0100 Subject: [PATCH 17/32] docs enhancements --- .web/docs/.vitepress/config.ts | 8 ++++---- .web/docs/developers/api/glossary.md | 14 +++++++++++++- .web/docs/developers/api/index.md | 18 +++++++++--------- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/.web/docs/.vitepress/config.ts b/.web/docs/.vitepress/config.ts index ba80aef6..8350b25d 100644 --- a/.web/docs/.vitepress/config.ts +++ b/.web/docs/.vitepress/config.ts @@ -241,14 +241,14 @@ export default defineConfig({ text: 'Rust', link: '/developers/api/rust/', }, - { - text: 'Java', - link: '/developers/api/java/', - }, { text: 'Kotlin', link: '/developers/api/kotlin/', }, + { + text: 'Java', + link: '/developers/api/java/', + }, { text: 'Glossary', link: '/developers/api/glossary', diff --git a/.web/docs/developers/api/glossary.md b/.web/docs/developers/api/glossary.md index b4d241c7..7b4d3aad 100644 --- a/.web/docs/developers/api/glossary.md +++ b/.web/docs/developers/api/glossary.md @@ -8,7 +8,7 @@ Protocol Buffers is Google's language-neutral, platform-neutral, extensible mech ## gRPC -gRPC is a modern, open-source remote procedure call (RPC) framework that can run anywhere. It enables client and server applications to communicate transparently and makes it easier to build connected systems. gRPC uses Protocol Buffers as its interface definition language. +gRPC is a modern, open-source remote procedure call (RPC) framework that runs over HTTP/2. It enables client and server applications to communicate transparently and makes it easier to build connected systems. gRPC uses Protocol Buffers as its interface definition language and leverages HTTP/2's features like multiplexing and header compression for efficient communication. ## ConnectRPC @@ -17,3 +17,15 @@ ConnectRPC is a slim RPC framework that supports both gRPC and HTTP/1.1 JSON, ma ## buf.build buf.build is a modern Protocol Buffers ecosystem that provides tools for managing, versioning, and sharing Protocol Buffer schemas. It includes features like linting, breaking change detection, and a schema registry. Gate uses buf.build to maintain its API definitions and automatically generate client libraries in multiple programming languages. + +## HTTP/1.1 + +HTTP/1.1 is the most widely used version of the HTTP protocol that enables client-server communication on the web. Gate's API supports HTTP/1.1 through ConnectRPC, allowing for broad compatibility with web browsers and standard HTTP clients. + +## JSON (JavaScript Object Notation) + +JSON is a lightweight, text-based data interchange format that is easy for humans to read and write and easy for machines to parse and generate. While Gate primarily uses Protocol Buffers for efficiency, it also supports JSON encoding through ConnectRPC for better web compatibility. + +## SDK (Software Development Kit) + +An SDK is a collection of tools, libraries, documentation, and examples that developers use to create applications for specific platforms or programming languages. Gate provides official SDKs for multiple languages including TypeScript, Python, Go, Rust, Kotlin, and Java through buf.build. See https://buf.build/minekube/gate/sdks for more information and available SDKs. \ No newline at end of file diff --git a/.web/docs/developers/api/index.md b/.web/docs/developers/api/index.md index d9ea764d..de766024 100644 --- a/.web/docs/developers/api/index.md +++ b/.web/docs/developers/api/index.md @@ -39,15 +39,6 @@ Gate's API definitions are hosted on [buf.build/minekube/gate](https://buf.build
via pip packages
- ## Features From d7c25c8604effb448504dccdc3b90f1fdbbc6d09 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Tue, 19 Nov 2024 19:05:46 +0100 Subject: [PATCH 18/32] refine docs overall and add install scripts --- .web/docs/.vitepress/config.ts | 4 +- .web/docs/guide/config/index.md | 2 - .web/docs/guide/index.md | 184 +++++++++++++++++------ .web/docs/guide/install/binaries.md | 149 +++++++++++++++++-- .web/docs/guide/quick-start.md | 73 +++++++++- .web/docs/guide/why.md | 149 ++++++++++++++----- .web/docs/index.md | 4 +- .web/docs/public/install | 218 ++++++++++++++++++++++++++++ .web/docs/public/install.ps1 | 201 +++++++++++++++++++++++++ 9 files changed, 886 insertions(+), 98 deletions(-) create mode 100644 .web/docs/public/install create mode 100644 .web/docs/public/install.ps1 diff --git a/.web/docs/.vitepress/config.ts b/.web/docs/.vitepress/config.ts index 8350b25d..00402ce4 100644 --- a/.web/docs/.vitepress/config.ts +++ b/.web/docs/.vitepress/config.ts @@ -81,10 +81,10 @@ export default defineConfig({ }, nav: [ - { text: 'Quick Start', link: '/guide/quick-start' }, { text: 'Guide', link: '/guide/' }, { text: 'Lite mode', link: '/guide/lite' }, - { text: 'Developer Guide', link: '/developers/' }, + { text: 'Developers', link: '/developers/' }, + { text: 'API', link: '/developers/api/' }, { text: 'Config', link: '/guide/config/' }, { text: 'Downloads', link: '/guide/install/' }, { text: 'Extensions', link: '/extensions' }, diff --git a/.web/docs/guide/config/index.md b/.web/docs/guide/config/index.md index 68423aae..4ee48923 100644 --- a/.web/docs/guide/config/index.md +++ b/.web/docs/guide/config/index.md @@ -3,5 +3,3 @@ ```yaml config.yml ``` - -TODO more detailed documentation about each section diff --git a/.web/docs/guide/index.md b/.web/docs/guide/index.md index d421ee4c..3d9a47f0 100644 --- a/.web/docs/guide/index.md +++ b/.web/docs/guide/index.md @@ -1,58 +1,158 @@ - # Introduction _Gate is a modern cloud-native, open source, fast, batteries-included and secure proxy for Minecraft servers -with a focus on scalability, flexibility, multi-version support and developer friendliness._ +that focuses on scalability, flexibility, multi-version support and developer friendliness._ --- -![server list ping](/images/server-list.png) +
+ Gate server list ping example +
-Gate is a tiny [binary](install/binaries) and can run locally, in [Docker](install/docker) containers or -scale with your growing demands in a [Kubernetes](install/kubernetes)-orchestrated -production environment in the cloud. - -It replaces legacy proxies like BungeeCord but also runs alongside them. -Gate is entirely written in Go and heavily inspired by the Velocity project. - -::: tip What is Go? -Gate is written in [Go](https://go.dev/), -an easy-to-learn, fast, reliable, efficient, statically typed, compiled programming language designed at Google. -It is one of the most used languages for modern applications and one of the fastest growing programming languages -that is used by companies like Google, Microsoft, Meta, Amazon, Twitter, PayPal, Twitch, Netflix, Dropbox, Uber, Cloudflare, Docker, and many more. -::: - -## Quick Start +## What is Gate? -If you already know the concepts of a Minecraft proxy, -you can skip this page and jump to the [Quick Start](quick-start) guide. +Gate is a lightweight yet powerful Minecraft proxy that can run anywhere - from your local machine to large-scale cloud deployments: -If you are a developer checkout the [Developers Guide](/developers/). +- 🚀 Run locally as a simple [binary](install/binaries) +- 🐳 Deploy with [Docker](install/docker) containers +- ☸️ Scale infinitely in [Kubernetes](install/kubernetes) clusters -## Why do we need a Minecraft proxy? +It's designed as a modern replacement for legacy proxies like BungeeCord, while maintaining compatibility to run alongside them. Built entirely in Go and inspired by the Velocity project, Gate brings enterprise-grade performance to Minecraft server networks. -### Use-cases +::: tip Why Go? +Gate is written in [Go](https://go.dev/) - a modern, fast, and reliable programming language designed by Google. -* You want to keep players connected to the proxy to move them between your different game servers like they would change the world. -* You want to enable cross game server plugins that e.g. handle player chat events or register proxy-wide commands - broadcast messages and more. -* You want to intercept and log packets on the network traffic between players and servers - -### How does a Minecraft proxy work? - -Gate presents itself as a normal Minecraft server in the player's server list, -but once the player connects Gate forwards the connection to one of the actual -game servers (e.g. Minecraft vanilla, paper, spigot, sponge, etc.) to play the game. - -The player can be moved around the network of Minecraft servers **without** -fully disconnecting, since we want the player to stay connected (and not want -them to re-login via the server-list every time). +Go powers the world's largest platforms and is used by companies like: +Google, Microsoft, Meta, Amazon, Twitter, PayPal, Twitch, Netflix, Dropbox, Uber, Cloudflare, Docker, and many more. +::: -Therefore, Gate reads all packets sent between players (Minecraft client) and -upstream servers, logs session state changes, emits different events like -[Login, Disconnect, ServerConnect, Chat, Kick etc.](https://github.com/minekube/gate/blob/master/pkg/edition/java/proxy/events.go) -that custom plugins/code can react to. +## Quick Start -The **advantages** for using a proxy are far-reaching depending on your use-case. +Ready to jump in? Choose your path: + +- 🎮 **Server Owners**: Head to the [Quick Start](quick-start) guide +- 💻 **Developers**: Check out the [Developer Guide](/developers/) + +## Why Use a Minecraft Proxy? + +
+
+
+

🎮 Seamless Player Experience

+
    +
  • Move players between servers instantly
  • +
  • No disconnects during server switches
  • +
  • Smooth transitions between game modes
  • +
  • Single point of entry for your network
  • +
+
+
+ +
+
+

🔌 Network-Wide Features

+
    +
  • Cross-server chat systems
  • +
  • Global command handling
  • +
  • Network-wide player management
  • +
  • Unified permission systems
  • +
+
+
+ +
+
+

🔍 Advanced Monitoring

+
    +
  • Real-time packet inspection
  • +
  • Network traffic analysis
  • +
  • Performance monitoring
  • +
  • Security audit capabilities
  • +
+
+
+ + +
+

Why Gate?

+
    +
  • Minimal resource footprint (10MB RAM)
  • +
  • Minecraft 1.7 to latest support
  • +
  • Modern Go-based architecture
  • +
  • Clean, documented APIs
  • +
+
+
+
+ +### How It Works + +Gate acts as an intelligent middleware between players and your Minecraft servers: + +1. Players connect to Gate like a normal Minecraft server +2. Gate forwards connections to your actual game servers (vanilla, Paper, Spigot, etc.) +3. Players can move between servers while maintaining their connection +4. Gate monitors all network traffic and emits events for: + - Login/Logout + - Server Connections + - Chat Messages + - Player Kicks + - [And more!](https://github.com/minekube/gate/blob/master/pkg/edition/java/proxy/events.go) + +This architecture enables powerful features like load balancing, server maintenance without disconnects, and network-wide plugins. + + diff --git a/.web/docs/guide/install/binaries.md b/.web/docs/guide/install/binaries.md index 29b40565..d4ba6524 100644 --- a/.web/docs/guide/install/binaries.md +++ b/.web/docs/guide/install/binaries.md @@ -3,24 +3,155 @@ _The installation of Gate is ultra easy, NO Java needed! Gate is only a single executable file ready to run the proxy._ ---- +## Quick Install -Visit the page, -go to the Assets section at the bottom and download Gate for your operating system -Windows, macOS or Linux. +::: code-group -**Make Gate executable** +```sh [Linux/macOS] +curl -fsSL https://gate.minekube.com/install | bash -```sh console +✨ Installing Gate... +⚡ Downloading Gate 0.42.2 for darwin-arm64... +✅ Checksum verified for gate_0.42.2_darwin_arm64 +✨ Successfully installed Gate 0.42.2! +📍 Location: /Users/robin/.local/bin/gate +🚀 Run gate to start the proxy +``` + +```powershell [Windows] +powershell -c "irm https://gate.minekube.com/install.ps1 | iex" +``` + +::: + +## Manual Download + +If you prefer to download and install Gate manually: + +1. Visit the page +2. Download the appropriate binary for your system +3. Verify the SHA256 checksum (recommended) +4. Place the binary in your preferred location + +**Make Gate Executable** (Linux/macOS only) + +```sh chmod +x gate* ``` -::: tip If you do not have root access on the target system, you can still install Gate to the ~/.local/bin directory: +::: tip No Root Access? +You can still install Gate to your user directory: -```sh console +```sh mkdir -p ~/.local/bin mv gate* ~/.local/bin/gate -# and then append (or prepend) ~/.local/bin to $PATH +# Add to PATH: +export PATH="$HOME/.local/bin:$PATH" +``` + +::: + +## Installation Locations + +- **Linux/macOS**: `~/.local/bin/gate` +- **Windows**: `%LOCALAPPDATA%\Gate\bin\gate.exe` + +Both locations are in user space and don't require administrative privileges. + +## Uninstalling Gate + +To uninstall Gate, simply remove the binary: + +::: code-group + +```sh [Linux/macOS] +rm ~/.local/bin/gate +``` + +```powershell [Windows] +Remove-Item "$env:LOCALAPPDATA\Gate\bin\gate.exe" ``` ::: + +## Troubleshooting + +If you encounter any issues: + +1. **PATH not set**: + + - The scripts will provide commands to add Gate to your PATH + - Follow the on-screen instructions after installation + +2. **Checksum Verification Failed**: + + - This is a security feature ensuring the downloaded binary matches the official release + - Try running the installation again + - If it persists, please report it on our GitHub issues + +3. **Permission Denied**: + - Our scripts install to user space and shouldn't require elevated privileges + - If you see permission errors, ensure you have write access to the installation directory + +## Security Notes + +- Our installation scripts are transparent and open source +- They only download from official GitHub releases +- All binaries are verified using SHA256 checksums +- No system-wide changes are made without your permission +- Installation is contained within your user directory +- No data collection or tracking + +### What the Installation Scripts Do + +Our installation scripts are designed to be transparent and secure. Here's exactly what they do: + +#### Linux/macOS (`install`) + +1. **Safety First**: + + - Installs to user space (`~/.local/bin`) without requiring root/sudo + - Downloads only from official GitHub releases + - Verifies file integrity using SHA256 checksums + +2. **Installation Steps**: + + - Detects your OS (Linux/macOS) and architecture (amd64/arm64) + - Creates `~/.local/bin` if it doesn't exist + - Downloads the appropriate Gate binary + - Verifies the checksum to ensure file integrity + - Makes the binary executable + - Provides clear PATH setup instructions + +3. **No System Changes**: + - Only writes to your user directory + - Suggests PATH changes but doesn't modify system files + - Can be easily uninstalled by removing the binary + +#### Windows (`install.ps1`) + +1. **Safety First**: + + - Installs to user space (`%LOCALAPPDATA%\Gate\bin`) + - Downloads only from official GitHub releases + - Verifies file integrity using SHA256 checksums + +2. **Installation Steps**: + + - Detects your Windows architecture (amd64/arm64) + - Creates installation directory if it doesn't exist + - Downloads the appropriate Gate binary + - Verifies the checksum to ensure file integrity + - Provides clear PATH setup instructions + +3. **No System Changes**: + - Only writes to your user directory + - Suggests PATH changes but doesn't modify system PATH without permission + - Can be easily uninstalled by removing the binary + +### Verifying the Scripts + +Both installation scripts are open source and can be inspected: + +- Unix: [View install script](https://github.com/minekube/gate/blob/master/.web/docs/public/install) +- Windows: [View install.ps1 script](https://github.com/minekube/gate/blob/master/.web/docs/public/install.ps1) diff --git a/.web/docs/guide/quick-start.md b/.web/docs/guide/quick-start.md index bf371947..c36dac34 100644 --- a/.web/docs/guide/quick-start.md +++ b/.web/docs/guide/quick-start.md @@ -1,6 +1,7 @@ # Quick Start -_This page quickly explains how to run Gate as a Minecraft proxy for your servers._ +_This page quickly explains how to run Gate as a Minecraft proxy for your servers. +If you want to extend Gate with custom functionality, see the [Developers](/developers/) section._ --- @@ -39,3 +40,73 @@ The `servers` section defines the addresses of your Minecraft servers. and the `try` section defines the order in which players fallback to connect to. There are many more options to configure, see [Configuration](/guide/config/) for more! + +## Next Steps + + + + diff --git a/.web/docs/guide/why.md b/.web/docs/guide/why.md index 495a759f..6558893b 100644 --- a/.web/docs/guide/why.md +++ b/.web/docs/guide/why.md @@ -1,52 +1,123 @@ -# Why +# Why Gate? -_We recommend reading the [Introduction](index) if you haven't already._ +
+
+

🚀 Performance First

+
    +
  • Minimal resource footprint (10MB RAM)
  • +
  • Optimized for high throughput
  • +
  • Efficient protocol handling
  • +
  • Perfect for large networks
  • +
+
-Let's start with where we come from, the problem definition, -different parties involved and the solution space. +
+

🎮 Protocol Support

+
    +
  • Minecraft 1.7 to latest
  • +
  • Forge mod support
  • +
  • BungeeCord compatibility
  • +
  • Velocity forwarding
  • +
+
-## Advantages +
+

💻 Developer Experience

+
    +
  • Modern Go-based architecture
  • +
  • Clean, documented APIs
  • +
  • Multiple SDK options
  • +
  • Active community
  • +
+
+
-- Fast and needs less resources (CPU/Memory) leading to improved scalability -- Excellent protocol version support - - Allows newest version down to 1.7 - - Forge support (for modded servers) - - BungeeCord compatible plugin channels - - BungeeCord or Velocity's player info forwarding -- A simple API for plugins/extensions - - Extend with [your Go code](https://github.com/minekube/gate/tree/master/.examples/extend/simple-proxy) - - Or use a [script language](https://github.com/minekube/gate/issues/9) -- Perfect for Go developers - Gate and developers immensely benefit from the Go language and its wide ecosystem +## Who is Gate For? -Similar to the Minecraft proxies written in Java: BungeeCord, Waterfall and Velocity -_(where much of the knowledge comes from)_ -Gate delivers a rich interface to interact with connected players -on your cluster of Minecraft servers. +
+
+

Server Networks

+

Perfect for networks serving thousands of concurrent players with needs for custom functionality and scalability.

+
+
+

Go Developers

+

Ideal for developers who want to leverage Go's performance and ecosystem for Minecraft infrastructure.

+
+
-## Target audience +::: warning Coming from Java? +If your existing codebase is in Java or you need BungeeCord/Velocity plugins, you might want to stick with those platforms. Gate doesn't support Java plugins from SpigotMC. +::: -Gate supports small and large Minecraft networks that need to serve thousands of -concurrent players and encourages new and established Golang developers to extend Gate. +## Why Go? -Although Gate targets better performance, has more version support -(modded servers) and has a simpler API than the BungeeCord Java proxy, -and Gate lets you write extension code in the awesome Go programming language... +Gate leverages Go's strengths to deliver: -_If you already have all your code base in Java or need to -use plugins for other proxies like BungeeCord and Velocity, just stay there._ -You can't use Java plugins from SpigotMC with Gate. +- 🏃‍♂️ Fast compilation and deployment +- 🔧 Simple dependency management +- 🌐 Excellent networking capabilities +- ☁️ First-class cloud integration +- 📦 Single binary distribution -## Why not use an existing proxy written in Java? + diff --git a/.web/docs/index.md b/.web/docs/index.md index 622a5f40..373a725b 100644 --- a/.web/docs/index.md +++ b/.web/docs/index.md @@ -35,9 +35,7 @@ features: linkText: Install - icon: 🚀 title: Developer Friendly - details: - Gate is written in Go, a modern programming language that is easy to learn and - has a great ecosystem of tools and libraries. + details: Build integrations in TypeScript, Python, Go, Rust, Kotlin, or Java using our modern API with official SDKs. link: /developers/ linkText: Developers & Starter Template - icon: 🌐 diff --git a/.web/docs/public/install b/.web/docs/public/install new file mode 100644 index 00000000..4d8a441a --- /dev/null +++ b/.web/docs/public/install @@ -0,0 +1,218 @@ +#!/bin/bash +set -e + +# Colors for terminal output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Constants +REPO_OWNER="minekube" +REPO_NAME="gate" +INSTALL_DIR="${GATE_INSTALL_DIR:-$HOME/.local/bin}" +TEMP_DIR="/tmp/gate-installer" +REQUIRED_SPACE_MB=50 + +# Functions + +# Print messages with colors +print_info() { + echo -e "${GREEN}$1${NC}" +} + +print_warning() { + echo -e "${YELLOW}$1${NC}" +} + +print_error() { + echo -e "${RED}$1${NC}" +} + +# Detect system architecture +detect_arch() { + local arch + arch=$(uname -m) + case $arch in + x86_64) echo "amd64" ;; + aarch64|arm64) echo "arm64" ;; + i386|i686) echo "386" ;; + *) + print_error "Unsupported architecture: $arch" + exit 1 + ;; + esac +} + +# Detect operating system +detect_os() { + local os + os=$(uname -s) + case $os in + Linux) echo "linux" ;; + Darwin) echo "darwin" ;; + *) + print_error "Unsupported OS: $os" + exit 1 + ;; + esac +} + +# Check available disk space +check_disk_space() { + local install_dir="$1" + local available_space + + available_space=$(df -m "$install_dir" | awk 'NR==2 {print $4}') + + if [ "$available_space" -lt "$REQUIRED_SPACE_MB" ]; then + print_error "Insufficient disk space. Required: ${REQUIRED_SPACE_MB}MB, Available: ${available_space}MB" + exit 1 + fi +} + +# Download a file using curl or wget +download() { + local url="$1" + local output="$2" + + mkdir -p "$TEMP_DIR" + + if command -v curl >/dev/null; then + curl -L "$url" --output "$output" && return 0 + elif command -v wget >/dev/null; then + wget -q "$url" -O "$output" && return 0 + fi + + print_error "Failed to download from $url using curl or wget." + rm -rf "$TEMP_DIR" + return 1 +} + +# Verify the checksum of the downloaded file +verify_checksum() { + local file="$1" + local checksum_file="$2" + local filename + local expected_checksum + local actual_checksum + + filename=$(basename "$file") + expected_checksum=$(grep "$filename" "$checksum_file" | awk '{print $1}') + + if command -v sha256sum >/dev/null; then + actual_checksum=$(sha256sum "$file" | awk '{print $1}') + elif command -v shasum >/dev/null; then + actual_checksum=$(shasum -a 256 "$file" | awk '{print $1}') + else + print_warning "No SHA256 checksum tool found. Skipping verification." + return 0 + fi + + if [ "$expected_checksum" != "$actual_checksum" ]; then + print_error "Checksum verification failed for $filename." + print_error "Expected: $expected_checksum" + print_error "Actual: $actual_checksum" + rm -f "$file" "$checksum_file" + exit 1 + fi + + print_info "✅ Checksum verified for $filename" + rm -f "$checksum_file" +} + +# Get installation path +get_install_path() { + echo "$INSTALL_DIR/gate" +} + +# Update PATH for the current session +update_path_session() { + export PATH="$INSTALL_DIR:$PATH" +} + +# Add PATH permanently +add_path_permanently() { + local shell_rc + shell_rc="$HOME/.$(basename "$SHELL")rc" + + echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$shell_rc" + source "$shell_rc" +} + +# Main installation function +install_gate() { + print_info "✨ Installing Gate..." + + mkdir -p "$INSTALL_DIR" + mkdir -p "$TEMP_DIR" + + check_disk_space "$INSTALL_DIR" + + OS=$(detect_os) + ARCH=$(detect_arch) + + # Fetch the latest version from GitHub API + VERSION=$(curl -fsSL "https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/' | sed 's/^v//') + if [ -z "$VERSION" ]; then + print_error "Failed to detect the latest version." + exit 1 + fi + + INSTALL_PATH=$(get_install_path) + + # Inform if updating + if [ -f "$INSTALL_PATH" ]; then + current_version=$("$INSTALL_PATH" version 2>/dev/null || echo "unknown") + if [ "$current_version" != "unknown" ]; then + print_warning "🔄 Updating Gate from version $current_version to $VERSION at $INSTALL_PATH" + else + print_warning "🔄 Updating existing Gate installation at $INSTALL_PATH" + fi + fi + + # Set download URLs + BINARY_NAME="gate_${VERSION}_${OS}_${ARCH}" + if [ "$OS" = "windows" ]; then + BINARY_NAME="${BINARY_NAME}.exe" + fi + + DOWNLOAD_URL="https://github.com/$REPO_OWNER/$REPO_NAME/releases/download/v${VERSION}/${BINARY_NAME}" + CHECKSUMS_URL="https://github.com/$REPO_OWNER/$REPO_NAME/releases/download/v${VERSION}/checksums.txt" + + print_info "⚡ Downloading Gate ${VERSION} for ${OS}-${ARCH}..." + echo "📥 From: $DOWNLOAD_URL" + + # ✨ Change: Download binary with original name to TEMP_DIR + download "$DOWNLOAD_URL" "$TEMP_DIR/$BINARY_NAME" + + # ✨ Change: Download checksums file + download "$CHECKSUMS_URL" "$TEMP_DIR/checksums.txt" + + # ✨ Change: Verify checksum using the correctly named binary + verify_checksum "$TEMP_DIR/$BINARY_NAME" "$TEMP_DIR/checksums.txt" + + # ✨ Change: Move the verified binary to the installation path as 'gate' + mv "$TEMP_DIR/$BINARY_NAME" "$INSTALL_PATH" + chmod +x "$INSTALL_PATH" + + # Update PATH for the current session + update_path_session + + # Final messages + print_info "✨ Successfully installed Gate ${VERSION}!" + echo "📍 Location: $INSTALL_PATH" + echo + + # Provide PATH update instructions + print_warning "To use Gate, run this command now:" + echo " export PATH=\"$INSTALL_DIR:\$PATH\"" + echo + print_warning "Or add it permanently by running:" + echo " echo 'export PATH=\"$INSTALL_DIR:\$PATH\"' >> \"\$HOME/.$(basename $SHELL)rc\" && source \"\$HOME/.$(basename $SHELL)rc\"" + echo + print_info "🚀 Run gate to start the proxy" +} + +# Execute installation +install_gate \ No newline at end of file diff --git a/.web/docs/public/install.ps1 b/.web/docs/public/install.ps1 new file mode 100644 index 00000000..b8e3c026 --- /dev/null +++ b/.web/docs/public/install.ps1 @@ -0,0 +1,201 @@ +# Install.ps1 - PowerShell installation script for Gate + +# Exit script on errors +$ErrorActionPreference = "Stop" + +# Colors for terminal output +$RED = "Red" +$GREEN = "Green" +$YELLOW = "Yellow" +$NC = "White" # No Color + +# Constants +$REPO_OWNER = "minekube" +$REPO_NAME = "gate" +$DEFAULT_INSTALL_DIR = "$env:LOCALAPPDATA\Gate\bin" +$INSTALL_DIR = if ($env:GATE_INSTALL_DIR) { $env:GATE_INSTALL_DIR } else { $DEFAULT_INSTALL_DIR } +$TEMP_DIR = "$env:TEMP\gate-installer" +$REQUIRED_SPACE_MB = 50 + +# Functions + +function Write-Info { + param([string]$Message) + Write-Host $Message -ForegroundColor $GREEN +} + +function Write-WarningMsg { + param([string]$Message) + Write-Host $Message -ForegroundColor $YELLOW +} + +function Write-ErrorMsg { + param([string]$Message) + Write-Host $Message -ForegroundColor $RED + exit 1 +} + +function Detect-Arch { + $arch = [Environment]::ProcessorArchitecture.ToString() + switch ($arch) { + "X86" { return "386" } + "AMD64" { return "amd64" } + "ARM64" { return "arm64" } + default { + Write-ErrorMsg "Unsupported architecture: $arch" + } + } +} + +function Detect-OS { + $os = [System.Runtime.InteropServices.RuntimeInformation]::OSDescription + if ($os -like "*Windows*") { + return "windows" + } else { + Write-ErrorMsg "Unsupported OS: $os" + } +} + +function Check-DiskSpace { + param([string]$Path) + + # Get free space in MB + $drive = (Get-Item $Path).PSDrive.Name + $freeSpace = (Get-PSDrive -Name $drive).Free / 1MB + + if ($freeSpace -lt $REQUIRED_SPACE_MB) { + Write-ErrorMsg "Insufficient disk space. Required: $REQUIRED_SPACE_MB MB, Available: $([math]::Round($freeSpace,2)) MB" + } +} + +function Download-File { + param( + [string]$Url, + [string]$Destination + ) + + try { + Invoke-WebRequest -Uri $Url -OutFile $Destination -ErrorAction Stop + } + catch { + Write-ErrorMsg "Failed to download from $Url" + } +} + +function Verify-Checksum { + param( + [string]$File, + [string]$ChecksumFile + ) + + $filename = [System.IO.Path]::GetFileName($File) + $expected_checksum = Select-String -Path $ChecksumFile -Pattern $filename | ForEach-Object { ($_ -split '\s+')[0] } + + if (-not $expected_checksum) { + Write-ErrorMsg "Checksum for $filename not found in $ChecksumFile" + } + + try { + $hash = Get-FileHash -Path $File -Algorithm SHA256 + $actual_checksum = $hash.Hash + } + catch { + Write-ErrorMsg "Failed to compute checksum for $filename" + } + + if ($expected_checksum -ne $actual_checksum) { + Write-ErrorMsg "Checksum verification failed for $filename.`nExpected: $expected_checksum`nActual: $actual_checksum" + } + + Write-Info "✅ Checksum verified for $filename" +} + +function Update-PATHSession { + $env:PATH = "$INSTALL_DIR;$env:PATH" +} + +function Add-PATHTemporarily { + Write-Info "✨ Successfully installed Gate $VERSION!" + Write-Host "📍 Location: $INSTALL_PATH" -ForegroundColor $YELLOW + Write-Host "" + + Write-WarningMsg "To use Gate, run this command now:" + Write-Host " \$env:PATH = `"$INSTALL_DIR;`$env:PATH`"" -ForegroundColor $GREEN + Write-Host "" + + Write-WarningMsg "Or add it permanently by running the following commands:" + Write-Host " [Environment]::SetEnvironmentVariable('PATH', `"$INSTALL_DIR;`$env:PATH`", 'User')" -ForegroundColor $GREEN + Write-Host " Reload your PowerShell session or restart your terminal." -ForegroundColor $GREEN + Write-Host "" + + Write-Info "🚀 Run gate to start the proxy" +} + +# Main Installation Function + +function Install-Gate { + Write-Info "✨ Installing Gate..." + + # Create installation and temp directories + New-Item -ItemType Directory -Path $INSTALL_DIR -Force | Out-Null + New-Item -ItemType Directory -Path $TEMP_DIR -Force | Out-Null + + # Check disk space + Check-DiskSpace -Path $INSTALL_DIR + + # Detect OS and architecture + $OS = Detect-OS + $ARCH = Detect-Arch + + # Fetch the latest version from GitHub API + Write-Info "📡 Fetching the latest release information..." + try { + $apiUrl = "https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/releases/latest" + $releaseInfo = Invoke-RestMethod -Uri $apiUrl -Method Get -Headers @{ "User-Agent" = "PowerShell" } + $VERSION = $releaseInfo.tag_name -replace '^v', '' + } + catch { + Write-ErrorMsg "Failed to fetch release information from GitHub." + } + + if (-not $VERSION) { + Write-ErrorMsg "Failed to detect the latest version." + } + + # Set download URLs + $BinaryName = "gate_${VERSION}_${OS}_${ARCH}" + if ($OS -eq "windows") { + $BinaryName += ".exe" + } + + $DOWNLOAD_URL = "https://github.com/$REPO_OWNER/$REPO_NAME/releases/download/v$VERSION/$BinaryName" + $CHECKSUMS_URL = "https://github.com/$REPO_OWNER/$REPO_NAME/releases/download/v$VERSION/checksums.txt" + + Write-Info "⚡ Downloading Gate $VERSION for $OS-$ARCH..." + Write-Host "📥 From: $DOWNLOAD_URL" -ForegroundColor $YELLOW + + # Download binary + $binaryPath = Join-Path $TEMP_DIR $BinaryName + Download-File -Url $DOWNLOAD_URL -Destination $binaryPath + + # Download checksums.txt + $checksumsPath = Join-Path $TEMP_DIR "checksums.txt" + Download-File -Url $CHECKSUMS_URL -Destination $checksumsPath + + # Verify checksum + Verify-Checksum -File $binaryPath -ChecksumFile $checksumsPath + + # Move binary to installation path + $finalPath = Join-Path $INSTALL_DIR "gate.exe" + Move-Item -Path $binaryPath -Destination $finalPath -Force + Write-Host "✔️ Moved gate.exe to $finalPath" -ForegroundColor $GREEN + + # Update PATH for current session + Update-PATHSession + + # Final messages and PATH instructions + Add-PATHTemporarily +} + +# Execute installation +Install-Gate From 2c5f240ab8b1d3d25d38e081ef127f99dee1e73b Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Wed, 20 Nov 2024 09:48:51 +0100 Subject: [PATCH 19/32] fix docs --- .web/docs/developers/api/typescript/bun/index.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/.web/docs/developers/api/typescript/bun/index.md b/.web/docs/developers/api/typescript/bun/index.md index 0149d856..00ac3f8b 100644 --- a/.web/docs/developers/api/typescript/bun/index.md +++ b/.web/docs/developers/api/typescript/bun/index.md @@ -12,8 +12,6 @@ You can use the following `bunfig.toml` to install the dependencies from the `bu To install dependencies: -To install dependencies: - ::: code-group ```bash [bun] From badf64200ad620e8c4859d7a8c455b881b241b8c Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Wed, 20 Nov 2024 09:49:04 +0100 Subject: [PATCH 20/32] doc add install commands to readme --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9874f3d6..2f7caf4a 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,11 @@ guides and any more information needed! Follow our [quick start guide](https://gate.minekube.com/guide/quick-start/) on creating a simple Minecraft network! -```shell -go run go.minekube.com/gate@latest -``` +| Platform | Installation Command | +|-------------|---------------------| +| Go | `go run go.minekube.com/gate@latest` | +| Linux/macOS | `curl -fsSL https://gate.minekube.com/install \| bash` | +| Windows | `powershell -c "irm https://gate.minekube.com/install.ps1 \| iex"` | [![Server list](.web/docs/images/server-list.png)](https://gate.minekube.com) @@ -45,7 +47,7 @@ graph LR C -->|10.0.0.1| D[Backend A] C -->|10.0.0.2| E[Backend B] C -->|10.0.0.3| F[Another Proxy] - + linkStyle 0 stroke:orange linkStyle 1 stroke:purple linkStyle 2 stroke:purple @@ -56,4 +58,3 @@ graph LR The starter template is designed to help you get started with your own Gate powered project. Fork it! 🚀 - [minekube/gate-plugin-template](https://github.com/minekube/gate-plugin-template) - From 2d5125c7bee65fc8dc5125b6c1658d31694d4ce6 Mon Sep 17 00:00:00 2001 From: Dylan Date: Wed, 20 Nov 2024 05:02:24 -0500 Subject: [PATCH 21/32] feat: Gate API - Addition/Removal/Updating of Servers (#427) * feat: Addition/Removal of servers * feat: updateservers instead of add/remove you can now update servers in bulk * feat: remove servers using only name or address can remove servers now using name or address or by having both * feat: updateplayer func to kick/send player can send/kick player(s) now using the same type of operation method like servers, you can provide reason for kicking. * refactor: favour idiomatic api --------- Co-authored-by: robinbraemer --- api/minekube/gate/v1/gate_service.proto | 86 +- pkg/internal/api/convert.go | 8 + .../gen/minekube/gate/v1/gate_service.pb.go | 746 +++++++++++++++--- .../v1/gatev1connect/gate_service.connect.go | 169 +++- pkg/internal/api/service.go | 119 ++- 5 files changed, 1028 insertions(+), 100 deletions(-) diff --git a/api/minekube/gate/v1/gate_service.proto b/api/minekube/gate/v1/gate_service.proto index 8a46e58b..3559959c 100644 --- a/api/minekube/gate/v1/gate_service.proto +++ b/api/minekube/gate/v1/gate_service.proto @@ -7,13 +7,78 @@ service GateService { // GetPlayer returns the player by the given id or username. // If the player is not online, the rpc fails with a NOT_FOUND error code. rpc GetPlayer(GetPlayerRequest) returns (GetPlayerResponse); + // ListPlayers returns all online players. + rpc ListPlayers(ListPlayersRequest) returns (ListPlayersResponse); // ListServers returns all registered servers. rpc ListServers(ListServersRequest) returns (ListServersResponse); + // RegisterServer allows you to add a server to the proxy. + rpc RegisterServer(RegisterServerRequest) returns (RegisterServerResponse); + // UnregisterServer allows you to remove a server from the proxy. + rpc UnregisterServer(UnregisterServerRequest) returns (UnregisterServerResponse); + // ConnectPlayer allows you to connect a player to a server. + rpc ConnectPlayer(ConnectPlayerRequest) returns (ConnectPlayerResponse); + // DisconnectPlayer allows you to disconnect a player from the proxy. + rpc DisconnectPlayer(DisconnectPlayerRequest) returns (DisconnectPlayerResponse); } -// ListServersRequest is the request for ListServers method. -message ListServersRequest { +// DisconnectPlayerRequest is the request for DisconnectPlayer method. +message DisconnectPlayerRequest { + // The player's username or ID + string player = 1; + // The reason displayed to the player when they are disconnected. + // + // Formats: + // - `{"text":"Hello, world!"}` - JSON text component. See https://wiki.vg/Text_formatting for details. + // - `§aHello,\n§bworld!` - Simple color codes. See https://wiki.vg/Text_formatting#Colors + // + // Optional, if empty the default message will be used. + string reason = 2; } + +// DisconnectPlayerResponse is the response for DisconnectPlayer method. +message DisconnectPlayerResponse {} + +// ConnectPlayerRequest is the request for ConnectPlayer method. +message ConnectPlayerRequest { + // The player's username or ID + string player = 1; + // The target server name to connect the player to. + string server = 2; +} + +// ConnectPlayerResponse is the response for ConnectPlayer method. +message ConnectPlayerResponse {} + +// RegisterServerRequest is the request for RegisterServer method. +message RegisterServerRequest { + // The name of the server + string name = 1; + // The address of the server + string address = 2; +} + +// RegisterServerResponse is the response for RegisterServer method. +message RegisterServerResponse {} + +// UnregisterServerRequest is the request for UnregisterServer method. +message UnregisterServerRequest { + // The name of the server. + // Optional, if not set, the address will be used to match servers. + string name = 1; + + // The address of the server. + // Optional, if not set, the name will be used to match servers. + // If both name and address are set, only the server that fully matches both properties is unregistered. + // If only the address is set, all servers with the matching address will be unregistered. + string address = 2; +} + +// UnregisterServerResponse is the response for UnregisterServer method. +message UnregisterServerResponse {} + +// ListServersRequest is the request for ListServers method. +message ListServersRequest {} + // ListServersResponse is the response for ListServers method. message ListServersResponse { repeated Server servers = 1; @@ -21,8 +86,11 @@ message ListServersResponse { // Server is a backend server where Gate can connect players to. message Server { + // The name of the server. string name = 1; + // The address of the server. string address = 2; + // The number of players currently on the server. int32 players = 3; } @@ -45,8 +113,22 @@ message GetPlayerResponse { Player player = 1; } +// ListPlayersRequest is the request for ListPlayers method. +message ListPlayersRequest { + // The server name to filter players by. + // Optional, if empty all players are returned. + repeated string servers = 1; +} + +// ListPlayersResponse is the response for ListPlayers method. +message ListPlayersResponse { + repeated Player players = 1; +} + // Player is a Gate player. message Player { + // The player's id (Minecraft UUID). string id = 1; + // The player's username. string username = 2; } diff --git a/pkg/internal/api/convert.go b/pkg/internal/api/convert.go index 06c07c3e..c0105eca 100644 --- a/pkg/internal/api/convert.go +++ b/pkg/internal/api/convert.go @@ -5,6 +5,14 @@ import ( pb "go.minekube.com/gate/pkg/internal/api/gen/minekube/gate/v1" ) +func PlayersToProto(p []proxy.Player) []*pb.Player { + var players []*pb.Player + for _, player := range p { + players = append(players, PlayerToProto(player)) + } + return players +} + func PlayerToProto(p proxy.Player) *pb.Player { return &pb.Player{ Id: p.ID().String(), diff --git a/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go b/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go index 7130ce99..14766341 100644 --- a/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go +++ b/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go @@ -20,6 +20,388 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// DisconnectPlayerRequest is the request for DisconnectPlayer method. +type DisconnectPlayerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The player's username or ID + Player string `protobuf:"bytes,1,opt,name=player,proto3" json:"player,omitempty"` + // The reason displayed to the player when they are disconnected. + // + // Formats: + // - `{"text":"Hello, world!"}` - JSON text component. See https://wiki.vg/Text_formatting for details. + // - `§aHello,\n§bworld!` - Simple color codes. See https://wiki.vg/Text_formatting#Colors + // + // Optional, if empty the default message will be used. + Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"` +} + +func (x *DisconnectPlayerRequest) Reset() { + *x = DisconnectPlayerRequest{} + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DisconnectPlayerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DisconnectPlayerRequest) ProtoMessage() {} + +func (x *DisconnectPlayerRequest) ProtoReflect() protoreflect.Message { + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DisconnectPlayerRequest.ProtoReflect.Descriptor instead. +func (*DisconnectPlayerRequest) Descriptor() ([]byte, []int) { + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{0} +} + +func (x *DisconnectPlayerRequest) GetPlayer() string { + if x != nil { + return x.Player + } + return "" +} + +func (x *DisconnectPlayerRequest) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +// DisconnectPlayerResponse is the response for DisconnectPlayer method. +type DisconnectPlayerResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DisconnectPlayerResponse) Reset() { + *x = DisconnectPlayerResponse{} + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DisconnectPlayerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DisconnectPlayerResponse) ProtoMessage() {} + +func (x *DisconnectPlayerResponse) ProtoReflect() protoreflect.Message { + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DisconnectPlayerResponse.ProtoReflect.Descriptor instead. +func (*DisconnectPlayerResponse) Descriptor() ([]byte, []int) { + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{1} +} + +// ConnectPlayerRequest is the request for ConnectPlayer method. +type ConnectPlayerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The player's username or ID + Player string `protobuf:"bytes,1,opt,name=player,proto3" json:"player,omitempty"` + // The target server name to connect the player to. + Server string `protobuf:"bytes,2,opt,name=server,proto3" json:"server,omitempty"` +} + +func (x *ConnectPlayerRequest) Reset() { + *x = ConnectPlayerRequest{} + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ConnectPlayerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConnectPlayerRequest) ProtoMessage() {} + +func (x *ConnectPlayerRequest) ProtoReflect() protoreflect.Message { + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConnectPlayerRequest.ProtoReflect.Descriptor instead. +func (*ConnectPlayerRequest) Descriptor() ([]byte, []int) { + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{2} +} + +func (x *ConnectPlayerRequest) GetPlayer() string { + if x != nil { + return x.Player + } + return "" +} + +func (x *ConnectPlayerRequest) GetServer() string { + if x != nil { + return x.Server + } + return "" +} + +// ConnectPlayerResponse is the response for ConnectPlayer method. +type ConnectPlayerResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ConnectPlayerResponse) Reset() { + *x = ConnectPlayerResponse{} + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ConnectPlayerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConnectPlayerResponse) ProtoMessage() {} + +func (x *ConnectPlayerResponse) ProtoReflect() protoreflect.Message { + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConnectPlayerResponse.ProtoReflect.Descriptor instead. +func (*ConnectPlayerResponse) Descriptor() ([]byte, []int) { + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{3} +} + +// RegisterServerRequest is the request for RegisterServer method. +type RegisterServerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of the server + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // The address of the server + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` +} + +func (x *RegisterServerRequest) Reset() { + *x = RegisterServerRequest{} + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegisterServerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterServerRequest) ProtoMessage() {} + +func (x *RegisterServerRequest) ProtoReflect() protoreflect.Message { + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterServerRequest.ProtoReflect.Descriptor instead. +func (*RegisterServerRequest) Descriptor() ([]byte, []int) { + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{4} +} + +func (x *RegisterServerRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RegisterServerRequest) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +// RegisterServerResponse is the response for RegisterServer method. +type RegisterServerResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *RegisterServerResponse) Reset() { + *x = RegisterServerResponse{} + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegisterServerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterServerResponse) ProtoMessage() {} + +func (x *RegisterServerResponse) ProtoReflect() protoreflect.Message { + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterServerResponse.ProtoReflect.Descriptor instead. +func (*RegisterServerResponse) Descriptor() ([]byte, []int) { + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{5} +} + +// UnregisterServerRequest is the request for UnregisterServer method. +type UnregisterServerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of the server. + // Optional, if not set, the address will be used to match servers. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // The address of the server. + // Optional, if not set, the name will be used to match servers. + // If both name and address are set, only the server that fully matches both properties is unregistered. + // If only the address is set, all servers with the matching address will be unregistered. + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` +} + +func (x *UnregisterServerRequest) Reset() { + *x = UnregisterServerRequest{} + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UnregisterServerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnregisterServerRequest) ProtoMessage() {} + +func (x *UnregisterServerRequest) ProtoReflect() protoreflect.Message { + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnregisterServerRequest.ProtoReflect.Descriptor instead. +func (*UnregisterServerRequest) Descriptor() ([]byte, []int) { + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{6} +} + +func (x *UnregisterServerRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UnregisterServerRequest) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +// UnregisterServerResponse is the response for UnregisterServer method. +type UnregisterServerResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *UnregisterServerResponse) Reset() { + *x = UnregisterServerResponse{} + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UnregisterServerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnregisterServerResponse) ProtoMessage() {} + +func (x *UnregisterServerResponse) ProtoReflect() protoreflect.Message { + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnregisterServerResponse.ProtoReflect.Descriptor instead. +func (*UnregisterServerResponse) Descriptor() ([]byte, []int) { + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{7} +} + // ListServersRequest is the request for ListServers method. type ListServersRequest struct { state protoimpl.MessageState @@ -29,7 +411,7 @@ type ListServersRequest struct { func (x *ListServersRequest) Reset() { *x = ListServersRequest{} - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[0] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -41,7 +423,7 @@ func (x *ListServersRequest) String() string { func (*ListServersRequest) ProtoMessage() {} func (x *ListServersRequest) ProtoReflect() protoreflect.Message { - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[0] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -54,7 +436,7 @@ func (x *ListServersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListServersRequest.ProtoReflect.Descriptor instead. func (*ListServersRequest) Descriptor() ([]byte, []int) { - return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{0} + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{8} } // ListServersResponse is the response for ListServers method. @@ -68,7 +450,7 @@ type ListServersResponse struct { func (x *ListServersResponse) Reset() { *x = ListServersResponse{} - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[1] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -80,7 +462,7 @@ func (x *ListServersResponse) String() string { func (*ListServersResponse) ProtoMessage() {} func (x *ListServersResponse) ProtoReflect() protoreflect.Message { - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[1] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -93,7 +475,7 @@ func (x *ListServersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListServersResponse.ProtoReflect.Descriptor instead. func (*ListServersResponse) Descriptor() ([]byte, []int) { - return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{1} + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{9} } func (x *ListServersResponse) GetServers() []*Server { @@ -109,14 +491,17 @@ type Server struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // The name of the server. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // The address of the server. Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` - Players int32 `protobuf:"varint,3,opt,name=players,proto3" json:"players,omitempty"` + // The number of players currently on the server. + Players int32 `protobuf:"varint,3,opt,name=players,proto3" json:"players,omitempty"` } func (x *Server) Reset() { *x = Server{} - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[2] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -128,7 +513,7 @@ func (x *Server) String() string { func (*Server) ProtoMessage() {} func (x *Server) ProtoReflect() protoreflect.Message { - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[2] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -141,7 +526,7 @@ func (x *Server) ProtoReflect() protoreflect.Message { // Deprecated: Use Server.ProtoReflect.Descriptor instead. func (*Server) Descriptor() ([]byte, []int) { - return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{2} + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{10} } func (x *Server) GetName() string { @@ -184,7 +569,7 @@ type GetPlayerRequest struct { func (x *GetPlayerRequest) Reset() { *x = GetPlayerRequest{} - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[3] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -196,7 +581,7 @@ func (x *GetPlayerRequest) String() string { func (*GetPlayerRequest) ProtoMessage() {} func (x *GetPlayerRequest) ProtoReflect() protoreflect.Message { - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[3] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -209,7 +594,7 @@ func (x *GetPlayerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetPlayerRequest.ProtoReflect.Descriptor instead. func (*GetPlayerRequest) Descriptor() ([]byte, []int) { - return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{3} + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{11} } func (x *GetPlayerRequest) GetId() string { @@ -238,7 +623,7 @@ type GetPlayerResponse struct { func (x *GetPlayerResponse) Reset() { *x = GetPlayerResponse{} - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[4] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -250,7 +635,7 @@ func (x *GetPlayerResponse) String() string { func (*GetPlayerResponse) ProtoMessage() {} func (x *GetPlayerResponse) ProtoReflect() protoreflect.Message { - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[4] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -263,7 +648,7 @@ func (x *GetPlayerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetPlayerResponse.ProtoReflect.Descriptor instead. func (*GetPlayerResponse) Descriptor() ([]byte, []int) { - return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{4} + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{12} } func (x *GetPlayerResponse) GetPlayer() *Player { @@ -273,19 +658,115 @@ func (x *GetPlayerResponse) GetPlayer() *Player { return nil } +// ListPlayersRequest is the request for ListPlayers method. +type ListPlayersRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The server name to filter players by. + // Optional, if empty all players are returned. + Servers []string `protobuf:"bytes,1,rep,name=servers,proto3" json:"servers,omitempty"` +} + +func (x *ListPlayersRequest) Reset() { + *x = ListPlayersRequest{} + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListPlayersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListPlayersRequest) ProtoMessage() {} + +func (x *ListPlayersRequest) ProtoReflect() protoreflect.Message { + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListPlayersRequest.ProtoReflect.Descriptor instead. +func (*ListPlayersRequest) Descriptor() ([]byte, []int) { + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{13} +} + +func (x *ListPlayersRequest) GetServers() []string { + if x != nil { + return x.Servers + } + return nil +} + +// ListPlayersResponse is the response for ListPlayers method. +type ListPlayersResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Players []*Player `protobuf:"bytes,1,rep,name=players,proto3" json:"players,omitempty"` +} + +func (x *ListPlayersResponse) Reset() { + *x = ListPlayersResponse{} + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListPlayersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListPlayersResponse) ProtoMessage() {} + +func (x *ListPlayersResponse) ProtoReflect() protoreflect.Message { + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListPlayersResponse.ProtoReflect.Descriptor instead. +func (*ListPlayersResponse) Descriptor() ([]byte, []int) { + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{14} +} + +func (x *ListPlayersResponse) GetPlayers() []*Player { + if x != nil { + return x.Players + } + return nil +} + // Player is a Gate player. type Player struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // The player's id (Minecraft UUID). + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // The player's username. Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"` } func (x *Player) Reset() { *x = Player{} - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[5] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -297,7 +778,7 @@ func (x *Player) String() string { func (*Player) ProtoMessage() {} func (x *Player) ProtoReflect() protoreflect.Message { - mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[5] + mi := &file_minekube_gate_v1_gate_service_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -310,7 +791,7 @@ func (x *Player) ProtoReflect() protoreflect.Message { // Deprecated: Use Player.ProtoReflect.Descriptor instead. func (*Player) Descriptor() ([]byte, []int) { - return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{5} + return file_minekube_gate_v1_gate_service_proto_rawDescGZIP(), []int{15} } func (x *Player) GetId() string { @@ -333,56 +814,120 @@ var file_minekube_gate_v1_gate_service_proto_rawDesc = []byte{ 0x0a, 0x23, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, - 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x22, 0x14, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x49, 0x0a, - 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, - 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, - 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x22, 0x50, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x18, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x22, 0x3e, 0x0a, 0x10, 0x47, 0x65, - 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, - 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x45, 0x0a, 0x11, 0x47, 0x65, - 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x30, 0x0a, 0x06, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x18, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x79, 0x65, - 0x72, 0x22, 0x34, 0x0a, 0x06, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, - 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, - 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x32, 0xbf, 0x01, 0x0a, 0x0b, 0x47, 0x61, 0x74, 0x65, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x54, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x50, 0x6c, - 0x61, 0x79, 0x65, 0x72, 0x12, 0x22, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, - 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, - 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, - 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, - 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x24, 0x2e, 0x6d, - 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, - 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0xcd, 0x01, 0x0a, 0x14, 0x63, 0x6f, - 0x6d, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, - 0x76, 0x31, 0x42, 0x10, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x67, 0x6f, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, - 0x75, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x2f, 0x70, 0x6b, 0x67, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, - 0x6e, 0x2f, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x2f, - 0x76, 0x31, 0x3b, 0x67, 0x61, 0x74, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x4d, 0x47, 0x58, 0xaa, - 0x02, 0x10, 0x4d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x2e, - 0x56, 0x31, 0xca, 0x02, 0x10, 0x4d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x5c, 0x47, 0x61, - 0x74, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, 0x4d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, - 0x5c, 0x47, 0x61, 0x74, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x12, 0x4d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x3a, - 0x3a, 0x47, 0x61, 0x74, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x22, 0x49, 0x0a, 0x17, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, + 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, + 0x6f, 0x6e, 0x22, 0x1a, 0x0a, 0x18, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x46, + 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x17, 0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x45, 0x0a, 0x15, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x47, 0x0a, 0x17, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x1a, 0x0a, 0x18, 0x55, 0x6e, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x14, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x49, 0x0a, 0x13, 0x4c, + 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, + 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x07, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x22, 0x50, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x18, + 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x22, 0x3e, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x50, + 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x45, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, + 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, + 0x06, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x22, + 0x2e, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x22, + 0x49, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, + 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, + 0x72, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x22, 0x34, 0x0a, 0x06, 0x50, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x32, 0xb8, 0x05, 0x0a, 0x0b, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x54, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x22, 0x2e, + 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x73, 0x12, 0x24, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, + 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, 0x61, + 0x79, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x69, + 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x12, 0x24, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, + 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, + 0x0a, 0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x12, 0x27, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x6d, 0x69, 0x6e, 0x65, + 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x69, 0x0a, 0x10, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x29, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, + 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, + 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, + 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, + 0x26, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, + 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x69, 0x0a, 0x10, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x12, 0x29, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, + 0x67, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2a, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x6c, 0x61, + 0x79, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0xcd, 0x01, 0x0a, 0x14, + 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x67, 0x61, 0x74, + 0x65, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x47, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x67, 0x6f, 0x2e, 0x6d, 0x69, 0x6e, + 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x2f, 0x70, + 0x6b, 0x67, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x67, 0x65, 0x6e, 0x2f, 0x6d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2f, 0x67, 0x61, 0x74, + 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x67, 0x61, 0x74, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x4d, 0x47, + 0x58, 0xaa, 0x02, 0x10, 0x4d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x2e, 0x47, 0x61, 0x74, + 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, 0x4d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, 0x65, 0x5c, + 0x47, 0x61, 0x74, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, 0x4d, 0x69, 0x6e, 0x65, 0x6b, 0x75, + 0x62, 0x65, 0x5c, 0x47, 0x61, 0x74, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x12, 0x4d, 0x69, 0x6e, 0x65, 0x6b, 0x75, 0x62, + 0x65, 0x3a, 0x3a, 0x47, 0x61, 0x74, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -397,27 +942,48 @@ func file_minekube_gate_v1_gate_service_proto_rawDescGZIP() []byte { return file_minekube_gate_v1_gate_service_proto_rawDescData } -var file_minekube_gate_v1_gate_service_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_minekube_gate_v1_gate_service_proto_msgTypes = make([]protoimpl.MessageInfo, 16) var file_minekube_gate_v1_gate_service_proto_goTypes = []any{ - (*ListServersRequest)(nil), // 0: minekube.gate.v1.ListServersRequest - (*ListServersResponse)(nil), // 1: minekube.gate.v1.ListServersResponse - (*Server)(nil), // 2: minekube.gate.v1.Server - (*GetPlayerRequest)(nil), // 3: minekube.gate.v1.GetPlayerRequest - (*GetPlayerResponse)(nil), // 4: minekube.gate.v1.GetPlayerResponse - (*Player)(nil), // 5: minekube.gate.v1.Player + (*DisconnectPlayerRequest)(nil), // 0: minekube.gate.v1.DisconnectPlayerRequest + (*DisconnectPlayerResponse)(nil), // 1: minekube.gate.v1.DisconnectPlayerResponse + (*ConnectPlayerRequest)(nil), // 2: minekube.gate.v1.ConnectPlayerRequest + (*ConnectPlayerResponse)(nil), // 3: minekube.gate.v1.ConnectPlayerResponse + (*RegisterServerRequest)(nil), // 4: minekube.gate.v1.RegisterServerRequest + (*RegisterServerResponse)(nil), // 5: minekube.gate.v1.RegisterServerResponse + (*UnregisterServerRequest)(nil), // 6: minekube.gate.v1.UnregisterServerRequest + (*UnregisterServerResponse)(nil), // 7: minekube.gate.v1.UnregisterServerResponse + (*ListServersRequest)(nil), // 8: minekube.gate.v1.ListServersRequest + (*ListServersResponse)(nil), // 9: minekube.gate.v1.ListServersResponse + (*Server)(nil), // 10: minekube.gate.v1.Server + (*GetPlayerRequest)(nil), // 11: minekube.gate.v1.GetPlayerRequest + (*GetPlayerResponse)(nil), // 12: minekube.gate.v1.GetPlayerResponse + (*ListPlayersRequest)(nil), // 13: minekube.gate.v1.ListPlayersRequest + (*ListPlayersResponse)(nil), // 14: minekube.gate.v1.ListPlayersResponse + (*Player)(nil), // 15: minekube.gate.v1.Player } var file_minekube_gate_v1_gate_service_proto_depIdxs = []int32{ - 2, // 0: minekube.gate.v1.ListServersResponse.servers:type_name -> minekube.gate.v1.Server - 5, // 1: minekube.gate.v1.GetPlayerResponse.player:type_name -> minekube.gate.v1.Player - 3, // 2: minekube.gate.v1.GateService.GetPlayer:input_type -> minekube.gate.v1.GetPlayerRequest - 0, // 3: minekube.gate.v1.GateService.ListServers:input_type -> minekube.gate.v1.ListServersRequest - 4, // 4: minekube.gate.v1.GateService.GetPlayer:output_type -> minekube.gate.v1.GetPlayerResponse - 1, // 5: minekube.gate.v1.GateService.ListServers:output_type -> minekube.gate.v1.ListServersResponse - 4, // [4:6] is the sub-list for method output_type - 2, // [2:4] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 10, // 0: minekube.gate.v1.ListServersResponse.servers:type_name -> minekube.gate.v1.Server + 15, // 1: minekube.gate.v1.GetPlayerResponse.player:type_name -> minekube.gate.v1.Player + 15, // 2: minekube.gate.v1.ListPlayersResponse.players:type_name -> minekube.gate.v1.Player + 11, // 3: minekube.gate.v1.GateService.GetPlayer:input_type -> minekube.gate.v1.GetPlayerRequest + 13, // 4: minekube.gate.v1.GateService.ListPlayers:input_type -> minekube.gate.v1.ListPlayersRequest + 8, // 5: minekube.gate.v1.GateService.ListServers:input_type -> minekube.gate.v1.ListServersRequest + 4, // 6: minekube.gate.v1.GateService.RegisterServer:input_type -> minekube.gate.v1.RegisterServerRequest + 6, // 7: minekube.gate.v1.GateService.UnregisterServer:input_type -> minekube.gate.v1.UnregisterServerRequest + 2, // 8: minekube.gate.v1.GateService.ConnectPlayer:input_type -> minekube.gate.v1.ConnectPlayerRequest + 0, // 9: minekube.gate.v1.GateService.DisconnectPlayer:input_type -> minekube.gate.v1.DisconnectPlayerRequest + 12, // 10: minekube.gate.v1.GateService.GetPlayer:output_type -> minekube.gate.v1.GetPlayerResponse + 14, // 11: minekube.gate.v1.GateService.ListPlayers:output_type -> minekube.gate.v1.ListPlayersResponse + 9, // 12: minekube.gate.v1.GateService.ListServers:output_type -> minekube.gate.v1.ListServersResponse + 5, // 13: minekube.gate.v1.GateService.RegisterServer:output_type -> minekube.gate.v1.RegisterServerResponse + 7, // 14: minekube.gate.v1.GateService.UnregisterServer:output_type -> minekube.gate.v1.UnregisterServerResponse + 3, // 15: minekube.gate.v1.GateService.ConnectPlayer:output_type -> minekube.gate.v1.ConnectPlayerResponse + 1, // 16: minekube.gate.v1.GateService.DisconnectPlayer:output_type -> minekube.gate.v1.DisconnectPlayerResponse + 10, // [10:17] is the sub-list for method output_type + 3, // [3:10] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_minekube_gate_v1_gate_service_proto_init() } @@ -431,7 +997,7 @@ func file_minekube_gate_v1_gate_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_minekube_gate_v1_gate_service_proto_rawDesc, NumEnums: 0, - NumMessages: 6, + NumMessages: 16, NumExtensions: 0, NumServices: 1, }, diff --git a/pkg/internal/api/gen/minekube/gate/v1/gatev1connect/gate_service.connect.go b/pkg/internal/api/gen/minekube/gate/v1/gatev1connect/gate_service.connect.go index 72d26857..d71edc2e 100644 --- a/pkg/internal/api/gen/minekube/gate/v1/gatev1connect/gate_service.connect.go +++ b/pkg/internal/api/gen/minekube/gate/v1/gatev1connect/gate_service.connect.go @@ -35,15 +35,34 @@ const ( const ( // GateServiceGetPlayerProcedure is the fully-qualified name of the GateService's GetPlayer RPC. GateServiceGetPlayerProcedure = "/minekube.gate.v1.GateService/GetPlayer" + // GateServiceListPlayersProcedure is the fully-qualified name of the GateService's ListPlayers RPC. + GateServiceListPlayersProcedure = "/minekube.gate.v1.GateService/ListPlayers" // GateServiceListServersProcedure is the fully-qualified name of the GateService's ListServers RPC. GateServiceListServersProcedure = "/minekube.gate.v1.GateService/ListServers" + // GateServiceRegisterServerProcedure is the fully-qualified name of the GateService's + // RegisterServer RPC. + GateServiceRegisterServerProcedure = "/minekube.gate.v1.GateService/RegisterServer" + // GateServiceUnregisterServerProcedure is the fully-qualified name of the GateService's + // UnregisterServer RPC. + GateServiceUnregisterServerProcedure = "/minekube.gate.v1.GateService/UnregisterServer" + // GateServiceConnectPlayerProcedure is the fully-qualified name of the GateService's ConnectPlayer + // RPC. + GateServiceConnectPlayerProcedure = "/minekube.gate.v1.GateService/ConnectPlayer" + // GateServiceDisconnectPlayerProcedure is the fully-qualified name of the GateService's + // DisconnectPlayer RPC. + GateServiceDisconnectPlayerProcedure = "/minekube.gate.v1.GateService/DisconnectPlayer" ) // These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. var ( - gateServiceServiceDescriptor = v1.File_minekube_gate_v1_gate_service_proto.Services().ByName("GateService") - gateServiceGetPlayerMethodDescriptor = gateServiceServiceDescriptor.Methods().ByName("GetPlayer") - gateServiceListServersMethodDescriptor = gateServiceServiceDescriptor.Methods().ByName("ListServers") + gateServiceServiceDescriptor = v1.File_minekube_gate_v1_gate_service_proto.Services().ByName("GateService") + gateServiceGetPlayerMethodDescriptor = gateServiceServiceDescriptor.Methods().ByName("GetPlayer") + gateServiceListPlayersMethodDescriptor = gateServiceServiceDescriptor.Methods().ByName("ListPlayers") + gateServiceListServersMethodDescriptor = gateServiceServiceDescriptor.Methods().ByName("ListServers") + gateServiceRegisterServerMethodDescriptor = gateServiceServiceDescriptor.Methods().ByName("RegisterServer") + gateServiceUnregisterServerMethodDescriptor = gateServiceServiceDescriptor.Methods().ByName("UnregisterServer") + gateServiceConnectPlayerMethodDescriptor = gateServiceServiceDescriptor.Methods().ByName("ConnectPlayer") + gateServiceDisconnectPlayerMethodDescriptor = gateServiceServiceDescriptor.Methods().ByName("DisconnectPlayer") ) // GateServiceClient is a client for the minekube.gate.v1.GateService service. @@ -51,8 +70,18 @@ type GateServiceClient interface { // GetPlayer returns the player by the given id or username. // If the player is not online, the rpc fails with a NOT_FOUND error code. GetPlayer(context.Context, *connect.Request[v1.GetPlayerRequest]) (*connect.Response[v1.GetPlayerResponse], error) + // ListPlayers returns all online players. + ListPlayers(context.Context, *connect.Request[v1.ListPlayersRequest]) (*connect.Response[v1.ListPlayersResponse], error) // ListServers returns all registered servers. ListServers(context.Context, *connect.Request[v1.ListServersRequest]) (*connect.Response[v1.ListServersResponse], error) + // RegisterServer allows you to add a server to the proxy. + RegisterServer(context.Context, *connect.Request[v1.RegisterServerRequest]) (*connect.Response[v1.RegisterServerResponse], error) + // UnregisterServer allows you to remove a server from the proxy. + UnregisterServer(context.Context, *connect.Request[v1.UnregisterServerRequest]) (*connect.Response[v1.UnregisterServerResponse], error) + // ConnectPlayer allows you to connect a player to a server. + ConnectPlayer(context.Context, *connect.Request[v1.ConnectPlayerRequest]) (*connect.Response[v1.ConnectPlayerResponse], error) + // DisconnectPlayer allows you to disconnect a player from the proxy. + DisconnectPlayer(context.Context, *connect.Request[v1.DisconnectPlayerRequest]) (*connect.Response[v1.DisconnectPlayerResponse], error) } // NewGateServiceClient constructs a client for the minekube.gate.v1.GateService service. By @@ -71,19 +100,54 @@ func NewGateServiceClient(httpClient connect.HTTPClient, baseURL string, opts .. connect.WithSchema(gateServiceGetPlayerMethodDescriptor), connect.WithClientOptions(opts...), ), + listPlayers: connect.NewClient[v1.ListPlayersRequest, v1.ListPlayersResponse]( + httpClient, + baseURL+GateServiceListPlayersProcedure, + connect.WithSchema(gateServiceListPlayersMethodDescriptor), + connect.WithClientOptions(opts...), + ), listServers: connect.NewClient[v1.ListServersRequest, v1.ListServersResponse]( httpClient, baseURL+GateServiceListServersProcedure, connect.WithSchema(gateServiceListServersMethodDescriptor), connect.WithClientOptions(opts...), ), + registerServer: connect.NewClient[v1.RegisterServerRequest, v1.RegisterServerResponse]( + httpClient, + baseURL+GateServiceRegisterServerProcedure, + connect.WithSchema(gateServiceRegisterServerMethodDescriptor), + connect.WithClientOptions(opts...), + ), + unregisterServer: connect.NewClient[v1.UnregisterServerRequest, v1.UnregisterServerResponse]( + httpClient, + baseURL+GateServiceUnregisterServerProcedure, + connect.WithSchema(gateServiceUnregisterServerMethodDescriptor), + connect.WithClientOptions(opts...), + ), + connectPlayer: connect.NewClient[v1.ConnectPlayerRequest, v1.ConnectPlayerResponse]( + httpClient, + baseURL+GateServiceConnectPlayerProcedure, + connect.WithSchema(gateServiceConnectPlayerMethodDescriptor), + connect.WithClientOptions(opts...), + ), + disconnectPlayer: connect.NewClient[v1.DisconnectPlayerRequest, v1.DisconnectPlayerResponse]( + httpClient, + baseURL+GateServiceDisconnectPlayerProcedure, + connect.WithSchema(gateServiceDisconnectPlayerMethodDescriptor), + connect.WithClientOptions(opts...), + ), } } // gateServiceClient implements GateServiceClient. type gateServiceClient struct { - getPlayer *connect.Client[v1.GetPlayerRequest, v1.GetPlayerResponse] - listServers *connect.Client[v1.ListServersRequest, v1.ListServersResponse] + getPlayer *connect.Client[v1.GetPlayerRequest, v1.GetPlayerResponse] + listPlayers *connect.Client[v1.ListPlayersRequest, v1.ListPlayersResponse] + listServers *connect.Client[v1.ListServersRequest, v1.ListServersResponse] + registerServer *connect.Client[v1.RegisterServerRequest, v1.RegisterServerResponse] + unregisterServer *connect.Client[v1.UnregisterServerRequest, v1.UnregisterServerResponse] + connectPlayer *connect.Client[v1.ConnectPlayerRequest, v1.ConnectPlayerResponse] + disconnectPlayer *connect.Client[v1.DisconnectPlayerRequest, v1.DisconnectPlayerResponse] } // GetPlayer calls minekube.gate.v1.GateService.GetPlayer. @@ -91,18 +155,53 @@ func (c *gateServiceClient) GetPlayer(ctx context.Context, req *connect.Request[ return c.getPlayer.CallUnary(ctx, req) } +// ListPlayers calls minekube.gate.v1.GateService.ListPlayers. +func (c *gateServiceClient) ListPlayers(ctx context.Context, req *connect.Request[v1.ListPlayersRequest]) (*connect.Response[v1.ListPlayersResponse], error) { + return c.listPlayers.CallUnary(ctx, req) +} + // ListServers calls minekube.gate.v1.GateService.ListServers. func (c *gateServiceClient) ListServers(ctx context.Context, req *connect.Request[v1.ListServersRequest]) (*connect.Response[v1.ListServersResponse], error) { return c.listServers.CallUnary(ctx, req) } +// RegisterServer calls minekube.gate.v1.GateService.RegisterServer. +func (c *gateServiceClient) RegisterServer(ctx context.Context, req *connect.Request[v1.RegisterServerRequest]) (*connect.Response[v1.RegisterServerResponse], error) { + return c.registerServer.CallUnary(ctx, req) +} + +// UnregisterServer calls minekube.gate.v1.GateService.UnregisterServer. +func (c *gateServiceClient) UnregisterServer(ctx context.Context, req *connect.Request[v1.UnregisterServerRequest]) (*connect.Response[v1.UnregisterServerResponse], error) { + return c.unregisterServer.CallUnary(ctx, req) +} + +// ConnectPlayer calls minekube.gate.v1.GateService.ConnectPlayer. +func (c *gateServiceClient) ConnectPlayer(ctx context.Context, req *connect.Request[v1.ConnectPlayerRequest]) (*connect.Response[v1.ConnectPlayerResponse], error) { + return c.connectPlayer.CallUnary(ctx, req) +} + +// DisconnectPlayer calls minekube.gate.v1.GateService.DisconnectPlayer. +func (c *gateServiceClient) DisconnectPlayer(ctx context.Context, req *connect.Request[v1.DisconnectPlayerRequest]) (*connect.Response[v1.DisconnectPlayerResponse], error) { + return c.disconnectPlayer.CallUnary(ctx, req) +} + // GateServiceHandler is an implementation of the minekube.gate.v1.GateService service. type GateServiceHandler interface { // GetPlayer returns the player by the given id or username. // If the player is not online, the rpc fails with a NOT_FOUND error code. GetPlayer(context.Context, *connect.Request[v1.GetPlayerRequest]) (*connect.Response[v1.GetPlayerResponse], error) + // ListPlayers returns all online players. + ListPlayers(context.Context, *connect.Request[v1.ListPlayersRequest]) (*connect.Response[v1.ListPlayersResponse], error) // ListServers returns all registered servers. ListServers(context.Context, *connect.Request[v1.ListServersRequest]) (*connect.Response[v1.ListServersResponse], error) + // RegisterServer allows you to add a server to the proxy. + RegisterServer(context.Context, *connect.Request[v1.RegisterServerRequest]) (*connect.Response[v1.RegisterServerResponse], error) + // UnregisterServer allows you to remove a server from the proxy. + UnregisterServer(context.Context, *connect.Request[v1.UnregisterServerRequest]) (*connect.Response[v1.UnregisterServerResponse], error) + // ConnectPlayer allows you to connect a player to a server. + ConnectPlayer(context.Context, *connect.Request[v1.ConnectPlayerRequest]) (*connect.Response[v1.ConnectPlayerResponse], error) + // DisconnectPlayer allows you to disconnect a player from the proxy. + DisconnectPlayer(context.Context, *connect.Request[v1.DisconnectPlayerRequest]) (*connect.Response[v1.DisconnectPlayerResponse], error) } // NewGateServiceHandler builds an HTTP handler from the service implementation. It returns the path @@ -117,18 +216,58 @@ func NewGateServiceHandler(svc GateServiceHandler, opts ...connect.HandlerOption connect.WithSchema(gateServiceGetPlayerMethodDescriptor), connect.WithHandlerOptions(opts...), ) + gateServiceListPlayersHandler := connect.NewUnaryHandler( + GateServiceListPlayersProcedure, + svc.ListPlayers, + connect.WithSchema(gateServiceListPlayersMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) gateServiceListServersHandler := connect.NewUnaryHandler( GateServiceListServersProcedure, svc.ListServers, connect.WithSchema(gateServiceListServersMethodDescriptor), connect.WithHandlerOptions(opts...), ) + gateServiceRegisterServerHandler := connect.NewUnaryHandler( + GateServiceRegisterServerProcedure, + svc.RegisterServer, + connect.WithSchema(gateServiceRegisterServerMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + gateServiceUnregisterServerHandler := connect.NewUnaryHandler( + GateServiceUnregisterServerProcedure, + svc.UnregisterServer, + connect.WithSchema(gateServiceUnregisterServerMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + gateServiceConnectPlayerHandler := connect.NewUnaryHandler( + GateServiceConnectPlayerProcedure, + svc.ConnectPlayer, + connect.WithSchema(gateServiceConnectPlayerMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + gateServiceDisconnectPlayerHandler := connect.NewUnaryHandler( + GateServiceDisconnectPlayerProcedure, + svc.DisconnectPlayer, + connect.WithSchema(gateServiceDisconnectPlayerMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) return "/minekube.gate.v1.GateService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case GateServiceGetPlayerProcedure: gateServiceGetPlayerHandler.ServeHTTP(w, r) + case GateServiceListPlayersProcedure: + gateServiceListPlayersHandler.ServeHTTP(w, r) case GateServiceListServersProcedure: gateServiceListServersHandler.ServeHTTP(w, r) + case GateServiceRegisterServerProcedure: + gateServiceRegisterServerHandler.ServeHTTP(w, r) + case GateServiceUnregisterServerProcedure: + gateServiceUnregisterServerHandler.ServeHTTP(w, r) + case GateServiceConnectPlayerProcedure: + gateServiceConnectPlayerHandler.ServeHTTP(w, r) + case GateServiceDisconnectPlayerProcedure: + gateServiceDisconnectPlayerHandler.ServeHTTP(w, r) default: http.NotFound(w, r) } @@ -142,6 +281,26 @@ func (UnimplementedGateServiceHandler) GetPlayer(context.Context, *connect.Reque return nil, connect.NewError(connect.CodeUnimplemented, errors.New("minekube.gate.v1.GateService.GetPlayer is not implemented")) } +func (UnimplementedGateServiceHandler) ListPlayers(context.Context, *connect.Request[v1.ListPlayersRequest]) (*connect.Response[v1.ListPlayersResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("minekube.gate.v1.GateService.ListPlayers is not implemented")) +} + func (UnimplementedGateServiceHandler) ListServers(context.Context, *connect.Request[v1.ListServersRequest]) (*connect.Response[v1.ListServersResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("minekube.gate.v1.GateService.ListServers is not implemented")) } + +func (UnimplementedGateServiceHandler) RegisterServer(context.Context, *connect.Request[v1.RegisterServerRequest]) (*connect.Response[v1.RegisterServerResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("minekube.gate.v1.GateService.RegisterServer is not implemented")) +} + +func (UnimplementedGateServiceHandler) UnregisterServer(context.Context, *connect.Request[v1.UnregisterServerRequest]) (*connect.Response[v1.UnregisterServerResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("minekube.gate.v1.GateService.UnregisterServer is not implemented")) +} + +func (UnimplementedGateServiceHandler) ConnectPlayer(context.Context, *connect.Request[v1.ConnectPlayerRequest]) (*connect.Response[v1.ConnectPlayerResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("minekube.gate.v1.GateService.ConnectPlayer is not implemented")) +} + +func (UnimplementedGateServiceHandler) DisconnectPlayer(context.Context, *connect.Request[v1.DisconnectPlayerRequest]) (*connect.Response[v1.DisconnectPlayerResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("minekube.gate.v1.GateService.DisconnectPlayer is not implemented")) +} diff --git a/pkg/internal/api/service.go b/pkg/internal/api/service.go index 66935e06..cd17d3dc 100644 --- a/pkg/internal/api/service.go +++ b/pkg/internal/api/service.go @@ -5,12 +5,14 @@ import ( "errors" "fmt" - pb "go.minekube.com/gate/pkg/internal/api/gen/minekube/gate/v1" - "go.minekube.com/gate/pkg/internal/api/gen/minekube/gate/v1/gatev1connect" - "connectrpc.com/connect" + "go.minekube.com/common/minecraft/component" "go.minekube.com/gate/pkg/edition/java/proxy" + pb "go.minekube.com/gate/pkg/internal/api/gen/minekube/gate/v1" + "go.minekube.com/gate/pkg/internal/api/gen/minekube/gate/v1/gatev1connect" + "go.minekube.com/gate/pkg/util/componentutil" + "go.minekube.com/gate/pkg/util/netutil" "go.minekube.com/gate/pkg/util/uuid" ) @@ -30,6 +32,117 @@ type ( var _ Handler = (*Service)(nil) +func (s *Service) ListPlayers(ctx context.Context, c *connect.Request[pb.ListPlayersRequest]) (*connect.Response[pb.ListPlayersResponse], error) { + var players []proxy.Player + if len(c.Msg.Servers) == 0 { + players = s.p.Players() + } else { + for _, svr := range c.Msg.Servers { + if s := s.p.Server(svr); s != nil { + s.Players().Range(func(p proxy.Player) bool { + players = append(players, p) + return true + }) + } + } + } + return connect.NewResponse(&pb.ListPlayersResponse{ + Players: PlayersToProto(players), + }), nil +} + +func (s *Service) RegisterServer(ctx context.Context, c *connect.Request[pb.RegisterServerRequest]) (*connect.Response[pb.RegisterServerResponse], error) { + serverAddr := netutil.NewAddr(c.Msg.Address, "tcp") + serverInfo := proxy.NewServerInfo(c.Msg.Name, serverAddr) + + _, err := s.p.Register(serverInfo) + if err != nil { + if errors.Is(err, proxy.ErrServerAlreadyExists) { + return nil, connect.NewError(connect.CodeAlreadyExists, fmt.Errorf("server %q already exists", serverInfo.Name())) + } + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to register server: %v", err)) + } + + return connect.NewResponse(&pb.RegisterServerResponse{}), nil +} + +func (s *Service) UnregisterServer(ctx context.Context, c *connect.Request[pb.UnregisterServerRequest]) (*connect.Response[pb.UnregisterServerResponse], error) { + var serverInfo proxy.ServerInfo + + switch { + case c.Msg.Name != "" && c.Msg.Address != "": + serverAddr := netutil.NewAddr(c.Msg.Address, "tcp") + serverInfo = proxy.NewServerInfo(c.Msg.Name, serverAddr) + case c.Msg.Name != "": + if s := s.p.Server(c.Msg.Name); s != nil { + serverInfo = s.ServerInfo() + } else { + return nil, connect.NewError(connect.CodeNotFound, errors.New("server not found by name")) + } + case c.Msg.Address != "": + var found bool + for _, s := range s.p.Servers() { + if s.ServerInfo().Addr().String() == c.Msg.Address { + serverInfo = s.ServerInfo() + found = true + break + } + } + if !found { + return nil, connect.NewError(connect.CodeNotFound, errors.New("server not found by address")) + } + default: + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("invalid request: must specify either name and/or address")) + } + + found := s.p.Unregister(serverInfo) + if !found { + return nil, connect.NewError(connect.CodeNotFound, errors.New("server not found")) + } + + return connect.NewResponse(&pb.UnregisterServerResponse{}), nil +} + +func (s *Service) ConnectPlayer(ctx context.Context, c *connect.Request[pb.ConnectPlayerRequest]) (*connect.Response[pb.ConnectPlayerResponse], error) { + player := s.p.PlayerByName(c.Msg.Player) + if player == nil { + return nil, connect.NewError(connect.CodeNotFound, errors.New("player not found")) + } + + targetServer := s.p.Server(c.Msg.Server) + if targetServer == nil { + return nil, connect.NewError(connect.CodeNotFound, errors.New("server not found")) + } + + connectionRequest := player.CreateConnectionRequest(targetServer) + _, err := connectionRequest.Connect(ctx) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to connect player: %v", err)) + } + + return connect.NewResponse(&pb.ConnectPlayerResponse{}), nil +} + +func (s *Service) DisconnectPlayer(ctx context.Context, c *connect.Request[pb.DisconnectPlayerRequest]) (*connect.Response[pb.DisconnectPlayerResponse], error) { + player := s.p.PlayerByName(c.Msg.Player) + if player == nil { + return nil, connect.NewError(connect.CodeNotFound, errors.New("player not found")) + } + + var reason *component.Text + if c.Msg.Reason != "" { + var err error + reason, err = componentutil.ParseTextComponent(player.Protocol(), c.Msg.Reason) + if err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("could not parse reason: %v", err)) + } + } + + player.Disconnect(reason) + + return connect.NewResponse(&pb.DisconnectPlayerResponse{}), nil +} + func (s *Service) ListServers(ctx context.Context, c *connect.Request[pb.ListServersRequest]) (*connect.Response[pb.ListServersResponse], error) { return connect.NewResponse(&pb.ListServersResponse{ Servers: ServersToProto(s.p.Servers()), From 66d510c843ce3034849e006b04d40b86b573ff66 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Wed, 20 Nov 2024 11:14:35 +0100 Subject: [PATCH 22/32] enhance proto --- api/minekube/gate/v1/gate_service.proto | 72 ++++++++++++++++--------- pkg/internal/api/service.go | 22 ++++++-- 2 files changed, 63 insertions(+), 31 deletions(-) diff --git a/api/minekube/gate/v1/gate_service.proto b/api/minekube/gate/v1/gate_service.proto index 3559959c..7e29f92d 100644 --- a/api/minekube/gate/v1/gate_service.proto +++ b/api/minekube/gate/v1/gate_service.proto @@ -2,28 +2,46 @@ syntax = "proto3"; package minekube.gate.v1; -// GateService is the service of a Gate instance. +// GateService is the service API for managing a Gate proxy instance. +// It provides methods for managing players and servers. +// All methods follow standard gRPC error codes and include detailed error messages. service GateService { // GetPlayer returns the player by the given id or username. - // If the player is not online, the rpc fails with a NOT_FOUND error code. + // Returns NOT_FOUND if the player is not online. + // Returns INVALID_ARGUMENT if neither id nor username is provided, or if the id format is invalid. rpc GetPlayer(GetPlayerRequest) returns (GetPlayerResponse); + // ListPlayers returns all online players. + // If servers are specified in the request, only returns players on those servers. rpc ListPlayers(ListPlayersRequest) returns (ListPlayersResponse); + // ListServers returns all registered servers. rpc ListServers(ListServersRequest) returns (ListServersResponse); - // RegisterServer allows you to add a server to the proxy. + + // RegisterServer adds a server to the proxy. + // Returns ALREADY_EXISTS if a server with the same name is already registered. + // Returns INVALID_ARGUMENT if the server name or address is invalid. rpc RegisterServer(RegisterServerRequest) returns (RegisterServerResponse); - // UnregisterServer allows you to remove a server from the proxy. + + // UnregisterServer removes a server from the proxy. + // Returns NOT_FOUND if no matching server is found. + // Returns INVALID_ARGUMENT if neither name nor address is provided. rpc UnregisterServer(UnregisterServerRequest) returns (UnregisterServerResponse); - // ConnectPlayer allows you to connect a player to a server. + + // ConnectPlayer connects a player to a specified server. + // Returns NOT_FOUND if either the player or target server doesn't exist. + // Returns FAILED_PRECONDITION if the connection attempt fails. rpc ConnectPlayer(ConnectPlayerRequest) returns (ConnectPlayerResponse); - // DisconnectPlayer allows you to disconnect a player from the proxy. + + // DisconnectPlayer disconnects a player from the proxy. + // Returns NOT_FOUND if the player doesn't exist. + // Returns INVALID_ARGUMENT if the reason text is malformed. rpc DisconnectPlayer(DisconnectPlayerRequest) returns (DisconnectPlayerResponse); } // DisconnectPlayerRequest is the request for DisconnectPlayer method. message DisconnectPlayerRequest { - // The player's username or ID + // The player's username or ID to disconnect string player = 1; // The reason displayed to the player when they are disconnected. // @@ -31,7 +49,7 @@ message DisconnectPlayerRequest { // - `{"text":"Hello, world!"}` - JSON text component. See https://wiki.vg/Text_formatting for details. // - `§aHello,\n§bworld!` - Simple color codes. See https://wiki.vg/Text_formatting#Colors // - // Optional, if empty the default message will be used. + // Optional, if empty no reason will be shown. string reason = 2; } @@ -40,9 +58,9 @@ message DisconnectPlayerResponse {} // ConnectPlayerRequest is the request for ConnectPlayer method. message ConnectPlayerRequest { - // The player's username or ID + // The player's username or ID to connect string player = 1; - // The target server name to connect the player to. + // The target server name to connect the player to string server = 2; } @@ -51,9 +69,9 @@ message ConnectPlayerResponse {} // RegisterServerRequest is the request for RegisterServer method. message RegisterServerRequest { - // The name of the server + // The unique name of the server string name = 1; - // The address of the server + // The network address of the server (e.g. "localhost:25565") string address = 2; } @@ -68,8 +86,8 @@ message UnregisterServerRequest { // The address of the server. // Optional, if not set, the name will be used to match servers. - // If both name and address are set, only the server that fully matches both properties is unregistered. - // If only the address is set, all servers with the matching address will be unregistered. + // If both name and address are set, only the server that matches both properties exactly will be unregistered. + // If only the address is set, the first server matching that address will be unregistered. string address = 2; } @@ -84,11 +102,11 @@ message ListServersResponse { repeated Server servers = 1; } -// Server is a backend server where Gate can connect players to. +// Server represents a backend server where Gate can connect players to. message Server { - // The name of the server. + // The unique name of the server. string name = 1; - // The address of the server. + // The network address of the server. string address = 2; // The number of players currently on the server. int32 players = 3; @@ -96,27 +114,29 @@ message Server { // GetPlayerRequest is the request for GetPlayer method. message GetPlayerRequest { - // Gets the player by the given id (Minecraft UUID). + // Gets the player by their Minecraft UUID. // Optional, if not set the username will be used. // If both id and username are set, the id will be used. // - // Format but be a valid Minecraft UUID. + // Must be a valid Minecraft UUID format (e.g. "550e8400-e29b-41d4-a716-446655440000") string id = 1; - // Gets the player by the given username. + // Gets the player by their username. // Optional, if not set the id will be used. + // Case-sensitive. string username = 2; } // GetPlayerResponse is the response for GetPlayer method. message GetPlayerResponse { - // The player matching the request. + // The player matching the request criteria Player player = 1; } // ListPlayersRequest is the request for ListPlayers method. message ListPlayersRequest { - // The server name to filter players by. - // Optional, if empty all players are returned. + // Filter players by server names. + // Optional, if empty all online players are returned. + // If specified, only returns players on the listed servers. repeated string servers = 1; } @@ -125,10 +145,10 @@ message ListPlayersResponse { repeated Player players = 1; } -// Player is a Gate player. +// Player represents an online player on the proxy. message Player { - // The player's id (Minecraft UUID). + // The player's Minecraft UUID string id = 1; - // The player's username. + // The player's username string username = 2; } diff --git a/pkg/internal/api/service.go b/pkg/internal/api/service.go index cd17d3dc..fccdb7c0 100644 --- a/pkg/internal/api/service.go +++ b/pkg/internal/api/service.go @@ -60,7 +60,7 @@ func (s *Service) RegisterServer(ctx context.Context, c *connect.Request[pb.Regi if errors.Is(err, proxy.ErrServerAlreadyExists) { return nil, connect.NewError(connect.CodeAlreadyExists, fmt.Errorf("server %q already exists", serverInfo.Name())) } - return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to register server: %v", err)) + return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid server info: %v", err)) } return connect.NewResponse(&pb.RegisterServerResponse{}), nil @@ -97,14 +97,20 @@ func (s *Service) UnregisterServer(ctx context.Context, c *connect.Request[pb.Un found := s.p.Unregister(serverInfo) if !found { - return nil, connect.NewError(connect.CodeNotFound, errors.New("server not found")) + return nil, connect.NewError(connect.CodeNotFound, + fmt.Errorf("server not found with name %q and address %q", serverInfo.Name(), serverInfo.Addr())) } return connect.NewResponse(&pb.UnregisterServerResponse{}), nil } func (s *Service) ConnectPlayer(ctx context.Context, c *connect.Request[pb.ConnectPlayerRequest]) (*connect.Response[pb.ConnectPlayerResponse], error) { - player := s.p.PlayerByName(c.Msg.Player) + var player proxy.Player + if id, err := uuid.Parse(c.Msg.Player); err == nil { + player = s.p.Player(id) + } else { + player = s.p.PlayerByName(c.Msg.Player) + } if player == nil { return nil, connect.NewError(connect.CodeNotFound, errors.New("player not found")) } @@ -117,14 +123,20 @@ func (s *Service) ConnectPlayer(ctx context.Context, c *connect.Request[pb.Conne connectionRequest := player.CreateConnectionRequest(targetServer) _, err := connectionRequest.Connect(ctx) if err != nil { - return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to connect player: %v", err)) + return nil, connect.NewError(connect.CodeFailedPrecondition, err) } return connect.NewResponse(&pb.ConnectPlayerResponse{}), nil } func (s *Service) DisconnectPlayer(ctx context.Context, c *connect.Request[pb.DisconnectPlayerRequest]) (*connect.Response[pb.DisconnectPlayerResponse], error) { - player := s.p.PlayerByName(c.Msg.Player) + var player proxy.Player + if id, err := uuid.Parse(c.Msg.Player); err == nil { + player = s.p.Player(id) + } else { + player = s.p.PlayerByName(c.Msg.Player) + } + if player == nil { return nil, connect.NewError(connect.CodeNotFound, errors.New("player not found")) } From 59dc1029b93b47e4cb208cbccd8138d6659a1a5e Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Wed, 20 Nov 2024 11:15:07 +0100 Subject: [PATCH 23/32] buf generate --- .../gen/minekube/gate/v1/gate_service.pb.go | 42 ++++++++++--------- .../v1/gatev1connect/gate_service.connect.go | 40 +++++++++++++----- 2 files changed, 52 insertions(+), 30 deletions(-) diff --git a/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go b/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go index 14766341..fb2a6f6c 100644 --- a/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go +++ b/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go @@ -26,7 +26,7 @@ type DisconnectPlayerRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The player's username or ID + // The player's username or ID to disconnect Player string `protobuf:"bytes,1,opt,name=player,proto3" json:"player,omitempty"` // The reason displayed to the player when they are disconnected. // @@ -34,7 +34,7 @@ type DisconnectPlayerRequest struct { // - `{"text":"Hello, world!"}` - JSON text component. See https://wiki.vg/Text_formatting for details. // - `§aHello,\n§bworld!` - Simple color codes. See https://wiki.vg/Text_formatting#Colors // - // Optional, if empty the default message will be used. + // Optional, if empty no reason will be shown. Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"` } @@ -125,9 +125,9 @@ type ConnectPlayerRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The player's username or ID + // The player's username or ID to connect Player string `protobuf:"bytes,1,opt,name=player,proto3" json:"player,omitempty"` - // The target server name to connect the player to. + // The target server name to connect the player to Server string `protobuf:"bytes,2,opt,name=server,proto3" json:"server,omitempty"` } @@ -218,9 +218,9 @@ type RegisterServerRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The name of the server + // The unique name of the server Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // The address of the server + // The network address of the server (e.g. "localhost:25565") Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` } @@ -316,8 +316,8 @@ type UnregisterServerRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // The address of the server. // Optional, if not set, the name will be used to match servers. - // If both name and address are set, only the server that fully matches both properties is unregistered. - // If only the address is set, all servers with the matching address will be unregistered. + // If both name and address are set, only the server that matches both properties exactly will be unregistered. + // If only the address is set, the first server matching that address will be unregistered. Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` } @@ -485,15 +485,15 @@ func (x *ListServersResponse) GetServers() []*Server { return nil } -// Server is a backend server where Gate can connect players to. +// Server represents a backend server where Gate can connect players to. type Server struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The name of the server. + // The unique name of the server. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // The address of the server. + // The network address of the server. Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` // The number of players currently on the server. Players int32 `protobuf:"varint,3,opt,name=players,proto3" json:"players,omitempty"` @@ -556,14 +556,15 @@ type GetPlayerRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Gets the player by the given id (Minecraft UUID). + // Gets the player by their Minecraft UUID. // Optional, if not set the username will be used. // If both id and username are set, the id will be used. // - // Format but be a valid Minecraft UUID. + // Must be a valid Minecraft UUID format (e.g. "550e8400-e29b-41d4-a716-446655440000") Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // Gets the player by the given username. + // Gets the player by their username. // Optional, if not set the id will be used. + // Case-sensitive. Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"` } @@ -617,7 +618,7 @@ type GetPlayerResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The player matching the request. + // The player matching the request criteria Player *Player `protobuf:"bytes,1,opt,name=player,proto3" json:"player,omitempty"` } @@ -664,8 +665,9 @@ type ListPlayersRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The server name to filter players by. - // Optional, if empty all players are returned. + // Filter players by server names. + // Optional, if empty all online players are returned. + // If specified, only returns players on the listed servers. Servers []string `protobuf:"bytes,1,rep,name=servers,proto3" json:"servers,omitempty"` } @@ -752,15 +754,15 @@ func (x *ListPlayersResponse) GetPlayers() []*Player { return nil } -// Player is a Gate player. +// Player represents an online player on the proxy. type Player struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The player's id (Minecraft UUID). + // The player's Minecraft UUID Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // The player's username. + // The player's username Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"` } diff --git a/pkg/internal/api/gen/minekube/gate/v1/gatev1connect/gate_service.connect.go b/pkg/internal/api/gen/minekube/gate/v1/gatev1connect/gate_service.connect.go index d71edc2e..a555b518 100644 --- a/pkg/internal/api/gen/minekube/gate/v1/gatev1connect/gate_service.connect.go +++ b/pkg/internal/api/gen/minekube/gate/v1/gatev1connect/gate_service.connect.go @@ -68,19 +68,29 @@ var ( // GateServiceClient is a client for the minekube.gate.v1.GateService service. type GateServiceClient interface { // GetPlayer returns the player by the given id or username. - // If the player is not online, the rpc fails with a NOT_FOUND error code. + // Returns NOT_FOUND if the player is not online. + // Returns INVALID_ARGUMENT if neither id nor username is provided, or if the id format is invalid. GetPlayer(context.Context, *connect.Request[v1.GetPlayerRequest]) (*connect.Response[v1.GetPlayerResponse], error) // ListPlayers returns all online players. + // If servers are specified in the request, only returns players on those servers. ListPlayers(context.Context, *connect.Request[v1.ListPlayersRequest]) (*connect.Response[v1.ListPlayersResponse], error) // ListServers returns all registered servers. ListServers(context.Context, *connect.Request[v1.ListServersRequest]) (*connect.Response[v1.ListServersResponse], error) - // RegisterServer allows you to add a server to the proxy. + // RegisterServer adds a server to the proxy. + // Returns ALREADY_EXISTS if a server with the same name is already registered. + // Returns INVALID_ARGUMENT if the server name or address is invalid. RegisterServer(context.Context, *connect.Request[v1.RegisterServerRequest]) (*connect.Response[v1.RegisterServerResponse], error) - // UnregisterServer allows you to remove a server from the proxy. + // UnregisterServer removes a server from the proxy. + // Returns NOT_FOUND if no matching server is found. + // Returns INVALID_ARGUMENT if neither name nor address is provided. UnregisterServer(context.Context, *connect.Request[v1.UnregisterServerRequest]) (*connect.Response[v1.UnregisterServerResponse], error) - // ConnectPlayer allows you to connect a player to a server. + // ConnectPlayer connects a player to a specified server. + // Returns NOT_FOUND if either the player or target server doesn't exist. + // Returns FAILED_PRECONDITION if the connection attempt fails. ConnectPlayer(context.Context, *connect.Request[v1.ConnectPlayerRequest]) (*connect.Response[v1.ConnectPlayerResponse], error) - // DisconnectPlayer allows you to disconnect a player from the proxy. + // DisconnectPlayer disconnects a player from the proxy. + // Returns NOT_FOUND if the player doesn't exist. + // Returns INVALID_ARGUMENT if the reason text is malformed. DisconnectPlayer(context.Context, *connect.Request[v1.DisconnectPlayerRequest]) (*connect.Response[v1.DisconnectPlayerResponse], error) } @@ -188,19 +198,29 @@ func (c *gateServiceClient) DisconnectPlayer(ctx context.Context, req *connect.R // GateServiceHandler is an implementation of the minekube.gate.v1.GateService service. type GateServiceHandler interface { // GetPlayer returns the player by the given id or username. - // If the player is not online, the rpc fails with a NOT_FOUND error code. + // Returns NOT_FOUND if the player is not online. + // Returns INVALID_ARGUMENT if neither id nor username is provided, or if the id format is invalid. GetPlayer(context.Context, *connect.Request[v1.GetPlayerRequest]) (*connect.Response[v1.GetPlayerResponse], error) // ListPlayers returns all online players. + // If servers are specified in the request, only returns players on those servers. ListPlayers(context.Context, *connect.Request[v1.ListPlayersRequest]) (*connect.Response[v1.ListPlayersResponse], error) // ListServers returns all registered servers. ListServers(context.Context, *connect.Request[v1.ListServersRequest]) (*connect.Response[v1.ListServersResponse], error) - // RegisterServer allows you to add a server to the proxy. + // RegisterServer adds a server to the proxy. + // Returns ALREADY_EXISTS if a server with the same name is already registered. + // Returns INVALID_ARGUMENT if the server name or address is invalid. RegisterServer(context.Context, *connect.Request[v1.RegisterServerRequest]) (*connect.Response[v1.RegisterServerResponse], error) - // UnregisterServer allows you to remove a server from the proxy. + // UnregisterServer removes a server from the proxy. + // Returns NOT_FOUND if no matching server is found. + // Returns INVALID_ARGUMENT if neither name nor address is provided. UnregisterServer(context.Context, *connect.Request[v1.UnregisterServerRequest]) (*connect.Response[v1.UnregisterServerResponse], error) - // ConnectPlayer allows you to connect a player to a server. + // ConnectPlayer connects a player to a specified server. + // Returns NOT_FOUND if either the player or target server doesn't exist. + // Returns FAILED_PRECONDITION if the connection attempt fails. ConnectPlayer(context.Context, *connect.Request[v1.ConnectPlayerRequest]) (*connect.Response[v1.ConnectPlayerResponse], error) - // DisconnectPlayer allows you to disconnect a player from the proxy. + // DisconnectPlayer disconnects a player from the proxy. + // Returns NOT_FOUND if the player doesn't exist. + // Returns INVALID_ARGUMENT if the reason text is malformed. DisconnectPlayer(context.Context, *connect.Request[v1.DisconnectPlayerRequest]) (*connect.Response[v1.DisconnectPlayerResponse], error) } From a1eee9aeb39f839dfe1ad304dd10e2b57ca19547 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Wed, 20 Nov 2024 11:20:52 +0100 Subject: [PATCH 24/32] docs: simplify What the Installation Scripts Do --- .web/docs/guide/install/binaries.md | 33 ++++------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/.web/docs/guide/install/binaries.md b/.web/docs/guide/install/binaries.md index d4ba6524..b30ac5e4 100644 --- a/.web/docs/guide/install/binaries.md +++ b/.web/docs/guide/install/binaries.md @@ -106,47 +106,22 @@ If you encounter any issues: Our installation scripts are designed to be transparent and secure. Here's exactly what they do: -#### Linux/macOS (`install`) - 1. **Safety First**: - - - Installs to user space (`~/.local/bin`) without requiring root/sudo + - Installs to user space (Linux/macOS: `~/.local/bin`, Windows: `%LOCALAPPDATA%\Gate\bin`) - Downloads only from official GitHub releases - Verifies file integrity using SHA256 checksums 2. **Installation Steps**: - - - Detects your OS (Linux/macOS) and architecture (amd64/arm64) - - Creates `~/.local/bin` if it doesn't exist - - Downloads the appropriate Gate binary - - Verifies the checksum to ensure file integrity - - Makes the binary executable - - Provides clear PATH setup instructions - -3. **No System Changes**: - - Only writes to your user directory - - Suggests PATH changes but doesn't modify system files - - Can be easily uninstalled by removing the binary - -#### Windows (`install.ps1`) - -1. **Safety First**: - - - Installs to user space (`%LOCALAPPDATA%\Gate\bin`) - - Downloads only from official GitHub releases - - Verifies file integrity using SHA256 checksums - -2. **Installation Steps**: - - - Detects your Windows architecture (amd64/arm64) + - Detects system architecture (amd64/arm64) - Creates installation directory if it doesn't exist - Downloads the appropriate Gate binary - Verifies the checksum to ensure file integrity + - Makes the binary executable (Linux/macOS only) - Provides clear PATH setup instructions 3. **No System Changes**: - Only writes to your user directory - - Suggests PATH changes but doesn't modify system PATH without permission + - Suggests PATH changes but doesn't modify system files - Can be easily uninstalled by removing the binary ### Verifying the Scripts From 98e3d294ce839488057db89acd34d57b587322e2 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Wed, 20 Nov 2024 11:28:58 +0100 Subject: [PATCH 25/32] docs: add proto definition --- .web/docs/.vitepress/config.ts | 4 + .web/docs/developers/api/definition.md | 7 ++ .web/docs/developers/api/index.md | 98 +---------------------- .web/docs/developers/api/sdks.md | 106 +++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 97 deletions(-) create mode 100644 .web/docs/developers/api/definition.md create mode 100644 .web/docs/developers/api/sdks.md diff --git a/.web/docs/.vitepress/config.ts b/.web/docs/.vitepress/config.ts index 00402ce4..a1de9906 100644 --- a/.web/docs/.vitepress/config.ts +++ b/.web/docs/.vitepress/config.ts @@ -211,6 +211,10 @@ export default defineConfig({ text: 'Getting Started', link: '/developers/api/', }, + { + text: 'Definition', + link: '/developers/api/definition', + }, { text: 'TypeScript', link: '/developers/api/typescript/', diff --git a/.web/docs/developers/api/definition.md b/.web/docs/developers/api/definition.md new file mode 100644 index 00000000..27798745 --- /dev/null +++ b/.web/docs/developers/api/definition.md @@ -0,0 +1,7 @@ +# API Definition + + + +```protobuf + +``` diff --git a/.web/docs/developers/api/index.md b/.web/docs/developers/api/index.md index de766024..4668d77c 100644 --- a/.web/docs/developers/api/index.md +++ b/.web/docs/developers/api/index.md @@ -16,66 +16,7 @@ api: ::: -## Official SDKs - -Gate's API definitions are hosted on [buf.build/minekube/gate](https://buf.build/minekube/gate/sdks), where you can directly pull client libraries using your preferred language's package manager: - - + ## Features @@ -148,41 +89,4 @@ To understand the key technologies used in Gate's API, check out the [Glossary]( font-size: 0.9em; line-height: 1.4; } - -.vp-feature-small { - padding: 12px; - border-radius: 6px; - background-color: var(--vp-c-bg-soft); - border: 1px solid var(--vp-c-divider); - text-align: center; - transition: all 0.3s; -} - -.vp-feature-small:hover { - border-color: var(--vp-c-brand-1); - transform: translateY(-1px); - box-shadow: 0 2px 8px 0 var(--vp-c-divider); -} - -.vp-feature-small .title { - font-weight: 600; - margin-bottom: 4px; - color: var(--vp-c-text-1); - display: flex; - align-items: center; - justify-content: center; -} - -.vp-feature-small .details { - color: var(--vp-c-text-2); - font-size: 0.9em; -} - -.tech-icon { - width: 24px; - height: 24px; - display: inline-block; - vertical-align: middle; - margin-right: 8px; -} diff --git a/.web/docs/developers/api/sdks.md b/.web/docs/developers/api/sdks.md new file mode 100644 index 00000000..dcdb38ab --- /dev/null +++ b/.web/docs/developers/api/sdks.md @@ -0,0 +1,106 @@ +## Official SDKs + +Gate's API definitions are hosted on [buf.build/minekube/gate](https://buf.build/minekube/gate/sdks), where you can directly pull client libraries using your preferred language's package manager: + + + + From 8ff7d6b32518f198936256ccf0e82c5e7de6820f Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Wed, 20 Nov 2024 11:54:49 +0100 Subject: [PATCH 26/32] docs: add generated definition --- .web/docs/.vitepress/config.ts | 8 +- .web/docs/developers/api/definition.md | 8 + .../docs/developers/api/gen/definition.gen.md | 314 ++++++++++++++++++ api/minekube/gate/v1/gate_service.proto | 3 +- buf.gen.yaml | 5 +- .../gen/minekube/gate/v1/gate_service.pb.go | 3 +- 6 files changed, 334 insertions(+), 7 deletions(-) create mode 100644 .web/docs/developers/api/gen/definition.gen.md diff --git a/.web/docs/.vitepress/config.ts b/.web/docs/.vitepress/config.ts index a1de9906..3bbd2b4b 100644 --- a/.web/docs/.vitepress/config.ts +++ b/.web/docs/.vitepress/config.ts @@ -211,10 +211,6 @@ export default defineConfig({ text: 'Getting Started', link: '/developers/api/', }, - { - text: 'Definition', - link: '/developers/api/definition', - }, { text: 'TypeScript', link: '/developers/api/typescript/', @@ -253,6 +249,10 @@ export default defineConfig({ text: 'Java', link: '/developers/api/java/', }, + { + text: 'Definition', + link: '/developers/api/definition', + }, { text: 'Glossary', link: '/developers/api/glossary', diff --git a/.web/docs/developers/api/definition.md b/.web/docs/developers/api/definition.md index 27798745..c46350c7 100644 --- a/.web/docs/developers/api/definition.md +++ b/.web/docs/developers/api/definition.md @@ -2,6 +2,14 @@ +::: details `gate_service.proto` + ```protobuf ``` + +::: + +--- + + diff --git a/.web/docs/developers/api/gen/definition.gen.md b/.web/docs/developers/api/gen/definition.gen.md new file mode 100644 index 00000000..e315a601 --- /dev/null +++ b/.web/docs/developers/api/gen/definition.gen.md @@ -0,0 +1,314 @@ +# Protocol Documentation + + +## Table of Contents + +- [minekube/gate/v1/gate_service.proto](#minekube_gate_v1_gate_service-proto) + - [ConnectPlayerRequest](#minekube-gate-v1-ConnectPlayerRequest) + - [ConnectPlayerResponse](#minekube-gate-v1-ConnectPlayerResponse) + - [DisconnectPlayerRequest](#minekube-gate-v1-DisconnectPlayerRequest) + - [DisconnectPlayerResponse](#minekube-gate-v1-DisconnectPlayerResponse) + - [GetPlayerRequest](#minekube-gate-v1-GetPlayerRequest) + - [GetPlayerResponse](#minekube-gate-v1-GetPlayerResponse) + - [ListPlayersRequest](#minekube-gate-v1-ListPlayersRequest) + - [ListPlayersResponse](#minekube-gate-v1-ListPlayersResponse) + - [ListServersRequest](#minekube-gate-v1-ListServersRequest) + - [ListServersResponse](#minekube-gate-v1-ListServersResponse) + - [Player](#minekube-gate-v1-Player) + - [RegisterServerRequest](#minekube-gate-v1-RegisterServerRequest) + - [RegisterServerResponse](#minekube-gate-v1-RegisterServerResponse) + - [Server](#minekube-gate-v1-Server) + - [UnregisterServerRequest](#minekube-gate-v1-UnregisterServerRequest) + - [UnregisterServerResponse](#minekube-gate-v1-UnregisterServerResponse) + + - [GateService](#minekube-gate-v1-GateService) + +- [Scalar Value Types](#scalar-value-types) + + + + +

Top

+ +## minekube/gate/v1/gate_service.proto + + + + + +### ConnectPlayerRequest +ConnectPlayerRequest is the request for ConnectPlayer method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| player | [string](#string) | | The player's username or ID to connect | +| server | [string](#string) | | The target server name to connect the player to | + + + + + + + + +### ConnectPlayerResponse +ConnectPlayerResponse is the response for ConnectPlayer method. + + + + + + + + +### DisconnectPlayerRequest +DisconnectPlayerRequest is the request for DisconnectPlayer method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| player | [string](#string) | | The player's username or ID to disconnect | +| reason | [string](#string) | | The reason displayed to the player when they are disconnected. + +Formats: + +- `{"text":"Hello, world!"}` - JSON text component. See https://wiki.vg/Text_formatting for details. + +- `§aHello,\n§bworld!` - Simple color codes. See https://wiki.vg/Text_formatting#Colors + +Optional, if empty no reason will be shown. | + + + + + + + + +### DisconnectPlayerResponse +DisconnectPlayerResponse is the response for DisconnectPlayer method. + + + + + + + + +### GetPlayerRequest +GetPlayerRequest is the request for GetPlayer method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [string](#string) | | Gets the player by their Minecraft UUID. Optional, if not set the username will be used. If both id and username are set, the id will be used. Must be a valid Minecraft UUID format (e.g. "550e8400-e29b-41d4-a716-446655440000") | +| username | [string](#string) | | Gets the player by their username. Optional, if not set the id will be used. Case-sensitive. | + + + + + + + + +### GetPlayerResponse +GetPlayerResponse is the response for GetPlayer method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| player | [Player](#minekube-gate-v1-Player) | | The player matching the request criteria | + + + + + + + + +### ListPlayersRequest +ListPlayersRequest is the request for ListPlayers method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| servers | [string](#string) | repeated | Filter players by server names. Optional, if empty all online players are returned. If specified, only returns players on the listed servers. | + + + + + + + + +### ListPlayersResponse +ListPlayersResponse is the response for ListPlayers method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| players | [Player](#minekube-gate-v1-Player) | repeated | | + + + + + + + + +### ListServersRequest +ListServersRequest is the request for ListServers method. + + + + + + + + +### ListServersResponse +ListServersResponse is the response for ListServers method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| servers | [Server](#minekube-gate-v1-Server) | repeated | | + + + + + + + + +### Player +Player represents an online player on the proxy. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [string](#string) | | The player's Minecraft UUID | +| username | [string](#string) | | The player's username | + + + + + + + + +### RegisterServerRequest +RegisterServerRequest is the request for RegisterServer method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | The unique name of the server | +| address | [string](#string) | | The network address of the server (e.g. "localhost:25565") | + + + + + + + + +### RegisterServerResponse +RegisterServerResponse is the response for RegisterServer method. + + + + + + + + +### Server +Server represents a backend server where Gate can connect players to. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | The unique name of the server. | +| address | [string](#string) | | The network address of the server. | +| players | [int32](#int32) | | The number of players currently on the server. | + + + + + + + + +### UnregisterServerRequest +UnregisterServerRequest is the request for UnregisterServer method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | The name of the server. Optional, if not set, the address will be used to match servers. | +| address | [string](#string) | | The address of the server. Optional, if not set, the name will be used to match servers. If both name and address are set, only the server that matches both properties exactly will be unregistered. If only the address is set, the first server matching that address will be unregistered. | + + + + + + + + +### UnregisterServerResponse +UnregisterServerResponse is the response for UnregisterServer method. + + + + + + + + + + + + + + +### GateService +GateService is the service API for managing a Gate proxy instance. +It provides methods for managing players and servers. +All methods follow standard gRPC error codes and include detailed error messages. + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| GetPlayer | [GetPlayerRequest](#minekube-gate-v1-GetPlayerRequest) | [GetPlayerResponse](#minekube-gate-v1-GetPlayerResponse) | GetPlayer returns the player by the given id or username. Returns NOT_FOUND if the player is not online. Returns INVALID_ARGUMENT if neither id nor username is provided, or if the id format is invalid. | +| ListPlayers | [ListPlayersRequest](#minekube-gate-v1-ListPlayersRequest) | [ListPlayersResponse](#minekube-gate-v1-ListPlayersResponse) | ListPlayers returns all online players. If servers are specified in the request, only returns players on those servers. | +| ListServers | [ListServersRequest](#minekube-gate-v1-ListServersRequest) | [ListServersResponse](#minekube-gate-v1-ListServersResponse) | ListServers returns all registered servers. | +| RegisterServer | [RegisterServerRequest](#minekube-gate-v1-RegisterServerRequest) | [RegisterServerResponse](#minekube-gate-v1-RegisterServerResponse) | RegisterServer adds a server to the proxy. Returns ALREADY_EXISTS if a server with the same name is already registered. Returns INVALID_ARGUMENT if the server name or address is invalid. | +| UnregisterServer | [UnregisterServerRequest](#minekube-gate-v1-UnregisterServerRequest) | [UnregisterServerResponse](#minekube-gate-v1-UnregisterServerResponse) | UnregisterServer removes a server from the proxy. Returns NOT_FOUND if no matching server is found. Returns INVALID_ARGUMENT if neither name nor address is provided. | +| ConnectPlayer | [ConnectPlayerRequest](#minekube-gate-v1-ConnectPlayerRequest) | [ConnectPlayerResponse](#minekube-gate-v1-ConnectPlayerResponse) | ConnectPlayer connects a player to a specified server. Returns NOT_FOUND if either the player or target server doesn't exist. Returns FAILED_PRECONDITION if the connection attempt fails. | +| DisconnectPlayer | [DisconnectPlayerRequest](#minekube-gate-v1-DisconnectPlayerRequest) | [DisconnectPlayerResponse](#minekube-gate-v1-DisconnectPlayerResponse) | DisconnectPlayer disconnects a player from the proxy. Returns NOT_FOUND if the player doesn't exist. Returns INVALID_ARGUMENT if the reason text is malformed. | + + + + + +## Scalar Value Types + +| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby | +| ----------- | ----- | --- | ---- | ------ | -- | -- | --- | ---- | +| double | | double | double | float | float64 | double | float | Float | +| float | | float | float | float | float32 | float | float | Float | +| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | +| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum | +| uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) | +| uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) | +| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | +| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum | +| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) | +| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum | +| sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | +| sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum | +| bool | | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass | +| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) | +| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) | + diff --git a/api/minekube/gate/v1/gate_service.proto b/api/minekube/gate/v1/gate_service.proto index 7e29f92d..8ff064a6 100644 --- a/api/minekube/gate/v1/gate_service.proto +++ b/api/minekube/gate/v1/gate_service.proto @@ -46,7 +46,9 @@ message DisconnectPlayerRequest { // The reason displayed to the player when they are disconnected. // // Formats: + // // - `{"text":"Hello, world!"}` - JSON text component. See https://wiki.vg/Text_formatting for details. + // // - `§aHello,\n§bworld!` - Simple color codes. See https://wiki.vg/Text_formatting#Colors // // Optional, if empty no reason will be shown. @@ -117,7 +119,6 @@ message GetPlayerRequest { // Gets the player by their Minecraft UUID. // Optional, if not set the username will be used. // If both id and username are set, the id will be used. - // // Must be a valid Minecraft UUID format (e.g. "550e8400-e29b-41d4-a716-446655440000") string id = 1; // Gets the player by their username. diff --git a/buf.gen.yaml b/buf.gen.yaml index 35ff7542..88b3d23e 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -11,4 +11,7 @@ plugins: opt: paths=source_relative - remote: buf.build/connectrpc/go out: pkg/internal/api/gen - opt: paths=source_relative \ No newline at end of file + opt: paths=source_relative + - remote: buf.build/community/pseudomuto-doc + out: .web/docs/developers/api/gen + opt: markdown,definition.gen.md diff --git a/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go b/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go index fb2a6f6c..7336d2ad 100644 --- a/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go +++ b/pkg/internal/api/gen/minekube/gate/v1/gate_service.pb.go @@ -31,7 +31,9 @@ type DisconnectPlayerRequest struct { // The reason displayed to the player when they are disconnected. // // Formats: + // // - `{"text":"Hello, world!"}` - JSON text component. See https://wiki.vg/Text_formatting for details. + // // - `§aHello,\n§bworld!` - Simple color codes. See https://wiki.vg/Text_formatting#Colors // // Optional, if empty no reason will be shown. @@ -559,7 +561,6 @@ type GetPlayerRequest struct { // Gets the player by their Minecraft UUID. // Optional, if not set the username will be used. // If both id and username are set, the id will be used. - // // Must be a valid Minecraft UUID format (e.g. "550e8400-e29b-41d4-a716-446655440000") Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Gets the player by their username. From 147e8f0d48dc42be6128da02be2774dad72b97d6 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Wed, 20 Nov 2024 13:26:58 +0100 Subject: [PATCH 27/32] web: add landing page content --- .../theme/components/LandingAfter.vue | 1018 +++++++++++++++++ .../.vitepress/theme/components/Layout.vue | 4 + 2 files changed, 1022 insertions(+) create mode 100644 .web/docs/.vitepress/theme/components/LandingAfter.vue diff --git a/.web/docs/.vitepress/theme/components/LandingAfter.vue b/.web/docs/.vitepress/theme/components/LandingAfter.vue new file mode 100644 index 00000000..38ea9af1 --- /dev/null +++ b/.web/docs/.vitepress/theme/components/LandingAfter.vue @@ -0,0 +1,1018 @@ + + + + + diff --git a/.web/docs/.vitepress/theme/components/Layout.vue b/.web/docs/.vitepress/theme/components/Layout.vue index daa653ef..7e4a0c74 100644 --- a/.web/docs/.vitepress/theme/components/Layout.vue +++ b/.web/docs/.vitepress/theme/components/Layout.vue @@ -3,6 +3,7 @@ import DefaultTheme from 'vitepress/theme' import {useRouter} from 'vitepress'; import {watch} from 'vue'; import HomeHeroImage from "./HomeHeroImage.vue"; +import LandingAfter from './LandingAfter.vue'; const {Layout} = DefaultTheme @@ -22,5 +23,8 @@ if (typeof window !== 'undefined' && window.posthog) { + \ No newline at end of file From d7a11a4904d999bea4eee12c2b1557ca89ae0168 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Wed, 20 Nov 2024 13:32:59 +0100 Subject: [PATCH 28/32] background alternating --- .web/docs/.vitepress/config.ts | 2 +- .../.vitepress/theme/components/LandingAfter.vue | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.web/docs/.vitepress/config.ts b/.web/docs/.vitepress/config.ts index 3bbd2b4b..71970a60 100644 --- a/.web/docs/.vitepress/config.ts +++ b/.web/docs/.vitepress/config.ts @@ -76,7 +76,7 @@ export default defineConfig({ // }, footer: { - message: `Released under the MIT License. (web version: ${commitRef})`, + message: `Released under the Apache 2.0 License. (web version: ${commitRef})`, copyright: 'Copyright © 2022-present Minekube & Contributors', }, diff --git a/.web/docs/.vitepress/theme/components/LandingAfter.vue b/.web/docs/.vitepress/theme/components/LandingAfter.vue index 38ea9af1..aa514f54 100644 --- a/.web/docs/.vitepress/theme/components/LandingAfter.vue +++ b/.web/docs/.vitepress/theme/components/LandingAfter.vue @@ -325,7 +325,7 @@
-
+

@@ -523,7 +523,7 @@

-
+

@@ -712,7 +712,7 @@ try:

-
+

-
- Open Source -
-
Apache 2.0 Licensed
+
650+
+
GitHub Stars

From 2fdc5a9bb884a8e2949f7a45b3292a7f0793c452 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Wed, 20 Nov 2024 15:12:04 +0100 Subject: [PATCH 29/32] fix(ui): mobile responsiveness --- .../theme/components/LandingAfter.vue | 976 +++++++++--------- 1 file changed, 493 insertions(+), 483 deletions(-) diff --git a/.web/docs/.vitepress/theme/components/LandingAfter.vue b/.web/docs/.vitepress/theme/components/LandingAfter.vue index aa514f54..24f61242 100644 --- a/.web/docs/.vitepress/theme/components/LandingAfter.vue +++ b/.web/docs/.vitepress/theme/components/LandingAfter.vue @@ -244,259 +244,252 @@
-
-
-
-
-
- powershell -c "irm https://gate.minekube.com/install.ps1 | - iex" -
-
- curl -sSL https://gate.minekube.com/install.sh | sh -
- -
-
- - -
+
+ +
- |
-
-
-
-
- - -
-
-
-

- Ultra-Lightweight Mode -

-

- Host-based routing made simple -

-

- Gate Lite acts as an ultra-thin reverse proxy, efficiently routing - connections based on hostnames. Protect multiple backend servers - behind a single port with minimal overhead. -

-
- - -
-
- Lite Mode Diagram -
-
- -
-
- - - - - -
-
- - - -
-
-

- Response Caching -

-

- Optimized ping responses -

+ +
+
+
+

+ Ultra-Lightweight Mode +

+

+ Host-based routing made simple +

+

+ Gate Lite acts as an ultra-thin reverse proxy, efficiently routing + connections based on hostnames. Protect multiple backend servers + behind a single port with minimal overhead. +

+
+ + +
+
+ Lite Mode Diagram
-
- - - +
+
+ + + +
+
+

+ Response Caching +

+

+ Optimized ping responses +

+
+
+ - -
-
-
-
- -
config:
+
+              
+              
+
+
+
+
+ config.yml + +
+
config:
   lite:
     enabled: true
     routes:
@@ -505,187 +498,187 @@
       - host: [ example.com, localhost ]
         backend: [ 10.0.0.2:25566 ]
         cachePingTTL: 3m
-
-
-
- - - -
-
-
- - -
-
-
-

- Live Configuration -

-

- Configure without restarts -

-

- Gate watches your config file for changes and applies them instantly - without disconnecting players. Switch modes, add servers, or update - settings - all while staying live. -

-
- - - +
+
- - - -
+ +
+
+
+

+ Scale your Minecraft network today +

+

+ Start using Gate in under 5 minutes. Join hundreds of server owners + building better networks with Minekube technology. +

- -
-
-
-

- Scale your Minecraft network today -

-

- Start using Gate in under 5 minutes. Join hundreds of server owners - building better networks with Minekube technology. -

+ +
+
+
650+
+
Discord Members
+
+
+
+
650+
+
GitHub Stars
+
+
- -
-
-
650+
-
Discord Members
-
-
-
-
650+
-
GitHub Stars
-
-
+ + - - +
@@ -985,13 +974,6 @@ button svg { transition: all 0.2s ease; } -/* Ensure sections don't overflow viewport */ -.py-24 { - min-height: min-content; - max-height: 100vh; - overflow-y: auto; -} - /* Ensure content is properly spaced */ .mx-auto { height: fit-content; @@ -1013,4 +995,32 @@ img.object-contain { img.object-contain:hover { opacity: 1; } + +/* Hide scrollbar but keep functionality */ +.scrollbar-hide { + -ms-overflow-style: none; /* IE and Edge */ + scrollbar-width: none; /* Firefox */ +} +.scrollbar-hide::-webkit-scrollbar { + display: none; /* Chrome, Safari and Opera */ +} + +/* Ensure the command text doesn't wrap but scrolls horizontally */ +.whitespace-nowrap { + white-space: nowrap; +} + +/* Improve command box text handling */ +.truncate { + text-overflow: ellipsis; +} + +/* Hide scrollbar but keep functionality */ +.scrollbar-hide { + -ms-overflow-style: none; + scrollbar-width: none; +} +.scrollbar-hide::-webkit-scrollbar { + display: none; +} From 024c3919984605ec587cb78dcdef52584386f139 Mon Sep 17 00:00:00 2001 From: robinbraemer Date: Wed, 20 Nov 2024 15:25:28 +0100 Subject: [PATCH 30/32] fix icons on mobile --- .../theme/components/LandingAfter.vue | 150 +++++++++++++----- 1 file changed, 107 insertions(+), 43 deletions(-) diff --git a/.web/docs/.vitepress/theme/components/LandingAfter.vue b/.web/docs/.vitepress/theme/components/LandingAfter.vue index 24f61242..f2c16b8c 100644 --- a/.web/docs/.vitepress/theme/components/LandingAfter.vue +++ b/.web/docs/.vitepress/theme/components/LandingAfter.vue @@ -39,7 +39,7 @@
- + @@ -246,12 +248,16 @@
-
+
-
-
config:
+        
+        
+
+
+
+
+ config.yml + +
+
config:
   lite:
     enabled: true
     routes:
@@ -522,327 +521,320 @@
       - host: [ example.com, localhost ]
         backend: [ 10.0.0.2:25566 ]
         cachePingTTL: 3m
-
-
-
- - -
- -
-
-
-

- Live Configuration -

-

- Configure without restarts -

-

- Gate watches your config file for changes and applies them - instantly without disconnecting players. Switch modes, add - servers, or update settings - all while staying live. -

-
+ + +
+
+
-
-
- - -
-
- - - -
-
-

- Auto Reload -

-

- Changes apply instantly without restarts -

-
-
-
+ +
+
+
+

+ Live Configuration +

+

+ Configure without restarts +

+

+ Gate watches your config file for changes and applies them instantly + without disconnecting players. Switch modes, add servers, or update + settings - all while staying live. +

+
- - +
+ + + + - -
-
-
-
-
- config.yml - -
-
bind: 0.0.0.0:25565
-servers:
-  lobby:
-    addr: 127.0.0.1:25566
-  minigames:
-    addr: 127.0.0.1:25567
-try:
-  - lobby
-  - minigames
-
-
+ + +
+
+ + +
- - -
- +

- Learn More About Configuration → - + Safe Validation +

+

+ Changes validated before applying +

-
-
- - -
-
-
-

- Scale your Minecraft network today -

-

- Start using Gate in under 5 minutes. Join hundreds of server - owners building better networks with Minekube technology. -

- - -
-
-
- 650+ -
-
- Discord Members -
-
-
-
-
- 650+ -
-
- GitHub Stars -
-
-
+ - -
- + +
+ +
+

- - - - Join Discord - + Switch Modes +

+

+ Toggle between Lite and Connect modes +

+
+ +
- -
- +
+
+
+
+ +
bind: 0.0.0.0:25565
+servers:
+  lobby:
+    addr: 127.0.0.1:25566
+  minigames:
+    addr: 127.0.0.1:25567
+try:
+  - lobby
+  - minigames
+
+
+
+ + + +
+
+
+ + +
+
+
+

+ Scale your Minecraft network today +

+

+ Start using Gate in under 5 minutes. Join hundreds of server owners + building better networks with Minekube technology. +

+ + +
+
+
+ 650+ +
+
+ Discord Members +
+
+
+
+
+ 650+ +
+
+ GitHub Stars
+ + + + + +
diff --git a/web/docs/.vitepress/theme/components/LandingAfter.vue b/web/docs/.vitepress/theme/components/LandingAfter.vue new file mode 100644 index 00000000..0519ecba --- /dev/null +++ b/web/docs/.vitepress/theme/components/LandingAfter.vue @@ -0,0 +1 @@ + \ No newline at end of file