2021-09-06 02:03:27 -07:00
|
|
|
package proxy
|
2021-08-27 09:59:27 -07:00
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"log"
|
|
|
|
"net"
|
2021-09-01 01:31:43 -07:00
|
|
|
"sync"
|
2021-08-27 09:59:27 -07:00
|
|
|
|
|
|
|
"github.com/anon55555/mt"
|
2021-08-28 05:18:56 -07:00
|
|
|
"github.com/anon55555/mt/rudp"
|
2021-08-27 09:59:27 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
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 {
|
2021-08-27 09:59:27 -07:00
|
|
|
mt.Peer
|
2021-09-06 02:03:27 -07:00
|
|
|
srv *ServerConn
|
2021-09-03 04:26:44 -07:00
|
|
|
mu sync.RWMutex
|
2021-08-27 09:59:27 -07:00
|
|
|
|
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
|
2021-08-27 09:59:27 -07:00
|
|
|
|
|
|
|
auth struct {
|
|
|
|
method mt.AuthMethods
|
|
|
|
salt, srpA, srpB, srpM, srpK []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
lang string
|
|
|
|
|
2021-08-29 10:45:20 -07:00
|
|
|
major, minor, patch uint8
|
|
|
|
reservedVer uint8
|
|
|
|
versionStr string
|
|
|
|
formspecVer uint16
|
|
|
|
|
2021-08-27 09:59:27 -07:00
|
|
|
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
|
2021-09-01 04:27:53 -07:00
|
|
|
|
2021-09-13 03:52:37 -07:00
|
|
|
modChs map[string]struct{}
|
|
|
|
modChsMu sync.RWMutex
|
2021-08-27 09:59:27 -07:00
|
|
|
}
|
|
|
|
|
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-08-27 09:59:27 -07:00
|
|
|
|
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-08-27 09:59:27 -07:00
|
|
|
|
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-08-27 09:59:27 -07:00
|
|
|
}
|
|
|
|
|
2021-09-06 02:03:27 -07:00
|
|
|
func handleClt(cc *ClientConn) {
|
2021-08-27 09:59:27 -07:00
|
|
|
for {
|
|
|
|
pkt, err := cc.Recv()
|
|
|
|
if err != nil {
|
|
|
|
if errors.Is(err, net.ErrClosed) {
|
2021-08-28 05:18:56 -07:00
|
|
|
if errors.Is(cc.WhyClosed(), rudp.ErrTimedOut) {
|
2021-09-06 02:03:27 -07:00
|
|
|
cc.Log("<->", "timeout")
|
2021-08-28 05:18:56 -07:00
|
|
|
} else {
|
2021-09-06 02:03:27 -07:00
|
|
|
cc.Log("<->", "disconnect")
|
2021-08-28 05:18:56 -07:00
|
|
|
}
|
|
|
|
|
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()
|
2021-09-04 03:35:42 -07:00
|
|
|
|
2021-09-05 03:56:21 -07:00
|
|
|
cc.server().mu.Lock()
|
2021-08-28 08:12:59 -07:00
|
|
|
cc.server().clt = nil
|
2021-09-05 03:56:21 -07:00
|
|
|
cc.server().mu.Unlock()
|
|
|
|
|
|
|
|
cc.mu.Lock()
|
2021-08-28 08:12:59 -07:00
|
|
|
cc.srv = nil
|
2021-09-04 03:35:42 -07:00
|
|
|
cc.mu.Unlock()
|
2021-08-28 08:12:59 -07:00
|
|
|
}
|
|
|
|
|
2021-08-27 09:59:27 -07:00
|
|
|
break
|
|
|
|
}
|
|
|
|
|
2021-09-13 03:14:11 -07:00
|
|
|
cc.Log("->", err)
|
2021-08-27 09:59:27 -07:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2021-09-13 03:52:37 -07:00
|
|
|
cc.process(pkt)
|
2021-08-27 09:59:27 -07:00
|
|
|
}
|
|
|
|
}
|