LastMUD/internal/server/server.go
2025-06-20 16:26:39 +03:00

110 lines
1.9 KiB
Go

package server
import (
"context"
"net"
"sync"
"time"
"code.haedhutner.dev/mvv/LastMUD/internal/game"
"code.haedhutner.dev/mvv/LastMUD/internal/logging"
)
type Server struct {
ctx context.Context
wg *sync.WaitGroup
listener *net.TCPListener
connections []*Connection
game *game.LastMUDGame
}
func CreateServer(ctx context.Context, wg *sync.WaitGroup, port string) (srv *Server, err error) {
logging.Info(" _ _ __ __ _ _ ____ ")
logging.Info(" | | __ _ ___| |_| \\/ | | | | _ \\ ")
logging.Info(" | | / _` / __| __| |\\/| | | | | | | | ")
logging.Info(" | |__| (_| \\__ \\ |_| | | | |_| | |_| | ")
logging.Info(" |_____\\__,_|___/\\__|_| |_|\\___/|____/ ")
logging.Info(" ")
addr, err := net.ResolveTCPAddr("tcp", port)
if err != nil {
logging.Error(err)
return nil, err
}
ln, err := net.ListenTCP("tcp", addr)
if err != nil {
logging.Error(err)
return nil, err
}
logging.Info("Starting server, listening on port ", port)
srv = &Server{
ctx: ctx,
wg: wg,
listener: ln,
connections: []*Connection{},
}
srv.game = game.CreateGame(ctx, srv.wg)
srv.wg.Add(1)
go srv.listen()
return
}
func (srv *Server) listen() {
defer srv.wg.Done()
defer srv.shutdown()
for {
srv.listener.SetDeadline(time.Now().Add(1 * time.Second))
if srv.shouldStop() {
break
}
conn, err := srv.listener.Accept()
if err != nil {
continue
}
tcpConn, ok := conn.(*net.TCPConn)
if !ok {
logging.Warn("Attempted invalid connection from", conn.RemoteAddr())
continue
}
c := CreateConnection(tcpConn, srv.ctx, srv.wg)
srv.connections = append(srv.connections, c)
}
}
func (srv *Server) shutdown() {
logging.Info("Stopping Server...")
err := srv.listener.Close()
if err != nil {
logging.Error(err)
}
}
func (srv *Server) shouldStop() bool {
select {
case <-srv.ctx.Done():
return true
default:
return false
}
}