"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"
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) {
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}
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)
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
})
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 |"
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
})
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?
}
node.SetReference(&fn)
root.AddChild(node)
}
-
}
centerFlex := tview.NewFlex().
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)
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")
}
}
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
}
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,
)
}