1.20.80 support (#1)
This commit is contained in:
151
example-proxy.go
Normal file
151
example-proxy.go
Normal file
@@ -0,0 +1,151 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/akmalfairuz/legacy-version/legacyver"
|
||||
"github.com/pelletier/go-toml"
|
||||
"github.com/sandertv/gophertunnel/minecraft"
|
||||
"github.com/sandertv/gophertunnel/minecraft/auth"
|
||||
"golang.org/x/oauth2"
|
||||
"log"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// The following program implements a proxy that forwards players from one local address to a remote address.
|
||||
func main() {
|
||||
config := readConfig()
|
||||
token, err := auth.RequestLiveToken()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
src := auth.RefreshTokenSource(token)
|
||||
|
||||
p, err := minecraft.NewForeignStatusProvider(config.Connection.RemoteAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
listener, err := minecraft.ListenConfig{
|
||||
StatusProvider: p,
|
||||
AcceptedProtocols: []minecraft.Protocol{
|
||||
legacyver.New748(),
|
||||
legacyver.New729(),
|
||||
legacyver.New712(),
|
||||
legacyver.New686(),
|
||||
legacyver.New685(),
|
||||
legacyver.New671(),
|
||||
},
|
||||
}.Listen("raknet", config.Connection.LocalAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer listener.Close()
|
||||
for {
|
||||
c, err := listener.Accept()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go handleConn(c.(*minecraft.Conn), listener, config, src)
|
||||
}
|
||||
}
|
||||
|
||||
// handleConn handles a new incoming minecraft.Conn from the minecraft.Listener passed.
|
||||
func handleConn(conn *minecraft.Conn, listener *minecraft.Listener, config config, src oauth2.TokenSource) {
|
||||
serverConn, err := minecraft.Dialer{
|
||||
TokenSource: src,
|
||||
ClientData: conn.ClientData(),
|
||||
}.Dial("raknet", config.Connection.RemoteAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var g sync.WaitGroup
|
||||
g.Add(2)
|
||||
go func() {
|
||||
if err := conn.StartGame(serverConn.GameData()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
g.Done()
|
||||
}()
|
||||
go func() {
|
||||
if err := serverConn.DoSpawn(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
g.Done()
|
||||
}()
|
||||
g.Wait()
|
||||
|
||||
go func() {
|
||||
defer listener.Disconnect(conn, "connection lost")
|
||||
defer serverConn.Close()
|
||||
for {
|
||||
pk, err := conn.ReadPacket()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err := serverConn.WritePacket(pk); err != nil {
|
||||
var disc minecraft.DisconnectError
|
||||
if ok := errors.As(err, &disc); ok {
|
||||
_ = listener.Disconnect(conn, disc.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
defer serverConn.Close()
|
||||
defer listener.Disconnect(conn, "connection lost")
|
||||
for {
|
||||
pk, err := serverConn.ReadPacket()
|
||||
if err != nil {
|
||||
var disc minecraft.DisconnectError
|
||||
if ok := errors.As(err, &disc); ok {
|
||||
_ = listener.Disconnect(conn, disc.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
if err := conn.WritePacket(pk); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
type config struct {
|
||||
Connection struct {
|
||||
LocalAddress string
|
||||
RemoteAddress string
|
||||
}
|
||||
}
|
||||
|
||||
func readConfig() config {
|
||||
c := config{}
|
||||
if _, err := os.Stat("config.toml"); os.IsNotExist(err) {
|
||||
f, err := os.Create("config.toml")
|
||||
if err != nil {
|
||||
log.Fatalf("create config: %v", err)
|
||||
}
|
||||
data, err := toml.Marshal(c)
|
||||
if err != nil {
|
||||
log.Fatalf("encode default config: %v", err)
|
||||
}
|
||||
if _, err := f.Write(data); err != nil {
|
||||
log.Fatalf("write default config: %v", err)
|
||||
}
|
||||
_ = f.Close()
|
||||
}
|
||||
data, err := os.ReadFile("config.toml")
|
||||
if err != nil {
|
||||
log.Fatalf("read config: %v", err)
|
||||
}
|
||||
if err := toml.Unmarshal(data, &c); err != nil {
|
||||
log.Fatalf("decode config: %v", err)
|
||||
}
|
||||
if c.Connection.LocalAddress == "" {
|
||||
c.Connection.LocalAddress = "0.0.0.0:19132"
|
||||
}
|
||||
data, _ = toml.Marshal(c)
|
||||
if err := os.WriteFile("config.toml", data, 0644); err != nil {
|
||||
log.Fatalf("write config: %v", err)
|
||||
}
|
||||
return c
|
||||
}
|
||||
Reference in New Issue
Block a user