diff options
| author | historia <[not public]> | 2026-06-16 23:37:50 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-06-16 23:37:50 -0400 |
| commit | 389e307f205f9b7edf604fb9f86e1038ead736ef (patch) | |
| tree | 595095b5877cc2b0513d31fb126303d8796cc311 /internal/net/server.go | |
| parent | 085e728d22a3369bd110b77409914cfbe9ebe611 (diff) | |
| download | thehouseoficarus-389e307f205f9b7edf604fb9f86e1038ead736ef.tar.gz | |
feat: major xterm256 color overhaul, see worldbuilding docs.
Diffstat (limited to 'internal/net/server.go')
| -rw-r--r-- | internal/net/server.go | 137 |
1 files changed, 119 insertions, 18 deletions
diff --git a/internal/net/server.go b/internal/net/server.go index 1b6c99b..203539c 100644 --- a/internal/net/server.go +++ b/internal/net/server.go @@ -6,8 +6,10 @@ import ( "log" "net" "net/http" + "strings" - "thirdcollapse/internal/config" + "thehouseoficarus/internal/color" + "thehouseoficarus/internal/config" ) type SessionState int @@ -30,6 +32,7 @@ const ( StateTalk StateDropAllConfirm StateCookRecipe + StateColorChoice ) type Session struct { @@ -51,11 +54,13 @@ type AccountEntry struct { Characters []string Aliases map[string]string Colors map[string]string + Options map[string]any } type Server struct { config *config.Config telnetLn net.Listener + telnetTLSLn net.Listener httpServer *http.Server httpsServer *http.Server hub *Hub @@ -149,6 +154,26 @@ func NewServer(cfg *config.Config) (*Server, error) { s.telnetLn = ln } + if cfg.TelnetTLS.Enabled { + if cfg.TelnetTLS.CertFile == "" || cfg.TelnetTLS.KeyFile == "" { + return nil, fmt.Errorf("telnet_tls enabled but cert_file and key_file are required") + } + cert, err := tls.LoadX509KeyPair(cfg.TelnetTLS.CertFile, cfg.TelnetTLS.KeyFile) + if err != nil { + return nil, fmt.Errorf("telnet_tls cert: %w", err) + } + tlsCfg := &tls.Config{ + Certificates: []tls.Certificate{cert}, + MinVersion: tls.VersionTLS12, + } + addr := fmt.Sprintf(":%d", cfg.TelnetTLS.Port) + ln, err := net.Listen("tcp", addr) + if err != nil { + return nil, fmt.Errorf("telnet_tls listen: %w", err) + } + s.telnetTLSLn = tls.NewListener(ln, tlsCfg) + } + if cfg.HTTP.Enabled { s.httpServer = &http.Server{ Addr: fmt.Sprintf(":%d", cfg.HTTP.Port), @@ -181,6 +206,10 @@ func (s *Server) ListenAndServe(handler func(*Session, string)) error { go s.serveTelnet() } + if s.telnetTLSLn != nil { + go s.serveTelnetTLS() + } + if s.httpServer != nil { go s.serveHTTP() } @@ -189,7 +218,7 @@ func (s *Server) ListenAndServe(handler func(*Session, string)) error { go s.serveHTTPS() } - if s.telnetLn == nil && s.httpServer == nil && s.httpsServer == nil { + if s.telnetLn == nil && s.telnetTLSLn == nil && s.httpServer == nil && s.httpsServer == nil { return fmt.Errorf("no listeners configured") } @@ -211,6 +240,21 @@ func (s *Server) serveTelnet() { } } +func (s *Server) serveTelnetTLS() { + for { + conn, err := s.telnetTLSLn.Accept() + if err != nil { + return + } + sess := &Session{ + Conn: newTCPConn(conn), + State: StateAccountName, + } + s.hub.Add(sess) + go s.handleSession(sess, s.handler) + } +} + func (s *Server) serveHTTP() { err := s.httpServer.ListenAndServe() if err != nil && err != http.ErrServerClosed { @@ -225,6 +269,53 @@ func (s *Server) serveHTTPS() { } } +func artColor(r rune) string { + switch r { + case '@': + return color.FgCode("ansi", 4) + case '!', ':', '.': + return color.StyleCode("dim") + color.FgCode("ansi", 4) + case ',': + return color.FgCode("ansi", 5) + case '*': + return color.FgCode("ansi", 5) + case '+', '|', '-': + return color.FgCode("ansi", 3) + } + return "" +} + +func colorizeRunes(s string) string { + var sb strings.Builder + current := "" + for _, r := range s { + want := artColor(r) + if want != current { + if current != "" { + sb.WriteString(color.Reset) + } + if want != "" { + sb.WriteString(want) + } + current = want + } + sb.WriteRune(r) + } + if current != "" { + sb.WriteString(color.Reset) + } + return sb.String() +} + +func colorizeArt(art string) string { + welcomeText := "welcome to the house of icarus" + before, after, found := strings.Cut(art, welcomeText) + if found { + return colorizeRunes(before) + color.FgCode("ansi", 7) + welcomeText + color.Reset + colorizeRunes(after) + } + return colorizeRunes(art) +} + func (s *Server) handleSession(sess *Session, handler func(*Session, string)) { defer func() { if r := recover(); r != nil { @@ -236,22 +327,32 @@ func (s *Server) handleSession(sess *Session, handler func(*Session, string)) { sess.Conn.Write([]byte("\033[2J\033[H")) - welcomeart := ` - , 3333333 333 333 333 3333333 3333333 - | 33! 33! 333 33! 33! 333 33! 333 ':. + - -+- * 3!! 3!3!3!3! !!3 3!3!!3! 3!3 !3! '::._ * - | !!: !!: !!! !!: !!: :!! !!: !!! '._) - : : : : : : : : :: : : , - . * , - , welcome to third collapse . * - - 3333333 333333 333 , 333 333333 3333333 333333 33333333 - !33 33! 333 33! 33! 33! 333 33! 333 !33 33! - !3! 3!3 !3! 3!! 3!! + 3!3!3!3! 3!33!3! !33!! 3!!!:! - :!! !!: !!! !!: !!: !!: !!! !!: !:! !!: - :: :: : : :. : : ::.: : : ::.: : : : : : ::.: : : :: ::: - -` + welcomeart := colorizeArt(` + | * + * + -+- + . , | +. , . , + * + @@@@@@@ @@@ @@@ @@@@@@@@ @@@ @@@ @@@@@@ @@@ @@@ @@@@@@ @@@@@@@@ + + @@! @@! @@@ @@! + @@! @@@ @@! @@@ @@! @@@ !@@ @@! + @!! @!@!@!@! @!!!:! @!@!@!@! @!@ !@! @!@ !@! !@@!! @!!!:! * + !!: !!: !!! !!: . !!: !!! !!: !!! !!: !!! !:! !!: + : : : : : :: ::: : : : : :. : :.:: : ::.: : : :: ::: . + . + + * welcome to the house of icarus , , + , . + @@@@@@ @@@@@@@@ @@@ @@@@@@@ @@@@@@ @@@@@@@ @@@ @@@ @@@@@@ + @@! @@@ @@! , @@! !@@ @@! @@@ @@! @@@ @@! @@@ !@@ + | @!@ !@! @!!!:! !!@ !@! @!@!@!@! @!@!!@! @!@ !@! !@@!! + -+- !!: !!! !!: !!: :!! !!: !!! !!: :!! !!: !!! !:! + | : :. : : . : :: :: : : : : : : : :.:: : ::.: : + , + . + , . + . , + * . , * + + +`) + sess.Write(welcomeart) sess.Write("What's your account name? ") |
