Skip to content

Commit d22711d

Browse files
authored
feat: route dynamic servers through managed Via
Route API-registered Gate servers through managed Via using vialite v0.2.8 dynamic backends. Preserve custom ServerDialer backends such as Connect through a local bridge, clean up dynamic Via resources, and document dynamic Via behavior.
1 parent b7fbf94 commit d22711d

10 files changed

Lines changed: 711 additions & 29 deletions

File tree

.web/docs/guide/compatibility.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,26 @@ Gate provides excellent support for **modded servers** including Fabric and NeoF
1414
Gate is compatible with Minecraft 1.8 through the latest version
1515
and we maintainers update Gate as soon as a new Minecraft version is released.
1616

17+
## Java Version Translation
18+
19+
Gate can run managed Via translation in classic proxy mode. When `config.via.enabled`
20+
is true, Gate starts vialite, keeps it on the latest stable release by default,
21+
and routes backend connections through Via-compatible protocol translation.
22+
This applies to both configured servers and API-registered servers, so dynamic
23+
Connect/session backends can be joined by Java clients even when the backend
24+
Minecraft version differs from the client version.
25+
26+
```yaml
27+
config:
28+
via:
29+
enabled: true
30+
```
31+
32+
Lite mode does not run managed Via translation. Dynamic API-registered backend
33+
translation uses the default subprocess mode; embedded mode is limited to
34+
configured servers. For controlled deployments, Gate still supports exact
35+
vialite version pins, offline mode, and local artifact paths.
36+
1737
## Paper <VPBadge>Recommended</VPBadge>
1838
1939
We highly recommend using [Paper](https://papermc.io/) for running a server in most cases.

README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ graph LR
6363
## Java Version Compatibility
6464

6565
Gate can start **Via-powered backend protocol translation** through managed
66-
vialite, so Java clients can join backend servers running different Minecraft
67-
versions without running a separate Via sidecar.
66+
vialite, so Java clients can join configured or API-registered backend servers
67+
running different Minecraft versions without running a separate Via sidecar.
6868

6969
Enable managed Via in classic proxy mode with:
7070

@@ -76,9 +76,13 @@ config:
7676
7777
Gate starts the native vialite subprocess, resolves the latest stable vialite
7878
release automatically, downloads the checksummed artifact into the local cache,
79-
and routes backend connections through it. Exact release pins, offline mode, and
80-
local artifact paths remain available for controlled deployments, but no manual
81-
version setting is required for the default path.
79+
and routes backend connections through it. Dynamic backends registered through
80+
Gate's Go API are added to vialite at runtime, which lets Connect-style session
81+
backends use the same version compatibility path as static config servers. Exact
82+
release pins, offline mode, and local artifact paths remain available for
83+
controlled deployments, but no manual version setting is required for the
84+
default path. Dynamic API-registered backend translation uses the default
85+
subprocess mode; embedded mode is limited to configured servers.
8286
8387
## Gate Lite Mode
8488

config.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,13 @@ config:
9595
# Can also be set via environment variable: GATE_BUNGEEGUARD_SECRET
9696
#bungeeGuardSecret: secret_here
9797
# Via backend protocol translation for Gate classic mode.
98-
# This starts vialite at startup and routes configured classic backend connections
99-
# through Via-compatible translation before Gate dials the backend.
98+
# This starts vialite at startup and routes configured or API-registered classic
99+
# backend connections through Via-compatible translation before Gate dials the backend.
100100
# Not used in lite mode. Changes require a Gate restart.
101101
via:
102102
enabled: false
103103
# Options: subprocess, embedded. Subprocess uses released vialite artifacts and is the default.
104+
# API-registered dynamic backends use subprocess mode; embedded mode only translates configured servers.
104105
mode: subprocess
105106
# Optional local bind for the native runtime's internal loopback listener.
106107
#bind: 127.0.0.1:0

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ require (
3535
go.minekube.com/common v0.3.0
3636
go.minekube.com/connect v0.6.2
3737
go.minekube.com/geyserlite v0.3.14
38-
go.minekube.com/vialite v0.2.7
38+
go.minekube.com/vialite v0.2.8
3939
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0
4040
go.opentelemetry.io/otel v1.41.0
4141
go.opentelemetry.io/otel/metric v1.41.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,8 @@ go.minekube.com/connect v0.6.2 h1:RajPc7YgqygcOviV2g4xetL3J0Wzi8b/lsYXUzIltxE=
254254
go.minekube.com/connect v0.6.2/go.mod h1:28k11I4RyzUfAL3AkOXt3atzjeOFAC8eqbCMwsYKAb0=
255255
go.minekube.com/geyserlite v0.3.14 h1:+cSN9o/b5jEOHeym/uXvt5MEoGnrYloJidrVe9K9pWo=
256256
go.minekube.com/geyserlite v0.3.14/go.mod h1:yy0/M0zSD6X3FoQMwtmf5Jn+7YFM7AZWamKw0E8fnOE=
257-
go.minekube.com/vialite v0.2.7 h1:G5OuIt0qN4xfowW2rahZhb8zzMark5nI6AqubVBn6gQ=
258-
go.minekube.com/vialite v0.2.7/go.mod h1:W9L1l8/b/GsLmkw1BW4wijaaPj/zV3OdrtYJgWdkhxE=
257+
go.minekube.com/vialite v0.2.8 h1:3xEuciKORVeuDdCOY6w2BSnenVYti0ZS8xlqCUX42nk=
258+
go.minekube.com/vialite v0.2.8/go.mod h1:W9L1l8/b/GsLmkw1BW4wijaaPj/zV3OdrtYJgWdkhxE=
259259
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
260260
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
261261
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=

pkg/configs/config.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,13 @@ config:
9595
# Can also be set via environment variable: GATE_BUNGEEGUARD_SECRET
9696
#bungeeGuardSecret: secret_here
9797
# Via backend protocol translation for Gate classic mode.
98-
# This starts vialite at startup and routes configured classic backend connections
99-
# through Via-compatible translation before Gate dials the backend.
98+
# This starts vialite at startup and routes configured or API-registered classic
99+
# backend connections through Via-compatible translation before Gate dials the backend.
100100
# Not used in lite mode. Changes require a Gate restart.
101101
via:
102102
enabled: false
103103
# Options: subprocess, embedded. Subprocess uses released vialite artifacts and is the default.
104+
# API-registered dynamic backends use subprocess mode; embedded mode only translates configured servers.
104105
mode: subprocess
105106
# Optional local bind for the native runtime's internal loopback listener.
106107
#bind: 127.0.0.1:0

pkg/edition/java/proxy/proxy.go

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,10 +496,39 @@ func (p *Proxy) Register(info ServerInfo) (RegisteredServer, error) {
496496
name := strings.ToLower(info.Name())
497497

498498
p.muS.Lock()
499-
defer p.muS.Unlock()
500499
if exists, ok := p.servers[name]; ok {
500+
p.muS.Unlock()
501+
return exists, ErrServerAlreadyExists
502+
}
503+
p.muS.Unlock()
504+
505+
var viaAdded bool
506+
if _, alreadyVia := info.(*viaServerInfo); !alreadyVia && p.via != nil {
507+
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
508+
defer cancel()
509+
enabled, err := p.via.AddBackend(ctx, info)
510+
if err != nil {
511+
return nil, fmt.Errorf("error adding via backend %q: %w", info.Name(), err)
512+
}
513+
if enabled {
514+
viaAdded = true
515+
info = newViaServerInfo(info, p.via)
516+
}
517+
}
518+
519+
p.muS.Lock()
520+
if exists, ok := p.servers[name]; ok {
521+
p.muS.Unlock()
522+
if viaAdded {
523+
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
524+
defer cancel()
525+
if err := p.via.RemoveBackend(ctx, info.Name()); err != nil {
526+
p.log.Error(err, "could not remove duplicate via backend", "server", info.Name())
527+
}
528+
}
501529
return exists, ErrServerAlreadyExists
502530
}
531+
defer p.muS.Unlock()
503532
rs := newRegisteredServer(info)
504533
p.servers[name] = rs
505534
// Note: We don't mark API-registered servers as config-managed
@@ -528,6 +557,13 @@ func (p *Proxy) Unregister(info ServerInfo) bool {
528557
}
529558
delete(p.servers, name)
530559
delete(p.configServers, name) // Clean up config tracking
560+
if p.via != nil {
561+
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
562+
defer cancel()
563+
if err := p.via.RemoveBackend(ctx, info.Name()); err != nil {
564+
p.log.Error(err, "could not remove via backend", "server", info.Name())
565+
}
566+
}
531567

532568
p.log.Info("unregistered backend server",
533569
"name", info.Name(), "addr", info.Addr())

0 commit comments

Comments
 (0)