aboutsummaryrefslogtreecommitdiff
path: root/internal/net/server.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/net/server.go')
-rw-r--r--internal/net/server.go153
1 files changed, 113 insertions, 40 deletions
diff --git a/internal/net/server.go b/internal/net/server.go
index 08d427f..7e73bc9 100644
--- a/internal/net/server.go
+++ b/internal/net/server.go
@@ -1,11 +1,13 @@
package net
import (
- "bufio"
+ "crypto/tls"
"fmt"
"log"
"net"
- "strings"
+ "net/http"
+
+ "thirdcollapse/internal/config"
)
type SessionState int
@@ -30,14 +32,13 @@ const (
)
type Session struct {
- Conn net.Conn
- Reader *bufio.Reader
- State SessionState
- Account *AccountEntry
- Player interface{} // *player.Player once character is selected
- PendingChar string // char being renamed/deleted
- PendingPass string // first password during signup
- Disconnecting bool
+ Conn Conn
+ State SessionState
+ Account *AccountEntry
+ Player interface{}
+ PendingChar string
+ PendingPass string
+ Disconnecting bool
DisconnectTicks int
}
@@ -49,14 +50,18 @@ type AccountEntry struct {
}
type Server struct {
- listener net.Listener
- hub *Hub
+ config *config.Config
+ telnetLn net.Listener
+ httpServer *http.Server
+ httpsServer *http.Server
+ hub *Hub
+ handler func(*Session, string)
}
type Hub struct {
- sessions map[*Session]bool
- rooms map[int]map[*Session]bool
- onRemove func(*Session)
+ sessions map[*Session]bool
+ rooms map[int]map[*Session]bool
+ onRemove func(*Session)
}
func NewHub() *Hub {
@@ -125,12 +130,40 @@ func (h *Hub) PlayersInRoom(roomID int) []*Session {
return out
}
-func NewServer(addr string) (*Server, error) {
- l, err := net.Listen("tcp", addr)
- if err != nil {
- return nil, err
+func NewServer(cfg *config.Config) (*Server, error) {
+ s := &Server{
+ config: cfg,
+ hub: NewHub(),
+ }
+
+ if cfg.Telnet.Enabled {
+ addr := fmt.Sprintf(":%d", cfg.Telnet.Port)
+ ln, err := net.Listen("tcp", addr)
+ if err != nil {
+ return nil, fmt.Errorf("telnet listen: %w", err)
+ }
+ s.telnetLn = ln
+ }
+
+ if cfg.HTTP.Enabled {
+ s.httpServer = &http.Server{
+ Addr: fmt.Sprintf(":%d", cfg.HTTP.Port),
+ Handler: newHTTPMux(s),
+ }
+ }
+
+ if cfg.HTTPS.Enabled {
+ if cfg.HTTPS.CertFile == "" || cfg.HTTPS.KeyFile == "" {
+ return nil, fmt.Errorf("https enabled but cert_file and key_file are required")
+ }
+ s.httpsServer = &http.Server{
+ Addr: fmt.Sprintf(":%d", cfg.HTTPS.Port),
+ Handler: newHTTPMux(s),
+ TLSConfig: &tls.Config{MinVersion: tls.VersionTLS12},
+ }
}
- return &Server{listener: l, hub: NewHub()}, nil
+
+ return s, nil
}
func (s *Server) Hub() *Hub {
@@ -138,31 +171,66 @@ func (s *Server) Hub() *Hub {
}
func (s *Server) ListenAndServe(handler func(*Session, string)) error {
+ s.handler = handler
+
+ if s.telnetLn != nil {
+ go s.serveTelnet()
+ }
+
+ if s.httpServer != nil {
+ go s.serveHTTP()
+ }
+
+ if s.httpsServer != nil {
+ go s.serveHTTPS()
+ }
+
+ if s.telnetLn == nil && s.httpServer == nil && s.httpsServer == nil {
+ return fmt.Errorf("no listeners configured")
+ }
+
+ select {}
+}
+
+func (s *Server) serveTelnet() {
for {
- conn, err := s.listener.Accept()
+ conn, err := s.telnetLn.Accept()
if err != nil {
- return err
+ return
}
- session := &Session{
- Conn: conn,
- Reader: bufio.NewReader(conn),
- State: StateAccountName,
+ sess := &Session{
+ Conn: newTCPConn(conn),
+ State: StateAccountName,
}
- s.hub.Add(session)
- go s.handleSession(session, handler)
+ s.hub.Add(sess)
+ go s.handleSession(sess, s.handler)
}
}
-func (s *Server) handleSession(session *Session, handler func(*Session, string)) {
+func (s *Server) serveHTTP() {
+ err := s.httpServer.ListenAndServe()
+ if err != nil && err != http.ErrServerClosed {
+ log.Printf("http server error: %v", err)
+ }
+}
+
+func (s *Server) serveHTTPS() {
+ err := s.httpsServer.ListenAndServeTLS(s.config.HTTPS.CertFile, s.config.HTTPS.KeyFile)
+ if err != nil && err != http.ErrServerClosed {
+ log.Printf("https server error: %v", err)
+ }
+}
+
+func (s *Server) handleSession(sess *Session, handler func(*Session, string)) {
defer func() {
if r := recover(); r != nil {
log.Printf("session panic: %v", r)
}
- s.hub.Remove(session)
- session.Conn.Close()
+ s.hub.Remove(sess)
+ sess.Close()
}()
- _, _ = session.Conn.Write([]byte("\033[2J\033[H")) // clear screen
+ sess.Conn.Write([]byte("\033[2J\033[H"))
welcomeart := `
, 3333333 333 333 333 3333333 3333333
@@ -179,29 +247,30 @@ func (s *Server) handleSession(session *Session, handler func(*Session, string))
:!! !!: !!! !!: !!: !!: !!! !!: !:! !!:
:: :: : : :. : : ::.: : : ::.: : : : : : ::.: : : :: :::
-
`
- session.Write(welcomeart)
- session.Write("ACCOUNT NAME> ")
+ sess.Write(welcomeart)
+ sess.Write("What's your account name? ")
for {
- line, err := session.Reader.ReadString('\n')
+ line, err := sess.Conn.ReadMessage()
if err != nil {
log.Printf("session read error: %v", err)
return
}
- line = strings.TrimSpace(line)
- handler(session, line)
+ if len(line) > 1024 {
+ line = line[:1024]
+ }
+ handler(sess, line)
}
}
func (sess *Session) Write(msg string) {
- _, _ = sess.Conn.Write([]byte(msg))
+ sess.Conn.Write([]byte(msg))
}
func (sess *Session) WriteLine(msg string) {
- _, _ = sess.Conn.Write([]byte(msg + "\r\n"))
+ sess.Conn.Write([]byte(msg + "\r\n"))
}
func (sess *Session) WriteLines(lines ...string) {
@@ -213,3 +282,7 @@ func (sess *Session) WriteLines(lines ...string) {
func (sess *Session) Writef(format string, args ...interface{}) {
sess.Write(fmt.Sprintf(format, args...))
}
+
+func (sess *Session) Close() error {
+ return sess.Conn.Close()
+}