]> git.r.bdr.sh - rbdr/mobius/blobdiff - hotline/client.go
Make UserFlags public
[rbdr/mobius] / hotline / client.go
index 6abe62322bfd3c95d6fc99f0b5137190a682edb5..ffd0fb3c1cb2c1607848c52278dcfcdf9c9ecd6a 100644 (file)
@@ -9,7 +9,6 @@ import (
        "fmt"
        "github.com/gdamore/tcell/v2"
        "github.com/rivo/tview"
-       "github.com/stretchr/testify/mock"
        "go.uber.org/zap"
        "gopkg.in/yaml.v3"
        "math/big"
@@ -49,10 +48,8 @@ func (cp *ClientPrefs) IconBytes() []byte {
        return iconBytes
 }
 
-func (cp *ClientPrefs) AddBookmark(name, addr, login, pass string) error {
+func (cp *ClientPrefs) AddBookmark(name, addr, login, pass string) {
        cp.Bookmarks = append(cp.Bookmarks, Bookmark{Addr: addr, Login: login, Password: pass})
-
-       return nil
 }
 
 func readConfig(cfgPath string) (*ClientPrefs, error) {
@@ -82,18 +79,24 @@ type Client struct {
 
        Pref *ClientPrefs
 
-       Handlers map[uint16]ClientTHandler
+       Handlers map[uint16]ClientHandler
 
        UI *UI
 
        Inbox chan *Transaction
 }
 
+type ClientHandler func(*Client, *Transaction) ([]Transaction, error)
+
+func (c *Client) HandleFunc(transactionID uint16, handler ClientHandler) {
+       c.Handlers[transactionID] = handler
+}
+
 func NewClient(username string, logger *zap.SugaredLogger) *Client {
        c := &Client{
                Logger:      logger,
                activeTasks: make(map[uint32]*Transaction),
-               Handlers:    make(map[uint16]ClientTHandler),
+               Handlers:    make(map[uint16]ClientHandler),
        }
        c.Pref = &ClientPrefs{Username: username}
 
@@ -154,70 +157,27 @@ type ClientTHandler interface {
        Handle(*Client, *Transaction) ([]Transaction, error)
 }
 
-type mockClientHandler struct {
-       mock.Mock
-}
-
-func (mh *mockClientHandler) Handle(cc *Client, t *Transaction) ([]Transaction, error) {
-       args := mh.Called(cc, t)
-       return args.Get(0).([]Transaction), args.Error(1)
-}
-
-var clientHandlers = map[uint16]ClientTHandler{
-       // Server initiated
-       TranChatMsg: ClientTransaction{
-               Name:    "TranChatMsg",
-               Handler: handleClientChatMsg,
-       },
-       TranLogin: ClientTransaction{
-               Name:    "TranLogin",
-               Handler: handleClientTranLogin,
-       },
-       TranShowAgreement: ClientTransaction{
-               Name:    "TranShowAgreement",
-               Handler: handleClientTranShowAgreement,
-       },
-       TranUserAccess: ClientTransaction{
-               Name:    "TranUserAccess",
-               Handler: handleClientTranUserAccess,
-       },
-       TranGetUserNameList: ClientTransaction{
-               Name:    "TranGetUserNameList",
-               Handler: handleClientGetUserNameList,
-       },
-       TranNotifyChangeUser: ClientTransaction{
-               Name:    "TranNotifyChangeUser",
-               Handler: handleNotifyChangeUser,
-       },
-       TranNotifyDeleteUser: ClientTransaction{
-               Name:    "TranNotifyDeleteUser",
-               Handler: handleNotifyDeleteUser,
-       },
-       TranGetMsgs: ClientTransaction{
-               Name:    "TranNotifyDeleteUser",
-               Handler: handleGetMsgs,
-       },
-       TranGetFileNameList: ClientTransaction{
-               Name:    "TranGetFileNameList",
-               Handler: handleGetFileNameList,
-       },
-       TranServerMsg: ClientTransaction{
-               Name:    "TranServerMsg",
-               Handler: handleTranServerMsg,
-       },
-       TranKeepAlive: ClientTransaction{
-               Name: "TranKeepAlive",
-               Handler: func(client *Client, transaction *Transaction) (t []Transaction, err error) {
-                       return t, err
-               },
+var clientHandlers = map[uint16]ClientHandler{
+       TranChatMsg:          handleClientChatMsg,
+       TranLogin:            handleClientTranLogin,
+       TranShowAgreement:    handleClientTranShowAgreement,
+       TranUserAccess:       handleClientTranUserAccess,
+       TranGetUserNameList:  handleClientGetUserNameList,
+       TranNotifyChangeUser: handleNotifyChangeUser,
+       TranNotifyDeleteUser: handleNotifyDeleteUser,
+       TranGetMsgs:          handleGetMsgs,
+       TranGetFileNameList:  handleGetFileNameList,
+       TranServerMsg:        handleTranServerMsg,
+       TranKeepAlive: func(client *Client, transaction *Transaction) (t []Transaction, err error) {
+               return t, err
        },
 }
 
 func handleTranServerMsg(c *Client, t *Transaction) (res []Transaction, err error) {
-       time := time.Now().Format(time.RFC850)
+       now := time.Now().Format(time.RFC850)
 
        msg := strings.ReplaceAll(string(t.GetField(FieldData).Data), "\r", "\n")
-       msg += "\n\nAt " + time
+       msg += "\n\nAt " + now
        title := fmt.Sprintf("| Private Message From:   %s |", t.GetField(FieldUserName).Data)
 
        msgBox := tview.NewTextView().SetScrollable(true)
@@ -226,7 +186,7 @@ func handleTranServerMsg(c *Client, t *Transaction) (res []Transaction, err erro
        msgBox.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
                switch event.Key() {
                case tcell.KeyEscape:
-                       c.UI.Pages.RemovePage("serverMsgModal" + time)
+                       c.UI.Pages.RemovePage("serverMsgModal" + now)
                }
                return event
        })
@@ -239,14 +199,14 @@ func handleTranServerMsg(c *Client, t *Transaction) (res []Transaction, err erro
                        AddItem(nil, 0, 1, false), 0, 2, true).
                AddItem(nil, 0, 1, false)
 
-       c.UI.Pages.AddPage("serverMsgModal"+time, centeredFlex, true, true)
+       c.UI.Pages.AddPage("serverMsgModal"+now, centeredFlex, true, true)
        c.UI.App.Draw() // TODO: errModal doesn't render without this.  wtf?
 
        return res, err
 }
 
 func (c *Client) showErrMsg(msg string) {
-       time := time.Now().Format(time.RFC850)
+       t := time.Now().Format(time.RFC850)
 
        title := "| Error |"
 
@@ -256,7 +216,7 @@ func (c *Client) showErrMsg(msg string) {
        msgBox.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
                switch event.Key() {
                case tcell.KeyEscape:
-                       c.UI.Pages.RemovePage("serverMsgModal" + time)
+                       c.UI.Pages.RemovePage("serverMsgModal" + t)
                }
                return event
        })
@@ -269,7 +229,7 @@ func (c *Client) showErrMsg(msg string) {
                        AddItem(nil, 0, 1, false), 0, 2, true).
                AddItem(nil, 0, 1, false)
 
-       c.UI.Pages.AddPage("serverMsgModal"+time, centeredFlex, true, true)
+       c.UI.Pages.AddPage("serverMsgModal"+t, centeredFlex, true, true)
        c.UI.App.Draw() // TODO: errModal doesn't render without this.  wtf?
 }
 
@@ -345,7 +305,6 @@ func handleGetFileNameList(c *Client, t *Transaction) (res []Transaction, err er
                        node.SetReference(&fn)
                        root.AddChild(node)
                }
-
        }
 
        centerFlex := tview.NewFlex().
@@ -464,7 +423,7 @@ func (c *Client) renderUserList() {
        c.UI.userList.Clear()
        for _, u := range c.UserList {
                flagBitmap := big.NewInt(int64(binary.BigEndian.Uint16(u.Flags)))
-               if flagBitmap.Bit(userFlagAdmin) == 1 {
+               if flagBitmap.Bit(UserFlagAdmin) == 1 {
                        _, _ = fmt.Fprintf(c.UI.userList, "[red::b]%s[-:-:-]\n", u.Name)
                } else {
                        _, _ = fmt.Fprintf(c.UI.userList, "%s\n", u.Name)
@@ -571,11 +530,13 @@ func (c *Client) Connect(address, login, passwd string) (err error) {
        return nil
 }
 
+const keepaliveInterval = 300 * time.Second
+
 func (c *Client) keepalive() error {
        for {
-               time.Sleep(300 * time.Second)
+               time.Sleep(keepaliveInterval)
                _ = c.Send(*NewTransaction(TranKeepAlive, nil))
-               c.Logger.Infow("Sent keepalive ping")
+               c.Logger.Debugw("Sent keepalive ping")
        }
 }
 
@@ -628,21 +589,18 @@ func (c *Client) LogIn(login string, password string) error {
 
 func (c *Client) Send(t Transaction) error {
        requestNum := binary.BigEndian.Uint16(t.Type)
-       tID := binary.BigEndian.Uint32(t.ID)
-
-       // handler := TransactionHandlers[requestNum]
 
        // if transaction is NOT reply, add it to the list to transactions we're expecting a response for
        if t.IsReply == 0 {
-               c.activeTasks[tID] = &t
+               c.activeTasks[binary.BigEndian.Uint32(t.ID)] = &t
        }
 
-       var n int
-       var err error
        b, err := t.MarshalBinary()
        if err != nil {
                return err
        }
+
+       var n int
        if n, err = c.Connection.Write(b); err != nil {
                return err
        }
@@ -662,18 +620,17 @@ func (c *Client) HandleTransaction(t *Transaction) error {
                t.Type = origT.Type
        }
 
-       requestNum := binary.BigEndian.Uint16(t.Type)
-       c.Logger.Debugw("Received Transaction", "RequestType", requestNum)
-
-       if handler, ok := c.Handlers[requestNum]; ok {
-               outT, _ := handler.Handle(c, t)
+       if handler, ok := c.Handlers[binary.BigEndian.Uint16(t.Type)]; ok {
+               outT, _ := handler(c, t)
                for _, t := range outT {
-                       c.Send(t)
+                       if err := c.Send(t); err != nil {
+                               return err
+                       }
                }
        } else {
                c.Logger.Debugw(
                        "Unimplemented transaction type received",
-                       "RequestID", requestNum,
+                       "RequestID", t.Type,
                        "TransactionID", t.ID,
                )
        }