client.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. return c
  32. }
  33. func (c *Client) Write(text string) {
  34. c.conn.Write([]byte(text))
  35. }
  36. var clearLine = bytes.Repeat([]byte("\b \b"), 500)
  37. func (c *Client) InsertWrite(text string) {
  38. c.conn.Write(clearLine)
  39. c.Write(text)
  40. if len(c.Prompt) != 0 {
  41. c.Write(c.Prompt)
  42. if c.PromptWLine {
  43. c.Write(c.Line)
  44. }
  45. }
  46. }
  47. func (c *Client) reader() {
  48. var (
  49. buf []byte = make([]byte, 1024) // 1kb
  50. read int
  51. err error
  52. )
  53. for {
  54. c.conn.SetReadDeadline(time.Now().Add(time.Duration(200) * time.Millisecond))
  55. read, err = c.conn.Read(buf)
  56. if err != nil {
  57. if errors.Is(err, net.ErrClosed) || errors.Is(err, os.ErrClosed) {
  58. return
  59. } else if errors.Is(err, os.ErrDeadlineExceeded) {
  60. if read != 0 {
  61. c.process(string(buf[0:read]))
  62. }
  63. continue
  64. } else {
  65. fmt.Printf("%s ERR> %v", c.Ip, err)
  66. continue
  67. }
  68. }
  69. if read != 0 {
  70. c.process(string(buf[0:read]))
  71. }
  72. }
  73. }
  74. func (c *Client) process(input string) {
  75. // Process the input as far as ENTER/RETURN and keys being pressed
  76. // This will require a state machine to track where the client is (Login, Password, Sitting in their ship, Accessing computer, etc)
  77. // For now we'll just echo it back
  78. c.Write(input)
  79. }