Initial commit
This commit is contained in:
133
network/server.go
Normal file
133
network/server.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/cubexteam/Frodding/net/info"
|
||||
"github.com/cubexteam/Frodding/raknet"
|
||||
"github.com/cubexteam/Frodding/resources"
|
||||
)
|
||||
|
||||
type Logger interface {
|
||||
Infof(format string, args ...any)
|
||||
Warnf(format string, args ...any)
|
||||
Errorf(format string, args ...any)
|
||||
Debugf(format string, args ...any)
|
||||
Chat(name, message string)
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
cfg *resources.Config
|
||||
log Logger
|
||||
rak *raknet.Server
|
||||
mu sync.RWMutex
|
||||
sessions map[int64]*Session
|
||||
|
||||
onShutdown func()
|
||||
}
|
||||
|
||||
func NewServer(cfg *resources.Config, log Logger) *Server {
|
||||
return &Server{
|
||||
cfg: cfg,
|
||||
log: log,
|
||||
sessions: make(map[int64]*Session),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) SetShutdownHook(fn func()) {
|
||||
s.onShutdown = fn
|
||||
}
|
||||
|
||||
func (s *Server) Start() error {
|
||||
guid := int64(0x526f6464696e6721)
|
||||
|
||||
motdFunc := func() string {
|
||||
protocol := info.LatestProtocol
|
||||
versionTag := info.LatestGameVersionNetwork
|
||||
if s.cfg.MotdProtocol > 0 {
|
||||
protocol = s.cfg.MotdProtocol
|
||||
if vt, ok := info.SupportedProtocols[int32(protocol)]; ok {
|
||||
versionTag = vt
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("MCPE;%s;%d;%s;%d;%d;%d;%s;Survival",
|
||||
s.cfg.ServerName, protocol, versionTag,
|
||||
s.OnlineCount(), s.cfg.MaxPlayers,
|
||||
guid, s.cfg.ServerName,
|
||||
)
|
||||
}
|
||||
|
||||
s.rak = raknet.NewServer(guid, motdFunc, s)
|
||||
s.log.Infof("Starting on %s:%d (MCBE %s, protocol %d)",
|
||||
s.cfg.ServerIP, s.cfg.ServerPort,
|
||||
info.LatestGameVersionNetwork, info.LatestProtocol)
|
||||
err := s.rak.Start(s.cfg.ServerIP, s.cfg.ServerPort)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.log.Infof("RakNet server started!")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) Shutdown() {
|
||||
s.rak.Shutdown()
|
||||
if s.onShutdown != nil {
|
||||
s.onShutdown()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) OnConnect(rs *raknet.Session) {
|
||||
s.log.Debugf("[NET] New connection guid=%d from %s", rs.GUID, rs.Addr)
|
||||
sess := NewSession(s, rs)
|
||||
s.mu.Lock()
|
||||
s.sessions[rs.GUID] = sess
|
||||
s.mu.Unlock()
|
||||
}
|
||||
|
||||
func (s *Server) OnPacket(rs *raknet.Session, payload []byte) {
|
||||
s.mu.RLock()
|
||||
sess, ok := s.sessions[rs.GUID]
|
||||
s.mu.RUnlock()
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
sess.HandlePayload(payload)
|
||||
}
|
||||
|
||||
func (s *Server) OnDisconnect(rs *raknet.Session) {
|
||||
s.mu.Lock()
|
||||
sess, ok := s.sessions[rs.GUID]
|
||||
delete(s.sessions, rs.GUID)
|
||||
s.mu.Unlock()
|
||||
if ok && sess.Spawned {
|
||||
s.BroadcastMessage(fmt.Sprintf("§e%s left the game", sess.Username))
|
||||
s.log.Infof("%s left the game", sess.Username)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) BroadcastMessage(msg string) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
for _, sess := range s.sessions {
|
||||
if sess.Spawned {
|
||||
sess.SendMessage(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) OnlineCount() int {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
return len(s.sessions)
|
||||
}
|
||||
|
||||
func (s *Server) GetSessions() []*Session {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
list := make([]*Session, 0, len(s.sessions))
|
||||
for _, sess := range s.sessions {
|
||||
list = append(list, sess)
|
||||
}
|
||||
return list
|
||||
}
|
||||
Reference in New Issue
Block a user