X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/blobdiff_plain/67d1f7231b807771b57c8f0e63dd796a03130eaf..fcac5b5d3ff250c5d3f5a25411810d9b1251ed41:/hotline/client.go diff --git a/hotline/client.go b/hotline/client.go index 6abe623..ffd0fb3 100644 --- a/hotline/client.go +++ b/hotline/client.go @@ -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, ) }