Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TCP alternative to RakNet #76

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ module github.com/paroxity/portal
go 1.18

require (
github.com/df-mc/dragonfly v0.9.2
github.com/go-gl/mathgl v1.0.0
github.com/google/uuid v1.3.0
github.com/klauspost/compress v1.15.15
github.com/mattn/go-colorable v0.1.11
github.com/sandertv/gophertunnel v1.27.2
github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e
Expand All @@ -13,21 +15,22 @@ require (
)

require (
github.com/brentp/intintmap v0.0.0-20190211203843-30dc0ade9af9 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/df-mc/atomic v1.10.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/klauspost/compress v1.15.13 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/muhammadmuzzammil1998/jsonc v1.0.0 // indirect
github.com/sandertv/go-raknet v1.12.0 // indirect
golang.org/x/crypto v0.5.0 // indirect
golang.org/x/exp v0.0.0-20230206171751-46f607a40771 // indirect
golang.org/x/image v0.3.0 // indirect
golang.org/x/net v0.5.0 // indirect
golang.org/x/oauth2 v0.4.0 // indirect
golang.org/x/sys v0.4.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.6.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
21 changes: 16 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/brentp/intintmap v0.0.0-20190211203843-30dc0ade9af9 h1:/G0ghZwrhou0Wq21qc1vXXMm/t/aKWkALWwITptKbE0=
github.com/brentp/intintmap v0.0.0-20190211203843-30dc0ade9af9/go.mod h1:TOk10ahXejq9wkEaym3KPRNeuR/h5Jx+s8QRWIa2oTM=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/df-mc/atomic v1.10.0 h1:0ZuxBKwR/hxcFGorKiHIp+hY7hgY+XBTzhCYD2NqSEg=
github.com/df-mc/atomic v1.10.0/go.mod h1:Gw9rf+rPIbydMjA329Jn4yjd/O2c/qusw3iNp4tFGSc=
github.com/df-mc/dragonfly v0.9.2 h1:VoffCnFiiOd03P5X+ZsbuZkSuNELYh1Zc51v+0A/3HA=
github.com/df-mc/dragonfly v0.9.2/go.mod h1:hGGjGbLxpcn7nVTZOrk8kPfeGGntaMOqqcbuugZauyI=
github.com/fatih/set v0.2.1 h1:nn2CaJyknWE/6txyUDGwysr3G5QC6xWB/PtVjPBbeaA=
github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI=
github.com/go-gl/mathgl v1.0.0 h1:t9DznWJlXxxjeeKLIdovCOVJQk/GzDEL7h/h+Ro2B68=
Expand All @@ -17,8 +25,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/klauspost/compress v1.15.13 h1:NFn1Wr8cfnenSJSA46lLq4wHCcBzKTSjnBIexDMMOV0=
github.com/klauspost/compress v1.15.13/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw=
github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4=
github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
Expand All @@ -35,6 +43,8 @@ github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e h1:7q6NSFZDeGfvv
github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e/go.mod h1:DkpGd78rljTxKAnTDPFqXSGxvETQnJyuSOQwsHycqfs=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
Expand All @@ -45,6 +55,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
golang.org/x/exp v0.0.0-20230206171751-46f607a40771 h1:xP7rWLUr1e1n2xkK5YB4LI0hPEy3LJC6Wk+D4pGlOJg=
golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.3.0 h1:HTDXbdK9bjfSWkPzDJIw89W8CAtfFGduujWs33NLLsg=
golang.org/x/image v0.3.0/go.mod h1:fXd9211C/0VTlYuAcOhW8dY/RtEJqODXOWBDpmYBf+A=
Expand All @@ -67,8 +79,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand All @@ -93,4 +105,3 @@ gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
20 changes: 14 additions & 6 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ import (

// Server represents a server connected to the proxy which players can join and play on.
type Server struct {
name string
address string
name string
address string
useRakNet bool

playerCount atomic.Int64
}

// New creates a new Server with the provided name, group and address.
func New(name, address string) *Server {
// New creates a new Server with the provided name, group and address as well as if the connection should use the RakNet
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// New creates a new Server with the provided name, group and address as well as if the connection should use the RakNet
// New creates a new Server with the provided name and address as well as if the connection should use the RakNet

// protocol or not.
func New(name, address string, useRakNet bool) *Server {
s := &Server{
name: name,
address: address,
name: name,
address: address,
useRakNet: useRakNet,
}

return s
Expand All @@ -33,6 +36,11 @@ func (s *Server) Address() string {
return s.address
}

// UseRakNet returns if a connection should use the RakNet protocol when connecting to the server.
func (s *Server) UseRakNet() bool {
return s.useRakNet
}

// IncrementPlayerCount increments the player count of the server.
func (s *Server) IncrementPlayerCount() {
s.playerCount.Add(1)
Expand Down
28 changes: 28 additions & 0 deletions session/server_conn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package session

import (
"github.com/sandertv/gophertunnel/minecraft"
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
"io"
"time"
)

// ServerConn represents a connection that can be used between the proxy and a server to communicate on behalf of a client.
type ServerConn interface {
io.Closer
// GameData returns specific game data set to the connection for the player to be initialised with. This data is
// obtained from the server during the login process.
GameData() minecraft.GameData
// DoSpawnTimeout starts the game for the client in the server with a timeout after which an error is returned if the
// client has not yet spawned by that time. DoSpawnTimeout will start the spawning sequence using the game data found
// in conn.GameData(), which was sent earlier by the server.
DoSpawnTimeout(timeout time.Duration) error
// ReadPacket reads a packet from the Conn, depending on the packet ID that is found in front of the packet data. If
// a read deadline is set, an error is returned if the deadline is reached before any packet is received. ReadPacket
// must not be called on multiple goroutines simultaneously. If the packet read was not implemented, a *packet.Unknown
// is returned, containing the raw payload of the packet read.
ReadPacket() (packet.Packet, error)
// WritePacket encodes the packet passed and writes it to the Conn. The encoded data is buffered until the next 20th
// of a second, after which the data is flushed and sent over the connection.
WritePacket(packet.Packet) error
}
24 changes: 16 additions & 8 deletions session/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/paroxity/portal/event"
"github.com/paroxity/portal/internal"
"github.com/paroxity/portal/server"
"github.com/paroxity/portal/session/tcpprotocol"
"github.com/sandertv/gophertunnel/minecraft"
"github.com/sandertv/gophertunnel/minecraft/protocol"
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
Expand Down Expand Up @@ -34,8 +35,8 @@ type Session struct {
loginMu sync.RWMutex
serverMu sync.RWMutex
server *server.Server
serverConn *minecraft.Conn
tempServerConn *minecraft.Conn
serverConn ServerConn
tempServerConn ServerConn

entities *i64set.Set
playerList *b16set.Set
Expand Down Expand Up @@ -106,13 +107,20 @@ func New(conn *minecraft.Conn, store *Store, loadBalancer LoadBalancer, log inte

// dial dials a new connection to the provided server. It then returns the connection between the proxy and
// that server, along with any error that may have occurred.
func (s *Session) dial(srv *server.Server) (*minecraft.Conn, error) {
func (s *Session) dial(srv *server.Server) (ServerConn, error) {
i := s.conn.IdentityData()
i.XUID = ""
return minecraft.Dialer{
ClientData: s.conn.ClientData(),
IdentityData: i,
}.Dial("raknet", srv.Address())
if srv.UseRakNet() {
return minecraft.Dialer{
ClientData: s.conn.ClientData(),
IdentityData: i,
}.Dial("raknet", srv.Address())
}
return tcpprotocol.Dialer{
ClientData: s.conn.ClientData(),
IdentityData: i,
EnableClientCache: s.conn.ClientCacheEnabled(),
}.Dial("tcp", srv.Address(), s.conn.RemoteAddr().String())
}

// login performs the initial login sequence for the session.
Expand Down Expand Up @@ -153,7 +161,7 @@ func (s *Session) Server() *server.Server {
}

// ServerConn returns the connection for the session's current server.
func (s *Session) ServerConn() *minecraft.Conn {
func (s *Session) ServerConn() ServerConn {
s.waitForLogin()
s.serverMu.RLock()
defer s.serverMu.RUnlock()
Expand Down
Loading