client.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package main
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "net"
  7. "os"
  8. "time"
  9. )
  10. type Client struct {
  11. server *Server
  12. conn net.Conn
  13. Ip string
  14. Line string
  15. Prompt string
  16. PromptWLine bool
  17. }
  18. func NewClient(server *Server, conn net.Conn) *Client {
  19. ip := conn.RemoteAddr().String()
  20. c := &Client{
  21. server: server,
  22. conn: conn,
  23. Ip: ip,
  24. Line: "",
  25. Prompt: "Login: ",
  26. PromptWLine: true,
  27. }
  28. c.Write("\xff\xfb\x01\xff\xfb\x03\xff\xfd\x10")
  29. Drain(c.conn, 3)
  30. go c.reader()
  31. c.Write("Login: ")
  32. c.InsertWrite("Trade Trek\r\n")
  33. c.InsertWrite("v1.0 Apollo@21:1/236\r\n\r\n")
  34. return c
  35. }
  36. func (c *Client) Write(text string) {
  37. c.conn.Write([]byte(text))
  38. }
  39. var clearLine = bytes.Repeat([]byte("\b \b"), 1000)
  40. func (c *Client) InsertWrite(text string) {
  41. c.conn.Write(clearLine)
  42. c.Write(text)
  43. if len(c.Prompt) != 0 {
  44. c.Write(c.Prompt)
  45. if c.PromptWLine {
  46. c.Write(c.Line)
  47. }
  48. }
  49. }
  50. func (c *Client) reader() {
  51. var (
  52. buf []byte = make([]byte, 1024) // 1kb
  53. read int
  54. err error
  55. )
  56. for {
  57. c.conn.SetReadDeadline(time.Now().Add(time.Duration(200) * time.Millisecond))
  58. read, err = c.conn.Read(buf)
  59. if err != nil {
  60. if errors.Is(err, net.ErrClosed) || errors.Is(err, os.ErrClosed) {
  61. return
  62. } else if errors.Is(err, os.ErrDeadlineExceeded) {
  63. if read != 0 {
  64. c.process(string(buf[0:read]))
  65. }
  66. continue
  67. } else {
  68. fmt.Printf("%s ERR> %v", c.Ip, err)
  69. continue
  70. }
  71. }
  72. if read != 0 {
  73. c.process(string(buf[0:read]))
  74. }
  75. }
  76. }
  77. func (c *Client) process(input string) {
  78. // Process the input as far as ENTER/RETURN and keys being pressed
  79. // This will require a state machine to track where the client is (Login, Password, Sitting in their ship, Accessing computer, etc)
  80. // For now we'll just echo it back
  81. c.Write(input)
  82. }