12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- package main
- import (
- "bytes"
- "errors"
- "fmt"
- "net"
- "os"
- "time"
- )
- type Client struct {
- server *Server
- conn net.Conn
- Ip string
- Line string
- Prompt string
- PromptWLine bool
- }
- func NewClient(server *Server, conn net.Conn) *Client {
- ip := conn.RemoteAddr().String()
- c := &Client{
- server: server,
- conn: conn,
- Ip: ip,
- Line: "",
- Prompt: "Login: ",
- PromptWLine: true,
- }
- c.Write("\xff\xfb\x01\xff\xfb\x03\xff\xfd\x10")
- Drain(c.conn, 3)
- go c.reader()
- c.Write("Login: ")
- c.InsertWrite("Trade Trek\r\n")
- c.InsertWrite("v1.0 Apollo@21:1/236\r\n\r\n")
- return c
- }
- func (c *Client) Write(text string) {
- c.conn.Write([]byte(text))
- }
- var clearLine = bytes.Repeat([]byte("\b \b"), 500)
- func (c *Client) InsertWrite(text string) {
- c.conn.Write(clearLine)
- c.Write(text)
- if len(c.Prompt) != 0 {
- c.Write(c.Prompt)
- if c.PromptWLine {
- c.Write(c.Line)
- }
- }
- }
- func (c *Client) reader() {
- var (
- buf []byte = make([]byte, 1024) // 1kb
- read int
- err error
- )
- for {
- c.conn.SetReadDeadline(time.Now().Add(time.Duration(200) * time.Millisecond))
- read, err = c.conn.Read(buf)
- if err != nil {
- if errors.Is(err, net.ErrClosed) || errors.Is(err, os.ErrClosed) {
- return
- } else if errors.Is(err, os.ErrDeadlineExceeded) {
- if read != 0 {
- c.process(string(buf[0:read]))
- }
- continue
- } else {
- fmt.Printf("%s ERR> %v", c.Ip, err)
- continue
- }
- }
- if read != 0 {
- c.process(string(buf[0:read]))
- }
- }
- }
- func (c *Client) process(input string) {
- // Process the input as far as ENTER/RETURN and keys being pressed
- // This will require a state machine to track where the client is (Login, Password, Sitting in their ship, Accessing computer, etc)
- // For now we'll just echo it back
- c.Write(input)
- }
|