mt-multiserver-proxy/client_conn.go

147 lines
2.6 KiB
Go
Raw Permalink Normal View History

2021-09-06 02:03:27 -07:00
package proxy
import (
"errors"
"log"
"net"
"sync"
"github.com/anon55555/mt"
"github.com/anon55555/mt/rudp"
)
type clientState uint8
const (
csCreated clientState = iota
csInit
csActive
csSudo
)
2021-09-10 03:47:19 -07:00
// A ClientConn is a connection to a minetest client.
2021-09-06 02:03:27 -07:00
type ClientConn struct {
mt.Peer
2021-09-06 02:03:27 -07:00
srv *ServerConn
2021-09-03 04:26:44 -07:00
mu sync.RWMutex
2021-09-13 03:14:11 -07:00
logger *log.Logger
2021-09-03 04:26:44 -07:00
cstate clientState
cstateMu sync.RWMutex
name string
initCh chan struct{}
hopMu sync.Mutex
auth struct {
method mt.AuthMethods
salt, srpA, srpB, srpM, srpK []byte
}
lang string
major, minor, patch uint8
reservedVer uint8
versionStr string
formspecVer uint16
itemDefs []mt.ItemDef
aliases []struct{ Alias, Orig string }
nodeDefs []mt.NodeDef
p0Map param0Map
p0SrvMap param0SrvMap
media []mediaFile
2021-08-27 11:40:07 -07:00
playerCAO, currentCAO mt.AOID
2021-08-30 11:06:20 -07:00
playerListInit bool
modChs map[string]struct{}
modChsMu sync.RWMutex
}
2021-09-10 03:47:19 -07:00
// Name returns the player name of the ClientConn.
2021-09-09 11:53:15 -07:00
func (cc *ClientConn) Name() string { return cc.name }
2021-09-09 10:39:59 -07:00
2021-09-06 02:03:27 -07:00
func (cc *ClientConn) server() *ServerConn {
2021-09-03 04:26:44 -07:00
cc.mu.RLock()
defer cc.mu.RUnlock()
return cc.srv
}
2021-09-10 03:47:19 -07:00
// ServerName returns the name of the current upstream server
// of the ClientConn. It is empty if there is no upstream connection.
2021-09-09 08:27:37 -07:00
func (cc *ClientConn) ServerName() string {
srv := cc.server()
if srv != nil {
return srv.name
}
return ""
}
2021-09-06 02:03:27 -07:00
func (cc *ClientConn) state() clientState {
2021-09-03 04:26:44 -07:00
cc.cstateMu.RLock()
defer cc.cstateMu.RUnlock()
return cc.cstate
}
2021-09-06 02:03:27 -07:00
func (cc *ClientConn) setState(state clientState) {
2021-09-03 04:26:44 -07:00
cc.cstateMu.Lock()
defer cc.cstateMu.Unlock()
cc.cstate = state
}
2021-09-10 03:47:19 -07:00
// Init returns a channel that is closed
// when the ClientConn enters the csActive state.
2021-09-06 02:03:27 -07:00
func (cc *ClientConn) Init() <-chan struct{} { return cc.initCh }
2021-09-10 03:47:19 -07:00
// Log logs an interaction with the ClientConn.
// dir indicates the direction of the interaction.
2021-09-06 02:03:27 -07:00
func (cc *ClientConn) Log(dir string, v ...interface{}) {
2021-09-13 03:14:11 -07:00
cc.logger.Println(append([]interface{}{dir}, v...)...)
}
2021-09-06 02:03:27 -07:00
func handleClt(cc *ClientConn) {
for {
pkt, err := cc.Recv()
if err != nil {
if errors.Is(err, net.ErrClosed) {
if errors.Is(cc.WhyClosed(), rudp.ErrTimedOut) {
2021-09-06 02:03:27 -07:00
cc.Log("<->", "timeout")
} else {
2021-09-06 02:03:27 -07:00
cc.Log("<->", "disconnect")
}
2021-09-09 11:07:36 -07:00
if cc.Name() != "" {
2021-09-04 11:25:00 -07:00
playersMu.Lock()
2021-09-09 11:07:36 -07:00
delete(players, cc.Name())
2021-09-04 11:25:00 -07:00
playersMu.Unlock()
}
2021-08-28 08:12:59 -07:00
if cc.server() != nil {
cc.server().Close()
cc.server().mu.Lock()
2021-08-28 08:12:59 -07:00
cc.server().clt = nil
cc.server().mu.Unlock()
cc.mu.Lock()
2021-08-28 08:12:59 -07:00
cc.srv = nil
cc.mu.Unlock()
2021-08-28 08:12:59 -07:00
}
break
}
2021-09-13 03:14:11 -07:00
cc.Log("->", err)
continue
}
cc.process(pkt)
}
}