From: Jeff Halter Date: Mon, 27 Mar 2023 04:10:03 +0000 (-0700) Subject: Initial refactor to split client from protocol package X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/commitdiff_plain/d005ef04cfaa26943e6dd33807d741577ffb232a?ds=sidebyside;hp=-c Initial refactor to split client from protocol package --- d005ef04cfaa26943e6dd33807d741577ffb232a diff --git a/cmd/mobius-hotline-client/main.go b/cmd/mobius-hotline-client/main.go index 4bd40c9..33100bf 100644 --- a/cmd/mobius-hotline-client/main.go +++ b/cmd/mobius-hotline-client/main.go @@ -71,7 +71,7 @@ func main() { cancelRoot() }() - client := hotline.NewClient(*configDir, logger) + client := hotline.NewUIClient(*configDir, logger) client.DebugBuf = db client.UI.Start() diff --git a/hotline/account.go b/hotline/account.go index 9a0fb7d..c51162d 100644 --- a/hotline/account.go +++ b/hotline/account.go @@ -18,13 +18,13 @@ type Account struct { // Read implements io.Reader interface for Account func (a *Account) Read(p []byte) (n int, err error) { fields := []Field{ - NewField(fieldUserName, []byte(a.Name)), - NewField(fieldUserLogin, negateString([]byte(a.Login))), - NewField(fieldUserAccess, a.Access[:]), + NewField(FieldUserName, []byte(a.Name)), + NewField(FieldUserLogin, negateString([]byte(a.Login))), + NewField(FieldUserAccess, a.Access[:]), } if bcrypt.CompareHashAndPassword([]byte(a.Password), []byte("")) != nil { - fields = append(fields, NewField(fieldUserPassword, []byte("x"))) + fields = append(fields, NewField(FieldUserPassword, []byte("x"))) } fieldCount := make([]byte, 2) diff --git a/hotline/client.go b/hotline/client.go index c7c1463..6abe623 100644 --- a/hotline/client.go +++ b/hotline/client.go @@ -1,6 +1,7 @@ package hotline import ( + "bufio" "bytes" "embed" "encoding/binary" @@ -72,11 +73,6 @@ type Client struct { cfgPath string DebugBuf *DebugBuffer Connection net.Conn - Login *[]byte - Password *[]byte - Flags *[]byte - ID *[]byte - Version []byte UserAccess []byte filePath []string UserList []User @@ -84,16 +80,27 @@ type Client struct { activeTasks map[uint32]*Transaction serverName string - pref *ClientPrefs + Pref *ClientPrefs - Handlers map[uint16]clientTHandler + Handlers map[uint16]ClientTHandler UI *UI Inbox chan *Transaction } -func NewClient(cfgPath string, logger *zap.SugaredLogger) *Client { +func NewClient(username string, logger *zap.SugaredLogger) *Client { + c := &Client{ + Logger: logger, + activeTasks: make(map[uint32]*Transaction), + Handlers: make(map[uint16]ClientTHandler), + } + c.Pref = &ClientPrefs{Username: username} + + return c +} + +func NewUIClient(cfgPath string, logger *zap.SugaredLogger) *Client { c := &Client{ cfgPath: cfgPath, Logger: logger, @@ -106,7 +113,7 @@ func NewClient(cfgPath string, logger *zap.SugaredLogger) *Client { if err != nil { logger.Fatal(fmt.Sprintf("unable to read config file %s\n", cfgPath)) } - c.pref = prefs + c.Pref = prefs return c } @@ -134,16 +141,16 @@ func randomBanner() string { return fmt.Sprintf("\n\n\nWelcome to...\n\n[red::b]%s[-:-:-]\n\n", file) } -type clientTransaction struct { +type ClientTransaction struct { Name string Handler func(*Client, *Transaction) ([]Transaction, error) } -func (ch clientTransaction) Handle(cc *Client, t *Transaction) ([]Transaction, error) { +func (ch ClientTransaction) Handle(cc *Client, t *Transaction) ([]Transaction, error) { return ch.Handler(cc, t) } -type clientTHandler interface { +type ClientTHandler interface { Handle(*Client, *Transaction) ([]Transaction, error) } @@ -156,50 +163,50 @@ func (mh *mockClientHandler) Handle(cc *Client, t *Transaction) ([]Transaction, return args.Get(0).([]Transaction), args.Error(1) } -var clientHandlers = map[uint16]clientTHandler{ +var clientHandlers = map[uint16]ClientTHandler{ // Server initiated - tranChatMsg: clientTransaction{ - Name: "tranChatMsg", + TranChatMsg: ClientTransaction{ + Name: "TranChatMsg", Handler: handleClientChatMsg, }, - tranLogin: clientTransaction{ - Name: "tranLogin", + TranLogin: ClientTransaction{ + Name: "TranLogin", Handler: handleClientTranLogin, }, - tranShowAgreement: clientTransaction{ - Name: "tranShowAgreement", + TranShowAgreement: ClientTransaction{ + Name: "TranShowAgreement", Handler: handleClientTranShowAgreement, }, - tranUserAccess: clientTransaction{ - Name: "tranUserAccess", + TranUserAccess: ClientTransaction{ + Name: "TranUserAccess", Handler: handleClientTranUserAccess, }, - tranGetUserNameList: clientTransaction{ - Name: "tranGetUserNameList", + TranGetUserNameList: ClientTransaction{ + Name: "TranGetUserNameList", Handler: handleClientGetUserNameList, }, - tranNotifyChangeUser: clientTransaction{ - Name: "tranNotifyChangeUser", + TranNotifyChangeUser: ClientTransaction{ + Name: "TranNotifyChangeUser", Handler: handleNotifyChangeUser, }, - tranNotifyDeleteUser: clientTransaction{ - Name: "tranNotifyDeleteUser", + TranNotifyDeleteUser: ClientTransaction{ + Name: "TranNotifyDeleteUser", Handler: handleNotifyDeleteUser, }, - tranGetMsgs: clientTransaction{ - Name: "tranNotifyDeleteUser", + TranGetMsgs: ClientTransaction{ + Name: "TranNotifyDeleteUser", Handler: handleGetMsgs, }, - tranGetFileNameList: clientTransaction{ - Name: "tranGetFileNameList", + TranGetFileNameList: ClientTransaction{ + Name: "TranGetFileNameList", Handler: handleGetFileNameList, }, - tranServerMsg: clientTransaction{ - Name: "tranServerMsg", + TranServerMsg: ClientTransaction{ + Name: "TranServerMsg", Handler: handleTranServerMsg, }, - tranKeepAlive: clientTransaction{ - Name: "tranKeepAlive", + TranKeepAlive: ClientTransaction{ + Name: "TranKeepAlive", Handler: func(client *Client, transaction *Transaction) (t []Transaction, err error) { return t, err }, @@ -209,9 +216,9 @@ var clientHandlers = map[uint16]clientTHandler{ func handleTranServerMsg(c *Client, t *Transaction) (res []Transaction, err error) { time := time.Now().Format(time.RFC850) - msg := strings.ReplaceAll(string(t.GetField(fieldData).Data), "\r", "\n") + msg := strings.ReplaceAll(string(t.GetField(FieldData).Data), "\r", "\n") msg += "\n\nAt " + time - title := fmt.Sprintf("| Private Message From: %s |", t.GetField(fieldUserName).Data) + title := fmt.Sprintf("| Private Message From: %s |", t.GetField(FieldUserName).Data) msgBox := tview.NewTextView().SetScrollable(true) msgBox.SetText(msg).SetBackgroundColor(tcell.ColorDarkSlateBlue) @@ -268,8 +275,8 @@ func (c *Client) showErrMsg(msg string) { func handleGetFileNameList(c *Client, t *Transaction) (res []Transaction, err error) { if t.IsError() { - c.showErrMsg(string(t.GetField(fieldError).Data)) - c.Logger.Infof("Error: %s", t.GetField(fieldError).Data) + c.showErrMsg(string(t.GetField(FieldError).Data)) + c.Logger.Infof("Error: %s", t.GetField(FieldError).Data) return res, err } @@ -287,9 +294,9 @@ func handleGetFileNameList(c *Client, t *Transaction) (res []Transaction, err er if selectedNode.GetText() == "<- Back" { c.filePath = c.filePath[:len(c.filePath)-1] - f := NewField(fieldFilePath, EncodeFilePath(strings.Join(c.filePath, "/"))) + f := NewField(FieldFilePath, EncodeFilePath(strings.Join(c.filePath, "/"))) - if err := c.UI.HLClient.Send(*NewTransaction(tranGetFileNameList, nil, f)); err != nil { + if err := c.UI.HLClient.Send(*NewTransaction(TranGetFileNameList, nil, f)); err != nil { c.UI.HLClient.Logger.Errorw("err", "err", err) } return event @@ -301,9 +308,9 @@ func handleGetFileNameList(c *Client, t *Transaction) (res []Transaction, err er c.Logger.Infow("get new directory listing", "name", string(entry.name)) c.filePath = append(c.filePath, string(entry.name)) - f := NewField(fieldFilePath, EncodeFilePath(strings.Join(c.filePath, "/"))) + f := NewField(FieldFilePath, EncodeFilePath(strings.Join(c.filePath, "/"))) - if err := c.UI.HLClient.Send(*NewTransaction(tranGetFileNameList, nil, f)); err != nil { + if err := c.UI.HLClient.Send(*NewTransaction(TranGetFileNameList, nil, f)); err != nil { c.UI.HLClient.Logger.Errorw("err", "err", err) } } else { @@ -357,7 +364,7 @@ func handleGetFileNameList(c *Client, t *Transaction) (res []Transaction, err er } func handleGetMsgs(c *Client, t *Transaction) (res []Transaction, err error) { - newsText := string(t.GetField(fieldData).Data) + newsText := string(t.GetField(FieldData).Data) newsText = strings.ReplaceAll(newsText, "\r", "\n") newsTextView := tview.NewTextView(). @@ -378,10 +385,10 @@ func handleGetMsgs(c *Client, t *Transaction) (res []Transaction, err error) { func handleNotifyChangeUser(c *Client, t *Transaction) (res []Transaction, err error) { newUser := User{ - ID: t.GetField(fieldUserID).Data, - Name: string(t.GetField(fieldUserName).Data), - Icon: t.GetField(fieldUserIconID).Data, - Flags: t.GetField(fieldUserFlags).Data, + ID: t.GetField(FieldUserID).Data, + Name: string(t.GetField(FieldUserName).Data), + Icon: t.GetField(FieldUserIconID).Data, + Flags: t.GetField(FieldUserFlags).Data, } // Possible cases: @@ -416,7 +423,7 @@ func handleNotifyChangeUser(c *Client, t *Transaction) (res []Transaction, err e } func handleNotifyDeleteUser(c *Client, t *Transaction) (res []Transaction, err error) { - exitUser := t.GetField(fieldUserID).Data + exitUser := t.GetField(FieldUserID).Data var newUserList []User for _, u := range c.UserList { @@ -435,8 +442,8 @@ func handleNotifyDeleteUser(c *Client, t *Transaction) (res []Transaction, err e func handleClientGetUserNameList(c *Client, t *Transaction) (res []Transaction, err error) { var users []User for _, field := range t.Fields { - // The Hotline protocol docs say that ClientGetUserNameList should only return fieldUsernameWithInfo (300) - // fields, but shxd sneaks in fieldChatSubject (115) so it's important to filter explicitly for the expected + // The Hotline protocol docs say that ClientGetUserNameList should only return FieldUsernameWithInfo (300) + // fields, but shxd sneaks in FieldChatSubject (115) so it's important to filter explicitly for the expected // field type. Probably a good idea to do everywhere. if bytes.Equal(field.ID, []byte{0x01, 0x2c}) { u, err := ReadUser(field.Data) @@ -467,23 +474,23 @@ func (c *Client) renderUserList() { } func handleClientChatMsg(c *Client, t *Transaction) (res []Transaction, err error) { - if c.pref.EnableBell { + if c.Pref.EnableBell { fmt.Println("\a") } - _, _ = fmt.Fprintf(c.UI.chatBox, "%s \n", t.GetField(fieldData).Data) + _, _ = fmt.Fprintf(c.UI.chatBox, "%s \n", t.GetField(FieldData).Data) return res, err } func handleClientTranUserAccess(c *Client, t *Transaction) (res []Transaction, err error) { - c.UserAccess = t.GetField(fieldUserAccess).Data + c.UserAccess = t.GetField(FieldUserAccess).Data return res, err } func handleClientTranShowAgreement(c *Client, t *Transaction) (res []Transaction, err error) { - agreement := string(t.GetField(fieldData).Data) + agreement := string(t.GetField(FieldData).Data) agreement = strings.ReplaceAll(agreement, "\r", "\n") agreeModal := tview.NewModal(). @@ -493,11 +500,11 @@ func handleClientTranShowAgreement(c *Client, t *Transaction) (res []Transaction if buttonIndex == 0 { res = append(res, *NewTransaction( - tranAgreed, nil, - NewField(fieldUserName, []byte(c.pref.Username)), - NewField(fieldUserIconID, c.pref.IconBytes()), - NewField(fieldUserFlags, []byte{0x00, 0x00}), - NewField(fieldOptions, []byte{0x00, 0x00}), + TranAgreed, nil, + NewField(FieldUserName, []byte(c.Pref.Username)), + NewField(FieldUserIconID, c.Pref.IconBytes()), + NewField(FieldUserFlags, []byte{0x00, 0x00}), + NewField(FieldOptions, []byte{0x00, 0x00}), ), ) c.UI.Pages.HidePage("agreement") @@ -516,7 +523,7 @@ func handleClientTranShowAgreement(c *Client, t *Transaction) (res []Transaction func handleClientTranLogin(c *Client, t *Transaction) (res []Transaction, err error) { if !bytes.Equal(t.ErrorCode, []byte{0, 0, 0, 0}) { - errMsg := string(t.GetField(fieldError).Data) + errMsg := string(t.GetField(FieldError).Data) errModal := tview.NewModal() errModal.SetText(errMsg) errModal.AddButtons([]string{"Oh no"}) @@ -528,22 +535,23 @@ func handleClientTranLogin(c *Client, t *Transaction) (res []Transaction, err er c.UI.App.Draw() // TODO: errModal doesn't render without this. wtf? - c.Logger.Error(string(t.GetField(fieldError).Data)) - return nil, errors.New("login error: " + string(t.GetField(fieldError).Data)) + c.Logger.Error(string(t.GetField(FieldError).Data)) + return nil, errors.New("login error: " + string(t.GetField(FieldError).Data)) } c.UI.Pages.AddAndSwitchToPage(serverUIPage, c.UI.renderServerUI(), true) c.UI.App.SetFocus(c.UI.chatInput) - if err := c.Send(*NewTransaction(tranGetUserNameList, nil)); err != nil { + if err := c.Send(*NewTransaction(TranGetUserNameList, nil)); err != nil { c.Logger.Errorw("err", "err", err) } return res, err } // JoinServer connects to a Hotline server and completes the login flow -func (c *Client) JoinServer(address, login, passwd string) error { +func (c *Client) Connect(address, login, passwd string) (err error) { // Establish TCP connection to server - if err := c.connect(address); err != nil { + c.Connection, err = net.DialTimeout("tcp", address, 5*time.Second) + if err != nil { return err } @@ -552,7 +560,7 @@ func (c *Client) JoinServer(address, login, passwd string) error { return err } - // Authenticate (send tranLogin 107) + // Authenticate (send TranLogin 107) if err := c.LogIn(login, passwd); err != nil { return err } @@ -566,21 +574,11 @@ func (c *Client) JoinServer(address, login, passwd string) error { func (c *Client) keepalive() error { for { time.Sleep(300 * time.Second) - _ = c.Send(*NewTransaction(tranKeepAlive, nil)) + _ = c.Send(*NewTransaction(TranKeepAlive, nil)) c.Logger.Infow("Sent keepalive ping") } } -// connect establishes a connection with a Server by sending handshake sequence -func (c *Client) connect(address string) error { - var err error - c.Connection, err = net.DialTimeout("tcp", address, 5*time.Second) - if err != nil { - return err - } - return nil -} - var ClientHandshake = []byte{ 0x54, 0x52, 0x54, 0x50, // TRTP 0x48, 0x4f, 0x54, 0x4c, // HOTL @@ -619,11 +617,11 @@ func (c *Client) Handshake() error { func (c *Client) LogIn(login string, password string) error { return c.Send( *NewTransaction( - tranLogin, nil, - NewField(fieldUserName, []byte(c.pref.Username)), - NewField(fieldUserIconID, c.pref.IconBytes()), - NewField(fieldUserLogin, negateString([]byte(login))), - NewField(fieldUserPassword, negateString([]byte(password))), + TranLogin, nil, + NewField(FieldUserName, []byte(c.Pref.Username)), + NewField(FieldUserIconID, c.Pref.IconBytes()), + NewField(FieldUserLogin, negateString([]byte(login))), + NewField(FieldUserPassword, negateString([]byte(password))), ), ) } @@ -673,7 +671,7 @@ func (c *Client) HandleTransaction(t *Transaction) error { c.Send(t) } } else { - c.Logger.Errorw( + c.Logger.Debugw( "Unimplemented transaction type received", "RequestID", requestNum, "TransactionID", t.ID, @@ -686,3 +684,31 @@ func (c *Client) HandleTransaction(t *Transaction) error { func (c *Client) Disconnect() error { return c.Connection.Close() } + +func (c *Client) HandleTransactions() error { + // Create a new scanner for parsing incoming bytes into transaction tokens + scanner := bufio.NewScanner(c.Connection) + scanner.Split(transactionScanner) + + // Scan for new transactions and handle them as they come in. + for scanner.Scan() { + // Make a new []byte slice and copy the scanner bytes to it. This is critical to avoid a data race as the + // scanner re-uses the buffer for subsequent scans. + buf := make([]byte, len(scanner.Bytes())) + copy(buf, scanner.Bytes()) + + var t Transaction + _, err := t.Write(buf) + if err != nil { + break + } + if err := c.HandleTransaction(&t); err != nil { + c.Logger.Errorw("Error handling transaction", "err", err) + } + } + + if scanner.Err() == nil { + return scanner.Err() + } + return nil +} diff --git a/hotline/client_conn.go b/hotline/client_conn.go index 14aef9e..f92c1cd 100644 --- a/hotline/client_conn.go +++ b/hotline/client_conn.go @@ -94,7 +94,7 @@ func (cc *ClientConn) handleTransaction(transaction Transaction) error { cc.Server.mux.Lock() defer cc.Server.mux.Unlock() - if requestNum != tranKeepAlive { + if requestNum != TranKeepAlive { // reset the user idle timer cc.IdleTime = 0 @@ -107,11 +107,11 @@ func (cc *ClientConn) handleTransaction(transaction Transaction) error { cc.Idle = false cc.sendAll( - tranNotifyChangeUser, - NewField(fieldUserID, *cc.ID), - NewField(fieldUserFlags, cc.Flags), - NewField(fieldUserName, cc.UserName), - NewField(fieldUserIconID, cc.Icon), + TranNotifyChangeUser, + NewField(FieldUserID, *cc.ID), + NewField(FieldUserFlags, cc.Flags), + NewField(FieldUserName, cc.UserName), + NewField(FieldUserIconID, cc.Icon), ) } } @@ -144,7 +144,7 @@ func (cc *ClientConn) Disconnect() { delete(cc.Server.Clients, binary.BigEndian.Uint16(*cc.ID)) - for _, t := range cc.notifyOthers(*NewTransaction(tranNotifyDeleteUser, nil, NewField(fieldUserID, *cc.ID))) { + for _, t := range cc.notifyOthers(*NewTransaction(TranNotifyDeleteUser, nil, NewField(FieldUserID, *cc.ID))) { cc.Server.outbox <- t } @@ -189,7 +189,7 @@ func (cc *ClientConn) NewErrReply(t *Transaction, errMsg string) Transaction { ID: t.ID, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte(errMsg)), + NewField(FieldError, []byte(errMsg)), }, } } diff --git a/hotline/field.go b/hotline/field.go index 3378552..c5ae55b 100644 --- a/hotline/field.go +++ b/hotline/field.go @@ -5,65 +5,65 @@ import ( "github.com/jhalter/mobius/concat" ) -const fieldError = 100 -const fieldData = 101 -const fieldUserName = 102 -const fieldUserID = 103 -const fieldUserIconID = 104 -const fieldUserLogin = 105 -const fieldUserPassword = 106 -const fieldRefNum = 107 -const fieldTransferSize = 108 -const fieldChatOptions = 109 -const fieldUserAccess = 110 - -// const fieldUserAlias = 111 TODO: implement -const fieldUserFlags = 112 -const fieldOptions = 113 -const fieldChatID = 114 -const fieldChatSubject = 115 -const fieldWaitingCount = 116 -const fieldBannerType = 152 -const fieldNoServerAgreement = 152 -const fieldVersion = 160 -const fieldCommunityBannerID = 161 -const fieldServerName = 162 -const fieldFileNameWithInfo = 200 -const fieldFileName = 201 -const fieldFilePath = 202 -const fieldFileResumeData = 203 -const fieldFileTransferOptions = 204 -const fieldFileTypeString = 205 -const fieldFileCreatorString = 206 -const fieldFileSize = 207 -const fieldFileCreateDate = 208 -const fieldFileModifyDate = 209 -const fieldFileComment = 210 -const fieldFileNewName = 211 -const fieldFileNewPath = 212 -const fieldFileType = 213 -const fieldQuotingMsg = 214 -const fieldAutomaticResponse = 215 -const fieldFolderItemCount = 220 -const fieldUsernameWithInfo = 300 -const fieldNewsArtListData = 321 -const fieldNewsCatName = 322 -const fieldNewsCatListData15 = 323 -const fieldNewsPath = 325 -const fieldNewsArtID = 326 -const fieldNewsArtDataFlav = 327 -const fieldNewsArtTitle = 328 -const fieldNewsArtPoster = 329 -const fieldNewsArtDate = 330 -const fieldNewsArtPrevArt = 331 -const fieldNewsArtNextArt = 332 -const fieldNewsArtData = 333 - -// const fieldNewsArtFlags = 334 -const fieldNewsArtParentArt = 335 -const fieldNewsArt1stChildArt = 336 - -// const fieldNewsArtRecurseDel = 337 +// List of Hotline protocol field types taken from the official 1.9 protocol document +const ( + FieldError = 100 + FieldData = 101 + FieldUserName = 102 + FieldUserID = 103 + FieldUserIconID = 104 + FieldUserLogin = 105 + FieldUserPassword = 106 + FieldRefNum = 107 + FieldTransferSize = 108 + FieldChatOptions = 109 + FieldUserAccess = 110 + FieldUserAlias = 111 // TODO: implement + FieldUserFlags = 112 + FieldOptions = 113 + FieldChatID = 114 + FieldChatSubject = 115 + FieldWaitingCount = 116 + FieldBannerType = 152 + FieldNoServerAgreement = 152 + FieldVersion = 160 + FieldCommunityBannerID = 161 + FieldServerName = 162 + FieldFileNameWithInfo = 200 + FieldFileName = 201 + FieldFilePath = 202 + FieldFileResumeData = 203 + FieldFileTransferOptions = 204 + FieldFileTypeString = 205 + FieldFileCreatorString = 206 + FieldFileSize = 207 + FieldFileCreateDate = 208 + FieldFileModifyDate = 209 + FieldFileComment = 210 + FieldFileNewName = 211 + FieldFileNewPath = 212 + FieldFileType = 213 + FieldQuotingMsg = 214 + FieldAutomaticResponse = 215 + FieldFolderItemCount = 220 + FieldUsernameWithInfo = 300 + FieldNewsArtListData = 321 + FieldNewsCatName = 322 + FieldNewsCatListData15 = 323 + FieldNewsPath = 325 + FieldNewsArtID = 326 + FieldNewsArtDataFlav = 327 + FieldNewsArtTitle = 328 + FieldNewsArtPoster = 329 + FieldNewsArtDate = 330 + FieldNewsArtPrevArt = 331 + FieldNewsArtNextArt = 332 + FieldNewsArtData = 333 + FieldNewsArtFlags = 334 // TODO: what is this used for? + FieldNewsArtParentArt = 335 + FieldNewsArt1stChildArt = 336 + FieldNewsArtRecurseDel = 337 // TODO: implement news article recusive deletion +) type Field struct { ID []byte // Type of field diff --git a/hotline/files.go b/hotline/files.go index aa248f8..c4ba718 100644 --- a/hotline/files.go +++ b/hotline/files.go @@ -131,7 +131,7 @@ func getFileNameList(path string, ignoreList []string) (fields []Field, err erro if err != nil { return nil, err } - fields = append(fields, NewField(fieldFileNameWithInfo, b)) + fields = append(fields, NewField(FieldFileNameWithInfo, b)) } return fields, nil diff --git a/hotline/server.go b/hotline/server.go index 9e5f498..f4a2ad4 100644 --- a/hotline/server.go +++ b/hotline/server.go @@ -319,11 +319,11 @@ func (s *Server) keepaliveHandler() { binary.BigEndian.PutUint16(c.Flags, uint16(flagBitmap.Int64())) c.sendAll( - tranNotifyChangeUser, - NewField(fieldUserID, *c.ID), - NewField(fieldUserFlags, c.Flags), - NewField(fieldUserName, c.UserName), - NewField(fieldUserIconID, c.Icon), + TranNotifyChangeUser, + NewField(FieldUserID, *c.ID), + NewField(FieldUserFlags, c.Flags), + NewField(FieldUserName, c.UserName), + NewField(FieldUserIconID, c.Icon), ) } } @@ -469,7 +469,7 @@ func (s *Server) connectedUsers() []Field { Flags: c.Flags, Name: string(c.UserName), } - connectedUsers = append(connectedUsers, NewField(fieldUsernameWithInfo, user.Payload())) + connectedUsers = append(connectedUsers, NewField(FieldUsernameWithInfo, user.Payload())) } return connectedUsers } @@ -572,10 +572,10 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser // permaban if banUntil == nil { t := NewTransaction( - tranServerMsg, + TranServerMsg, &[]byte{0, 0}, - NewField(fieldData, []byte("You are permanently banned on this server")), - NewField(fieldChatOptions, []byte{0, 0}), + NewField(FieldData, []byte("You are permanently banned on this server")), + NewField(FieldChatOptions, []byte{0, 0}), ) b, err := t.MarshalBinary() @@ -595,10 +595,10 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser // temporary ban if time.Now().Before(*banUntil) { t := NewTransaction( - tranServerMsg, + TranServerMsg, &[]byte{0, 0}, - NewField(fieldData, []byte("You are temporarily banned on this server")), - NewField(fieldChatOptions, []byte{0, 0}), + NewField(FieldData, []byte("You are temporarily banned on this server")), + NewField(FieldChatOptions, []byte{0, 0}), ) b, err := t.MarshalBinary() if err != nil { @@ -618,9 +618,9 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser c := s.NewClientConn(rwc, remoteAddr) defer c.Disconnect() - encodedLogin := clientLogin.GetField(fieldUserLogin).Data - encodedPassword := clientLogin.GetField(fieldUserPassword).Data - c.Version = clientLogin.GetField(fieldVersion).Data + encodedLogin := clientLogin.GetField(FieldUserLogin).Data + encodedPassword := clientLogin.GetField(FieldUserPassword).Data + c.Version = clientLogin.GetField(FieldVersion).Data var login string for _, char := range encodedLogin { @@ -648,15 +648,15 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser return nil } - if clientLogin.GetField(fieldUserIconID).Data != nil { - c.Icon = clientLogin.GetField(fieldUserIconID).Data + if clientLogin.GetField(FieldUserIconID).Data != nil { + c.Icon = clientLogin.GetField(FieldUserIconID).Data } c.Account = c.Server.Accounts[login] - if clientLogin.GetField(fieldUserName).Data != nil { + if clientLogin.GetField(FieldUserName).Data != nil { if c.Authorize(accessAnyName) { - c.UserName = clientLogin.GetField(fieldUserName).Data + c.UserName = clientLogin.GetField(FieldUserName).Data } else { c.UserName = []byte(c.Account.Name) } @@ -667,44 +667,44 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser } s.outbox <- c.NewReply(&clientLogin, - NewField(fieldVersion, []byte{0x00, 0xbe}), - NewField(fieldCommunityBannerID, []byte{0, 0}), - NewField(fieldServerName, []byte(s.Config.Name)), + NewField(FieldVersion, []byte{0x00, 0xbe}), + NewField(FieldCommunityBannerID, []byte{0, 0}), + NewField(FieldServerName, []byte(s.Config.Name)), ) // Send user access privs so client UI knows how to behave - c.Server.outbox <- *NewTransaction(tranUserAccess, c.ID, NewField(fieldUserAccess, c.Account.Access[:])) + c.Server.outbox <- *NewTransaction(TranUserAccess, c.ID, NewField(FieldUserAccess, c.Account.Access[:])) // Accounts with accessNoAgreement do not receive the server agreement on login. The behavior is different between - // client versions. For 1.2.3 client, we do not send tranShowAgreement. For other client versions, we send - // tranShowAgreement but with the NoServerAgreement field set to 1. + // client versions. For 1.2.3 client, we do not send TranShowAgreement. For other client versions, we send + // TranShowAgreement but with the NoServerAgreement field set to 1. if c.Authorize(accessNoAgreement) { // If client version is nil, then the client uses the 1.2.3 login behavior if c.Version != nil { - c.Server.outbox <- *NewTransaction(tranShowAgreement, c.ID, NewField(fieldNoServerAgreement, []byte{1})) + c.Server.outbox <- *NewTransaction(TranShowAgreement, c.ID, NewField(FieldNoServerAgreement, []byte{1})) } } else { - c.Server.outbox <- *NewTransaction(tranShowAgreement, c.ID, NewField(fieldData, s.Agreement)) + c.Server.outbox <- *NewTransaction(TranShowAgreement, c.ID, NewField(FieldData, s.Agreement)) } // If the client has provided a username as part of the login, we can infer that it is using the 1.2.3 login // flow and not the 1.5+ flow. if len(c.UserName) != 0 { // Add the client username to the logger. For 1.5+ clients, we don't have this information yet as it comes as - // part of tranAgreed + // part of TranAgreed c.logger = c.logger.With("name", string(c.UserName)) c.logger.Infow("Login successful", "clientVersion", "Not sent (probably 1.2.3)") // Notify other clients on the server that the new user has logged in. For 1.5+ clients we don't have this - // information yet, so we do it in tranAgreed instead + // information yet, so we do it in TranAgreed instead for _, t := range c.notifyOthers( *NewTransaction( - tranNotifyChangeUser, nil, - NewField(fieldUserName, c.UserName), - NewField(fieldUserID, *c.ID), - NewField(fieldUserIconID, c.Icon), - NewField(fieldUserFlags, c.Flags), + TranNotifyChangeUser, nil, + NewField(FieldUserName, c.UserName), + NewField(FieldUserID, *c.ID), + NewField(FieldUserIconID, c.Icon), + NewField(FieldUserFlags, c.Flags), ), ) { c.Server.outbox <- t diff --git a/hotline/transaction.go b/hotline/transaction.go index 8d7d9ed..b01fdfb 100644 --- a/hotline/transaction.go +++ b/hotline/transaction.go @@ -10,64 +10,64 @@ import ( ) const ( - tranError = 0 - tranGetMsgs = 101 - tranNewMsg = 102 - tranOldPostNews = 103 - tranServerMsg = 104 - tranChatSend = 105 - tranChatMsg = 106 - tranLogin = 107 - tranSendInstantMsg = 108 - tranShowAgreement = 109 - tranDisconnectUser = 110 - // tranDisconnectMsg = 111 TODO: implement friendly disconnect - tranInviteNewChat = 112 - tranInviteToChat = 113 - tranRejectChatInvite = 114 - tranJoinChat = 115 - tranLeaveChat = 116 - tranNotifyChatChangeUser = 117 - tranNotifyChatDeleteUser = 118 - tranNotifyChatSubject = 119 - tranSetChatSubject = 120 - tranAgreed = 121 - tranServerBanner = 122 - tranGetFileNameList = 200 - tranDownloadFile = 202 - tranUploadFile = 203 - tranNewFolder = 205 - tranDeleteFile = 204 - tranGetFileInfo = 206 - tranSetFileInfo = 207 - tranMoveFile = 208 - tranMakeFileAlias = 209 - tranDownloadFldr = 210 - // tranDownloadInfo = 211 TODO: implement file transfer queue - tranDownloadBanner = 212 - tranUploadFldr = 213 - tranGetUserNameList = 300 - tranNotifyChangeUser = 301 - tranNotifyDeleteUser = 302 - tranGetClientInfoText = 303 - tranSetClientUserInfo = 304 - tranListUsers = 348 - tranUpdateUser = 349 - tranNewUser = 350 - tranDeleteUser = 351 - tranGetUser = 352 - tranSetUser = 353 - tranUserAccess = 354 - tranUserBroadcast = 355 - tranGetNewsCatNameList = 370 - tranGetNewsArtNameList = 371 - tranDelNewsItem = 380 - tranNewNewsFldr = 381 - tranNewNewsCat = 382 - tranGetNewsArtData = 400 - tranPostNewsArt = 410 - tranDelNewsArt = 411 - tranKeepAlive = 500 + TranError = 0 + TranGetMsgs = 101 + TranNewMsg = 102 + TranOldPostNews = 103 + TranServerMsg = 104 + TranChatSend = 105 + TranChatMsg = 106 + TranLogin = 107 + TranSendInstantMsg = 108 + TranShowAgreement = 109 + TranDisconnectUser = 110 + TranDisconnectMsg = 111 // TODO: implement server initiated friendly disconnect + TranInviteNewChat = 112 + TranInviteToChat = 113 + TranRejectChatInvite = 114 + TranJoinChat = 115 + TranLeaveChat = 116 + TranNotifyChatChangeUser = 117 + TranNotifyChatDeleteUser = 118 + TranNotifyChatSubject = 119 + TranSetChatSubject = 120 + TranAgreed = 121 + TranServerBanner = 122 + TranGetFileNameList = 200 + TranDownloadFile = 202 + TranUploadFile = 203 + TranNewFolder = 205 + TranDeleteFile = 204 + TranGetFileInfo = 206 + TranSetFileInfo = 207 + TranMoveFile = 208 + TranMakeFileAlias = 209 + TranDownloadFldr = 210 + TranDownloadInfo = 211 // TODO: implement file transfer queue + TranDownloadBanner = 212 + TranUploadFldr = 213 + TranGetUserNameList = 300 + TranNotifyChangeUser = 301 + TranNotifyDeleteUser = 302 + TranGetClientInfoText = 303 + TranSetClientUserInfo = 304 + TranListUsers = 348 + TranUpdateUser = 349 + TranNewUser = 350 + TranDeleteUser = 351 + TranGetUser = 352 + TranSetUser = 353 + TranUserAccess = 354 + TranUserBroadcast = 355 + TranGetNewsCatNameList = 370 + TranGetNewsArtNameList = 371 + TranDelNewsItem = 380 + TranNewNewsFldr = 381 + TranNewNewsCat = 382 + TranGetNewsArtData = 400 + TranPostNewsArt = 410 + TranDelNewsArt = 411 + TranKeepAlive = 500 ) type Transaction struct { diff --git a/hotline/transaction_handlers.go b/hotline/transaction_handlers.go index d99da53..813d25c 100644 --- a/hotline/transaction_handlers.go +++ b/hotline/transaction_handlers.go @@ -15,223 +15,225 @@ import ( "time" ) +type HandlerFunc func(*ClientConn, *Transaction) ([]Transaction, error) + type TransactionType struct { - Handler func(*ClientConn, *Transaction) ([]Transaction, error) // function for handling the transaction type - Name string // Name of transaction as it will appear in logging + Handler HandlerFunc // function for handling the transaction type + Name string // Name of transaction as it will appear in logging RequiredFields []requiredField } var TransactionHandlers = map[uint16]TransactionType{ // Server initiated - tranChatMsg: { - Name: "tranChatMsg", + TranChatMsg: { + Name: "TranChatMsg", }, // Server initiated - tranNotifyChangeUser: { - Name: "tranNotifyChangeUser", + TranNotifyChangeUser: { + Name: "TranNotifyChangeUser", }, - tranError: { - Name: "tranError", + TranError: { + Name: "TranError", }, - tranShowAgreement: { - Name: "tranShowAgreement", + TranShowAgreement: { + Name: "TranShowAgreement", }, - tranUserAccess: { - Name: "tranUserAccess", + TranUserAccess: { + Name: "TranUserAccess", }, - tranNotifyDeleteUser: { - Name: "tranNotifyDeleteUser", + TranNotifyDeleteUser: { + Name: "TranNotifyDeleteUser", }, - tranAgreed: { - Name: "tranAgreed", + TranAgreed: { + Name: "TranAgreed", Handler: HandleTranAgreed, }, - tranChatSend: { - Name: "tranChatSend", + TranChatSend: { + Name: "TranChatSend", Handler: HandleChatSend, RequiredFields: []requiredField{ { - ID: fieldData, + ID: FieldData, minLen: 0, }, }, }, - tranDelNewsArt: { - Name: "tranDelNewsArt", + TranDelNewsArt: { + Name: "TranDelNewsArt", Handler: HandleDelNewsArt, }, - tranDelNewsItem: { - Name: "tranDelNewsItem", + TranDelNewsItem: { + Name: "TranDelNewsItem", Handler: HandleDelNewsItem, }, - tranDeleteFile: { - Name: "tranDeleteFile", + TranDeleteFile: { + Name: "TranDeleteFile", Handler: HandleDeleteFile, }, - tranDeleteUser: { - Name: "tranDeleteUser", + TranDeleteUser: { + Name: "TranDeleteUser", Handler: HandleDeleteUser, }, - tranDisconnectUser: { - Name: "tranDisconnectUser", + TranDisconnectUser: { + Name: "TranDisconnectUser", Handler: HandleDisconnectUser, }, - tranDownloadFile: { - Name: "tranDownloadFile", + TranDownloadFile: { + Name: "TranDownloadFile", Handler: HandleDownloadFile, }, - tranDownloadFldr: { - Name: "tranDownloadFldr", + TranDownloadFldr: { + Name: "TranDownloadFldr", Handler: HandleDownloadFolder, }, - tranGetClientInfoText: { - Name: "tranGetClientInfoText", + TranGetClientInfoText: { + Name: "TranGetClientInfoText", Handler: HandleGetClientInfoText, }, - tranGetFileInfo: { - Name: "tranGetFileInfo", + TranGetFileInfo: { + Name: "TranGetFileInfo", Handler: HandleGetFileInfo, }, - tranGetFileNameList: { - Name: "tranGetFileNameList", + TranGetFileNameList: { + Name: "TranGetFileNameList", Handler: HandleGetFileNameList, }, - tranGetMsgs: { - Name: "tranGetMsgs", + TranGetMsgs: { + Name: "TranGetMsgs", Handler: HandleGetMsgs, }, - tranGetNewsArtData: { - Name: "tranGetNewsArtData", + TranGetNewsArtData: { + Name: "TranGetNewsArtData", Handler: HandleGetNewsArtData, }, - tranGetNewsArtNameList: { - Name: "tranGetNewsArtNameList", + TranGetNewsArtNameList: { + Name: "TranGetNewsArtNameList", Handler: HandleGetNewsArtNameList, }, - tranGetNewsCatNameList: { - Name: "tranGetNewsCatNameList", + TranGetNewsCatNameList: { + Name: "TranGetNewsCatNameList", Handler: HandleGetNewsCatNameList, }, - tranGetUser: { - Name: "tranGetUser", + TranGetUser: { + Name: "TranGetUser", Handler: HandleGetUser, }, - tranGetUserNameList: { + TranGetUserNameList: { Name: "tranHandleGetUserNameList", Handler: HandleGetUserNameList, }, - tranInviteNewChat: { - Name: "tranInviteNewChat", + TranInviteNewChat: { + Name: "TranInviteNewChat", Handler: HandleInviteNewChat, }, - tranInviteToChat: { - Name: "tranInviteToChat", + TranInviteToChat: { + Name: "TranInviteToChat", Handler: HandleInviteToChat, }, - tranJoinChat: { - Name: "tranJoinChat", + TranJoinChat: { + Name: "TranJoinChat", Handler: HandleJoinChat, }, - tranKeepAlive: { - Name: "tranKeepAlive", + TranKeepAlive: { + Name: "TranKeepAlive", Handler: HandleKeepAlive, }, - tranLeaveChat: { - Name: "tranJoinChat", + TranLeaveChat: { + Name: "TranJoinChat", Handler: HandleLeaveChat, }, - tranListUsers: { - Name: "tranListUsers", + TranListUsers: { + Name: "TranListUsers", Handler: HandleListUsers, }, - tranMoveFile: { - Name: "tranMoveFile", + TranMoveFile: { + Name: "TranMoveFile", Handler: HandleMoveFile, }, - tranNewFolder: { - Name: "tranNewFolder", + TranNewFolder: { + Name: "TranNewFolder", Handler: HandleNewFolder, }, - tranNewNewsCat: { - Name: "tranNewNewsCat", + TranNewNewsCat: { + Name: "TranNewNewsCat", Handler: HandleNewNewsCat, }, - tranNewNewsFldr: { - Name: "tranNewNewsFldr", + TranNewNewsFldr: { + Name: "TranNewNewsFldr", Handler: HandleNewNewsFldr, }, - tranNewUser: { - Name: "tranNewUser", + TranNewUser: { + Name: "TranNewUser", Handler: HandleNewUser, }, - tranUpdateUser: { - Name: "tranUpdateUser", + TranUpdateUser: { + Name: "TranUpdateUser", Handler: HandleUpdateUser, }, - tranOldPostNews: { - Name: "tranOldPostNews", + TranOldPostNews: { + Name: "TranOldPostNews", Handler: HandleTranOldPostNews, }, - tranPostNewsArt: { - Name: "tranPostNewsArt", + TranPostNewsArt: { + Name: "TranPostNewsArt", Handler: HandlePostNewsArt, }, - tranRejectChatInvite: { - Name: "tranRejectChatInvite", + TranRejectChatInvite: { + Name: "TranRejectChatInvite", Handler: HandleRejectChatInvite, }, - tranSendInstantMsg: { - Name: "tranSendInstantMsg", + TranSendInstantMsg: { + Name: "TranSendInstantMsg", Handler: HandleSendInstantMsg, RequiredFields: []requiredField{ { - ID: fieldData, + ID: FieldData, minLen: 0, }, { - ID: fieldUserID, + ID: FieldUserID, }, }, }, - tranSetChatSubject: { - Name: "tranSetChatSubject", + TranSetChatSubject: { + Name: "TranSetChatSubject", Handler: HandleSetChatSubject, }, - tranMakeFileAlias: { - Name: "tranMakeFileAlias", + TranMakeFileAlias: { + Name: "TranMakeFileAlias", Handler: HandleMakeAlias, RequiredFields: []requiredField{ - {ID: fieldFileName, minLen: 1}, - {ID: fieldFilePath, minLen: 1}, - {ID: fieldFileNewPath, minLen: 1}, + {ID: FieldFileName, minLen: 1}, + {ID: FieldFilePath, minLen: 1}, + {ID: FieldFileNewPath, minLen: 1}, }, }, - tranSetClientUserInfo: { - Name: "tranSetClientUserInfo", + TranSetClientUserInfo: { + Name: "TranSetClientUserInfo", Handler: HandleSetClientUserInfo, }, - tranSetFileInfo: { - Name: "tranSetFileInfo", + TranSetFileInfo: { + Name: "TranSetFileInfo", Handler: HandleSetFileInfo, }, - tranSetUser: { - Name: "tranSetUser", + TranSetUser: { + Name: "TranSetUser", Handler: HandleSetUser, }, - tranUploadFile: { - Name: "tranUploadFile", + TranUploadFile: { + Name: "TranUploadFile", Handler: HandleUploadFile, }, - tranUploadFldr: { - Name: "tranUploadFldr", + TranUploadFldr: { + Name: "TranUploadFldr", Handler: HandleUploadFolder, }, - tranUserBroadcast: { - Name: "tranUserBroadcast", + TranUserBroadcast: { + Name: "TranUserBroadcast", Handler: HandleUserBroadcast, }, - tranDownloadBanner: { - Name: "tranDownloadBanner", + TranDownloadBanner: { + Name: "TranDownloadBanner", Handler: HandleDownloadBanner, }, } @@ -244,19 +246,19 @@ func HandleChatSend(cc *ClientConn, t *Transaction) (res []Transaction, err erro // Truncate long usernames trunc := fmt.Sprintf("%13s", cc.UserName) - formattedMsg := fmt.Sprintf("\r%.14s: %s", trunc, t.GetField(fieldData).Data) + formattedMsg := fmt.Sprintf("\r%.14s: %s", trunc, t.GetField(FieldData).Data) // By holding the option key, Hotline chat allows users to send /me formatted messages like: // *** Halcyon does stuff - // This is indicated by the presence of the optional field fieldChatOptions set to a value of 1. + // This is indicated by the presence of the optional field FieldChatOptions set to a value of 1. // Most clients do not send this option for normal chat messages. - if t.GetField(fieldChatOptions).Data != nil && bytes.Equal(t.GetField(fieldChatOptions).Data, []byte{0, 1}) { - formattedMsg = fmt.Sprintf("\r*** %s %s", cc.UserName, t.GetField(fieldData).Data) + if t.GetField(FieldChatOptions).Data != nil && bytes.Equal(t.GetField(FieldChatOptions).Data, []byte{0, 1}) { + formattedMsg = fmt.Sprintf("\r*** %s %s", cc.UserName, t.GetField(FieldData).Data) } // The ChatID field is used to identify messages as belonging to a private chat. // All clients *except* Frogblast omit this field for public chat, but Frogblast sends a value of 00 00 00 00. - chatID := t.GetField(fieldChatID).Data + chatID := t.GetField(FieldChatID).Data if chatID != nil && !bytes.Equal([]byte{0, 0, 0, 0}, chatID) { chatInt := binary.BigEndian.Uint32(chatID) privChat := cc.Server.PrivateChats[chatInt] @@ -266,10 +268,10 @@ func HandleChatSend(cc *ClientConn, t *Transaction) (res []Transaction, err erro // send the message to all connected clients of the private chat for _, c := range clients { res = append(res, *NewTransaction( - tranChatMsg, + TranChatMsg, c.ID, - NewField(fieldChatID, chatID), - NewField(fieldData, []byte(formattedMsg)), + NewField(FieldChatID, chatID), + NewField(FieldData, []byte(formattedMsg)), )) } return res, err @@ -278,7 +280,7 @@ func HandleChatSend(cc *ClientConn, t *Transaction) (res []Transaction, err erro for _, c := range sortedClients(cc.Server.Clients) { // Filter out clients that do not have the read chat permission if c.Authorize(accessReadChat) { - res = append(res, *NewTransaction(tranChatMsg, c.ID, NewField(fieldData, []byte(formattedMsg)))) + res = append(res, *NewTransaction(TranChatMsg, c.ID, NewField(FieldData, []byte(formattedMsg)))) } } @@ -306,22 +308,22 @@ func HandleSendInstantMsg(cc *ClientConn, t *Transaction) (res []Transaction, er return res, err } - msg := t.GetField(fieldData) - ID := t.GetField(fieldUserID) + msg := t.GetField(FieldData) + ID := t.GetField(FieldUserID) reply := NewTransaction( - tranServerMsg, + TranServerMsg, &ID.Data, - NewField(fieldData, msg.Data), - NewField(fieldUserName, cc.UserName), - NewField(fieldUserID, *cc.ID), - NewField(fieldOptions, []byte{0, 1}), + NewField(FieldData, msg.Data), + NewField(FieldUserName, cc.UserName), + NewField(FieldUserID, *cc.ID), + NewField(FieldOptions, []byte{0, 1}), ) - // Later versions of Hotline include the original message in the fieldQuotingMsg field so + // Later versions of Hotline include the original message in the FieldQuotingMsg field so // the receiving client can display both the received message and what it is in reply to - if t.GetField(fieldQuotingMsg).Data != nil { - reply.Fields = append(reply.Fields, NewField(fieldQuotingMsg, t.GetField(fieldQuotingMsg).Data)) + if t.GetField(FieldQuotingMsg).Data != nil { + reply.Fields = append(reply.Fields, NewField(FieldQuotingMsg, t.GetField(FieldQuotingMsg).Data)) } id, _ := byteToInt(ID.Data) @@ -335,12 +337,12 @@ func HandleSendInstantMsg(cc *ClientConn, t *Transaction) (res []Transaction, er if flagBitmap.Bit(userFLagRefusePChat) == 1 { res = append(res, *NewTransaction( - tranServerMsg, + TranServerMsg, cc.ID, - NewField(fieldData, []byte(string(otherClient.UserName)+" does not accept private messages.")), - NewField(fieldUserName, otherClient.UserName), - NewField(fieldUserID, *otherClient.ID), - NewField(fieldOptions, []byte{0, 2}), + NewField(FieldData, []byte(string(otherClient.UserName)+" does not accept private messages.")), + NewField(FieldUserName, otherClient.UserName), + NewField(FieldUserID, *otherClient.ID), + NewField(FieldOptions, []byte{0, 2}), ), ) } else { @@ -351,12 +353,12 @@ func HandleSendInstantMsg(cc *ClientConn, t *Transaction) (res []Transaction, er if len(otherClient.AutoReply) > 0 { res = append(res, *NewTransaction( - tranServerMsg, + TranServerMsg, cc.ID, - NewField(fieldData, otherClient.AutoReply), - NewField(fieldUserName, otherClient.UserName), - NewField(fieldUserID, *otherClient.ID), - NewField(fieldOptions, []byte{0, 1}), + NewField(FieldData, otherClient.AutoReply), + NewField(FieldUserName, otherClient.UserName), + NewField(FieldUserID, *otherClient.ID), + NewField(FieldOptions, []byte{0, 1}), ), ) } @@ -367,8 +369,8 @@ func HandleSendInstantMsg(cc *ClientConn, t *Transaction) (res []Transaction, er } func HandleGetFileInfo(cc *ClientConn, t *Transaction) (res []Transaction, err error) { - fileName := t.GetField(fieldFileName).Data - filePath := t.GetField(fieldFilePath).Data + fileName := t.GetField(FieldFileName).Data + filePath := t.GetField(FieldFilePath).Data fullFilePath, err := readPath(cc.Server.Config.FileRoot, filePath, fileName) if err != nil { @@ -381,14 +383,14 @@ func HandleGetFileInfo(cc *ClientConn, t *Transaction) (res []Transaction, err e } res = append(res, cc.NewReply(t, - NewField(fieldFileName, []byte(fw.name)), - NewField(fieldFileTypeString, fw.ffo.FlatFileInformationFork.friendlyType()), - NewField(fieldFileCreatorString, fw.ffo.FlatFileInformationFork.friendlyCreator()), - NewField(fieldFileComment, fw.ffo.FlatFileInformationFork.Comment), - NewField(fieldFileType, fw.ffo.FlatFileInformationFork.TypeSignature), - NewField(fieldFileCreateDate, fw.ffo.FlatFileInformationFork.CreateDate), - NewField(fieldFileModifyDate, fw.ffo.FlatFileInformationFork.ModifyDate), - NewField(fieldFileSize, fw.totalSize()), + NewField(FieldFileName, []byte(fw.name)), + NewField(FieldFileTypeString, fw.ffo.FlatFileInformationFork.friendlyType()), + NewField(FieldFileCreatorString, fw.ffo.FlatFileInformationFork.friendlyCreator()), + NewField(FieldFileComment, fw.ffo.FlatFileInformationFork.Comment), + NewField(FieldFileType, fw.ffo.FlatFileInformationFork.TypeSignature), + NewField(FieldFileCreateDate, fw.ffo.FlatFileInformationFork.CreateDate), + NewField(FieldFileModifyDate, fw.ffo.FlatFileInformationFork.ModifyDate), + NewField(FieldFileSize, fw.totalSize()), )) return res, err } @@ -401,8 +403,8 @@ func HandleGetFileInfo(cc *ClientConn, t *Transaction) (res []Transaction, err e // * 210 File comment Optional // Fields used in the reply: None func HandleSetFileInfo(cc *ClientConn, t *Transaction) (res []Transaction, err error) { - fileName := t.GetField(fieldFileName).Data - filePath := t.GetField(fieldFilePath).Data + fileName := t.GetField(FieldFileName).Data + filePath := t.GetField(FieldFilePath).Data fullFilePath, err := readPath(cc.Server.Config.FileRoot, filePath, fileName) if err != nil { @@ -418,7 +420,7 @@ func HandleSetFileInfo(cc *ClientConn, t *Transaction) (res []Transaction, err e if err != nil { return res, err } - if t.GetField(fieldFileComment).Data != nil { + if t.GetField(FieldFileComment).Data != nil { switch mode := fi.Mode(); { case mode.IsDir(): if !cc.Authorize(accessSetFolderComment) { @@ -432,7 +434,7 @@ func HandleSetFileInfo(cc *ClientConn, t *Transaction) (res []Transaction, err e } } - if err := hlFile.ffo.FlatFileInformationFork.setComment(t.GetField(fieldFileComment).Data); err != nil { + if err := hlFile.ffo.FlatFileInformationFork.setComment(t.GetField(FieldFileComment).Data); err != nil { return res, err } w, err := hlFile.infoForkWriter() @@ -445,12 +447,12 @@ func HandleSetFileInfo(cc *ClientConn, t *Transaction) (res []Transaction, err e } } - fullNewFilePath, err := readPath(cc.Server.Config.FileRoot, filePath, t.GetField(fieldFileNewName).Data) + fullNewFilePath, err := readPath(cc.Server.Config.FileRoot, filePath, t.GetField(FieldFileNewName).Data) if err != nil { return nil, err } - fileNewName := t.GetField(fieldFileNewName).Data + fileNewName := t.GetField(FieldFileNewName).Data if fileNewName != nil { switch mode := fi.Mode(); { @@ -495,8 +497,8 @@ func HandleSetFileInfo(cc *ClientConn, t *Transaction) (res []Transaction, err e // * 202 File path // Fields used in the reply: none func HandleDeleteFile(cc *ClientConn, t *Transaction) (res []Transaction, err error) { - fileName := t.GetField(fieldFileName).Data - filePath := t.GetField(fieldFilePath).Data + fileName := t.GetField(FieldFileName).Data + filePath := t.GetField(FieldFilePath).Data fullFilePath, err := readPath(cc.Server.Config.FileRoot, filePath, fileName) if err != nil { @@ -537,14 +539,14 @@ func HandleDeleteFile(cc *ClientConn, t *Transaction) (res []Transaction, err er // HandleMoveFile moves files or folders. Note: seemingly not documented func HandleMoveFile(cc *ClientConn, t *Transaction) (res []Transaction, err error) { - fileName := string(t.GetField(fieldFileName).Data) + fileName := string(t.GetField(FieldFileName).Data) - filePath, err := readPath(cc.Server.Config.FileRoot, t.GetField(fieldFilePath).Data, t.GetField(fieldFileName).Data) + filePath, err := readPath(cc.Server.Config.FileRoot, t.GetField(FieldFilePath).Data, t.GetField(FieldFileName).Data) if err != nil { return res, err } - fileNewPath, err := readPath(cc.Server.Config.FileRoot, t.GetField(fieldFileNewPath).Data, nil) + fileNewPath, err := readPath(cc.Server.Config.FileRoot, t.GetField(FieldFileNewPath).Data, nil) if err != nil { return res, err } @@ -590,16 +592,16 @@ func HandleNewFolder(cc *ClientConn, t *Transaction) (res []Transaction, err err res = append(res, cc.NewErrReply(t, "You are not allowed to create folders.")) return res, err } - folderName := string(t.GetField(fieldFileName).Data) + folderName := string(t.GetField(FieldFileName).Data) folderName = path.Join("/", folderName) var subPath string - // fieldFilePath is only present for nested paths - if t.GetField(fieldFilePath).Data != nil { + // FieldFilePath is only present for nested paths + if t.GetField(FieldFilePath).Data != nil { var newFp FilePath - _, err := newFp.Write(t.GetField(fieldFilePath).Data) + _, err := newFp.Write(t.GetField(FieldFilePath).Data) if err != nil { return nil, err } @@ -634,22 +636,22 @@ func HandleSetUser(cc *ClientConn, t *Transaction) (res []Transaction, err error return res, err } - login := DecodeUserString(t.GetField(fieldUserLogin).Data) - userName := string(t.GetField(fieldUserName).Data) + login := DecodeUserString(t.GetField(FieldUserLogin).Data) + userName := string(t.GetField(FieldUserName).Data) - newAccessLvl := t.GetField(fieldUserAccess).Data + newAccessLvl := t.GetField(FieldUserAccess).Data account := cc.Server.Accounts[login] account.Name = userName copy(account.Access[:], newAccessLvl) // If the password field is cleared in the Hotline edit user UI, the SetUser transaction does - // not include fieldUserPassword - if t.GetField(fieldUserPassword).Data == nil { + // not include FieldUserPassword + if t.GetField(FieldUserPassword).Data == nil { account.Password = hashAndSalt([]byte("")) } - if len(t.GetField(fieldUserPassword).Data) > 1 { - account.Password = hashAndSalt(t.GetField(fieldUserPassword).Data) + if len(t.GetField(FieldUserPassword).Data) > 1 { + account.Password = hashAndSalt(t.GetField(FieldUserPassword).Data) } out, err := yaml.Marshal(&account) @@ -664,7 +666,7 @@ func HandleSetUser(cc *ClientConn, t *Transaction) (res []Transaction, err error for _, c := range cc.Server.Clients { if c.Account.Login == login { // Note: comment out these two lines to test server-side deny messages - newT := NewTransaction(tranUserAccess, c.ID, NewField(fieldUserAccess, newAccessLvl)) + newT := NewTransaction(TranUserAccess, c.ID, NewField(FieldUserAccess, newAccessLvl)) res = append(res, *newT) flagBitmap := big.NewInt(int64(binary.BigEndian.Uint16(c.Flags))) @@ -678,11 +680,11 @@ func HandleSetUser(cc *ClientConn, t *Transaction) (res []Transaction, err error c.Account.Access = account.Access cc.sendAll( - tranNotifyChangeUser, - NewField(fieldUserID, *c.ID), - NewField(fieldUserFlags, c.Flags), - NewField(fieldUserName, c.UserName), - NewField(fieldUserIconID, c.Icon), + TranNotifyChangeUser, + NewField(FieldUserID, *c.ID), + NewField(FieldUserFlags, c.Flags), + NewField(FieldUserName, c.UserName), + NewField(FieldUserIconID, c.Icon), ) } } @@ -697,17 +699,17 @@ func HandleGetUser(cc *ClientConn, t *Transaction) (res []Transaction, err error return res, err } - account := cc.Server.Accounts[string(t.GetField(fieldUserLogin).Data)] + account := cc.Server.Accounts[string(t.GetField(FieldUserLogin).Data)] if account == nil { res = append(res, cc.NewErrReply(t, "Account does not exist.")) return res, err } res = append(res, cc.NewReply(t, - NewField(fieldUserName, []byte(account.Name)), - NewField(fieldUserLogin, negateString(t.GetField(fieldUserLogin).Data)), - NewField(fieldUserPassword, []byte(account.Password)), - NewField(fieldUserAccess, account.Access[:]), + NewField(FieldUserName, []byte(account.Name)), + NewField(FieldUserLogin, negateString(t.GetField(FieldUserLogin).Data)), + NewField(FieldUserPassword, []byte(account.Password)), + NewField(FieldUserAccess, account.Access[:]), )) return res, err } @@ -726,7 +728,7 @@ func HandleListUsers(cc *ClientConn, t *Transaction) (res []Transaction, err err return res, err } - userFields = append(userFields, NewField(fieldData, b[:n])) + userFields = append(userFields, NewField(FieldData, b[:n])) } res = append(res, cc.NewReply(t, userFields...)) @@ -750,7 +752,7 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er } if len(subFields) == 1 { - login := DecodeUserString(getField(fieldData, &subFields).Data) + login := DecodeUserString(getField(FieldData, &subFields).Data) cc.logger.Infow("DeleteUser", "login", login) if !cc.Authorize(accessDeleteUser) { @@ -764,7 +766,7 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er continue } - login := DecodeUserString(getField(fieldUserLogin, &subFields).Data) + login := DecodeUserString(getField(FieldUserLogin, &subFields).Data) // check if the login dataFile; if so, we know we are updating an existing user if acc, ok := cc.Server.Accounts[login]; ok { @@ -776,21 +778,21 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er return res, err } - if getField(fieldUserPassword, &subFields) != nil { - newPass := getField(fieldUserPassword, &subFields).Data + if getField(FieldUserPassword, &subFields) != nil { + newPass := getField(FieldUserPassword, &subFields).Data acc.Password = hashAndSalt(newPass) } else { acc.Password = hashAndSalt([]byte("")) } - if getField(fieldUserAccess, &subFields) != nil { - copy(acc.Access[:], getField(fieldUserAccess, &subFields).Data) + if getField(FieldUserAccess, &subFields) != nil { + copy(acc.Access[:], getField(FieldUserAccess, &subFields).Data) } err = cc.Server.UpdateUser( - DecodeUserString(getField(fieldData, &subFields).Data), - DecodeUserString(getField(fieldUserLogin, &subFields).Data), - string(getField(fieldUserName, &subFields).Data), + DecodeUserString(getField(FieldData, &subFields).Data), + DecodeUserString(getField(FieldUserLogin, &subFields).Data), + string(getField(FieldUserName, &subFields).Data), acc.Password, acc.Access, ) @@ -806,7 +808,7 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er } newAccess := accessBitmap{} - copy(newAccess[:], getField(fieldUserAccess, &subFields).Data[:]) + copy(newAccess[:], getField(FieldUserAccess, &subFields).Data[:]) // Prevent account from creating new account with greater permission for i := 0; i < 64; i++ { @@ -817,7 +819,7 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er } } - err := cc.Server.NewUser(login, string(getField(fieldUserName, &subFields).Data), string(getField(fieldUserPassword, &subFields).Data), newAccess) + err := cc.Server.NewUser(login, string(getField(FieldUserName, &subFields).Data), string(getField(FieldUserPassword, &subFields).Data), newAccess) if err != nil { return []Transaction{}, err } @@ -835,7 +837,7 @@ func HandleNewUser(cc *ClientConn, t *Transaction) (res []Transaction, err error return res, err } - login := DecodeUserString(t.GetField(fieldUserLogin).Data) + login := DecodeUserString(t.GetField(FieldUserLogin).Data) // If the account already dataFile, reply with an error if _, ok := cc.Server.Accounts[login]; ok { @@ -844,7 +846,7 @@ func HandleNewUser(cc *ClientConn, t *Transaction) (res []Transaction, err error } newAccess := accessBitmap{} - copy(newAccess[:], t.GetField(fieldUserAccess).Data[:]) + copy(newAccess[:], t.GetField(FieldUserAccess).Data[:]) // Prevent account from creating new account with greater permission for i := 0; i < 64; i++ { @@ -856,7 +858,7 @@ func HandleNewUser(cc *ClientConn, t *Transaction) (res []Transaction, err error } } - if err := cc.Server.NewUser(login, string(t.GetField(fieldUserName).Data), string(t.GetField(fieldUserPassword).Data), newAccess); err != nil { + if err := cc.Server.NewUser(login, string(t.GetField(FieldUserName).Data), string(t.GetField(FieldUserPassword).Data), newAccess); err != nil { return []Transaction{}, err } @@ -871,7 +873,7 @@ func HandleDeleteUser(cc *ClientConn, t *Transaction) (res []Transaction, err er } // TODO: Handle case where account doesn't exist; e.g. delete race condition - login := DecodeUserString(t.GetField(fieldUserLogin).Data) + login := DecodeUserString(t.GetField(FieldUserLogin).Data) if err := cc.Server.DeleteUser(login); err != nil { return res, err @@ -889,9 +891,9 @@ func HandleUserBroadcast(cc *ClientConn, t *Transaction) (res []Transaction, err } cc.sendAll( - tranServerMsg, - NewField(fieldData, t.GetField(tranGetMsgs).Data), - NewField(fieldChatOptions, []byte{0}), + TranServerMsg, + NewField(FieldData, t.GetField(TranGetMsgs).Data), + NewField(FieldChatOptions, []byte{0}), ) res = append(res, cc.NewReply(t)) @@ -912,7 +914,7 @@ func HandleGetClientInfoText(cc *ClientConn, t *Transaction) (res []Transaction, return res, err } - clientID, _ := byteToInt(t.GetField(fieldUserID).Data) + clientID, _ := byteToInt(t.GetField(FieldUserID).Data) clientConn := cc.Server.Clients[uint16(clientID)] if clientConn == nil { @@ -920,8 +922,8 @@ func HandleGetClientInfoText(cc *ClientConn, t *Transaction) (res []Transaction, } res = append(res, cc.NewReply(t, - NewField(fieldData, []byte(clientConn.String())), - NewField(fieldUserName, clientConn.UserName), + NewField(FieldData, []byte(clientConn.String())), + NewField(FieldUserName, clientConn.UserName), )) return res, err } @@ -933,20 +935,20 @@ func HandleGetUserNameList(cc *ClientConn, t *Transaction) (res []Transaction, e } func HandleTranAgreed(cc *ClientConn, t *Transaction) (res []Transaction, err error) { - if t.GetField(fieldUserName).Data != nil { + if t.GetField(FieldUserName).Data != nil { if cc.Authorize(accessAnyName) { - cc.UserName = t.GetField(fieldUserName).Data + cc.UserName = t.GetField(FieldUserName).Data } else { cc.UserName = []byte(cc.Account.Name) } } - cc.Icon = t.GetField(fieldUserIconID).Data + cc.Icon = t.GetField(FieldUserIconID).Data cc.logger = cc.logger.With("name", string(cc.UserName)) cc.logger.Infow("Login successful", "clientVersion", fmt.Sprintf("%v", func() int { i, _ := byteToInt(cc.Version); return i }())) - options := t.GetField(fieldOptions).Data + options := t.GetField(FieldOptions).Data optBitmap := big.NewInt(int64(binary.BigEndian.Uint16(options))) flagBitmap := big.NewInt(int64(binary.BigEndian.Uint16(cc.Flags))) @@ -965,24 +967,24 @@ func HandleTranAgreed(cc *ClientConn, t *Transaction) (res []Transaction, err er // Check auto response if optBitmap.Bit(autoResponse) == 1 { - cc.AutoReply = t.GetField(fieldAutomaticResponse).Data + cc.AutoReply = t.GetField(FieldAutomaticResponse).Data } else { cc.AutoReply = []byte{} } trans := cc.notifyOthers( *NewTransaction( - tranNotifyChangeUser, nil, - NewField(fieldUserName, cc.UserName), - NewField(fieldUserID, *cc.ID), - NewField(fieldUserIconID, cc.Icon), - NewField(fieldUserFlags, cc.Flags), + TranNotifyChangeUser, nil, + NewField(FieldUserName, cc.UserName), + NewField(FieldUserID, *cc.ID), + NewField(FieldUserIconID, cc.Icon), + NewField(FieldUserFlags, cc.Flags), ), ) res = append(res, trans...) if cc.Server.Config.BannerFile != "" { - res = append(res, *NewTransaction(tranServerBanner, cc.ID, NewField(fieldBannerType, []byte("JPEG")))) + res = append(res, *NewTransaction(TranServerBanner, cc.ID, NewField(FieldBannerType, []byte("JPEG")))) } res = append(res, cc.NewReply(t)) @@ -1012,7 +1014,7 @@ func HandleTranOldPostNews(cc *ClientConn, t *Transaction) (res []Transaction, e newsTemplate = cc.Server.Config.NewsDelimiter } - newsPost := fmt.Sprintf(newsTemplate+"\r", cc.UserName, time.Now().Format(newsDateTemplate), t.GetField(fieldData).Data) + newsPost := fmt.Sprintf(newsTemplate+"\r", cc.UserName, time.Now().Format(newsDateTemplate), t.GetField(FieldData).Data) newsPost = strings.Replace(newsPost, "\n", "\r", -1) // update news in memory @@ -1025,8 +1027,8 @@ func HandleTranOldPostNews(cc *ClientConn, t *Transaction) (res []Transaction, e // Notify all clients of updated news cc.sendAll( - tranNewMsg, - NewField(fieldData, []byte(newsPost)), + TranNewMsg, + NewField(FieldData, []byte(newsPost)), ) res = append(res, cc.NewReply(t)) @@ -1039,27 +1041,27 @@ func HandleDisconnectUser(cc *ClientConn, t *Transaction) (res []Transaction, er return res, err } - clientConn := cc.Server.Clients[binary.BigEndian.Uint16(t.GetField(fieldUserID).Data)] + clientConn := cc.Server.Clients[binary.BigEndian.Uint16(t.GetField(FieldUserID).Data)] if clientConn.Authorize(accessCannotBeDiscon) { res = append(res, cc.NewErrReply(t, clientConn.Account.Login+" is not allowed to be disconnected.")) return res, err } - // If fieldOptions is set, then the client IP is banned in addition to disconnected. + // If FieldOptions is set, then the client IP is banned in addition to disconnected. // 00 01 = temporary ban // 00 02 = permanent ban - if t.GetField(fieldOptions).Data != nil { - switch t.GetField(fieldOptions).Data[1] { + if t.GetField(FieldOptions).Data != nil { + switch t.GetField(FieldOptions).Data[1] { case 1: // send message: "You are temporarily banned on this server" cc.logger.Infow("Disconnect & temporarily ban " + string(clientConn.UserName)) res = append(res, *NewTransaction( - tranServerMsg, + TranServerMsg, clientConn.ID, - NewField(fieldData, []byte("You are temporarily banned on this server")), - NewField(fieldChatOptions, []byte{0, 0}), + NewField(FieldData, []byte("You are temporarily banned on this server")), + NewField(FieldChatOptions, []byte{0, 0}), )) banUntil := time.Now().Add(tempBanDuration) @@ -1070,10 +1072,10 @@ func HandleDisconnectUser(cc *ClientConn, t *Transaction) (res []Transaction, er cc.logger.Infow("Disconnect & ban " + string(clientConn.UserName)) res = append(res, *NewTransaction( - tranServerMsg, + TranServerMsg, clientConn.ID, - NewField(fieldData, []byte("You are permanently banned on this server")), - NewField(fieldChatOptions, []byte{0, 0}), + NewField(FieldData, []byte("You are permanently banned on this server")), + NewField(FieldChatOptions, []byte{0, 0}), )) cc.Server.banList[strings.Split(clientConn.RemoteAddr, ":")[0]] = nil @@ -1099,7 +1101,7 @@ func HandleGetNewsCatNameList(cc *ClientConn, t *Transaction) (res []Transaction return res, err } - pathStrs := ReadNewsPath(t.GetField(fieldNewsPath).Data) + pathStrs := ReadNewsPath(t.GetField(FieldNewsPath).Data) cats := cc.Server.GetNewsCatByPath(pathStrs) // To store the keys in slice in sorted order @@ -1116,7 +1118,7 @@ func HandleGetNewsCatNameList(cc *ClientConn, t *Transaction) (res []Transaction cat := cats[k] b, _ := cat.MarshalBinary() fieldData = append(fieldData, NewField( - fieldNewsCatListData15, + FieldNewsCatListData15, b, )) } @@ -1131,8 +1133,8 @@ func HandleNewNewsCat(cc *ClientConn, t *Transaction) (res []Transaction, err er return res, err } - name := string(t.GetField(fieldNewsCatName).Data) - pathStrs := ReadNewsPath(t.GetField(fieldNewsPath).Data) + name := string(t.GetField(FieldNewsCatName).Data) + pathStrs := ReadNewsPath(t.GetField(FieldNewsPath).Data) cats := cc.Server.GetNewsCatByPath(pathStrs) cats[name] = NewsCategoryListData15{ @@ -1158,8 +1160,8 @@ func HandleNewNewsFldr(cc *ClientConn, t *Transaction) (res []Transaction, err e return res, err } - name := string(t.GetField(fieldFileName).Data) - pathStrs := ReadNewsPath(t.GetField(fieldNewsPath).Data) + name := string(t.GetField(FieldFileName).Data) + pathStrs := ReadNewsPath(t.GetField(FieldNewsPath).Data) cc.logger.Infof("Creating new news folder %s", name) @@ -1189,7 +1191,7 @@ func HandleGetNewsArtNameList(cc *ClientConn, t *Transaction) (res []Transaction res = append(res, cc.NewErrReply(t, "You are not allowed to read news.")) return res, err } - pathStrs := ReadNewsPath(t.GetField(fieldNewsPath).Data) + pathStrs := ReadNewsPath(t.GetField(FieldNewsPath).Data) var cat NewsCategoryListData15 cats := cc.Server.ThreadedNews.Categories @@ -1201,7 +1203,7 @@ func HandleGetNewsArtNameList(cc *ClientConn, t *Transaction) (res []Transaction nald := cat.GetNewsArtListData() - res = append(res, cc.NewReply(t, NewField(fieldNewsArtListData, nald.Payload()))) + res = append(res, cc.NewReply(t, NewField(FieldNewsArtListData, nald.Payload()))) return res, err } @@ -1232,14 +1234,14 @@ func HandleGetNewsArtData(cc *ClientConn, t *Transaction) (res []Transaction, er var cat NewsCategoryListData15 cats := cc.Server.ThreadedNews.Categories - for _, fp := range ReadNewsPath(t.GetField(fieldNewsPath).Data) { + for _, fp := range ReadNewsPath(t.GetField(FieldNewsPath).Data) { cat = cats[fp] cats = cats[fp].SubCats } // The official Hotline clients will send the article ID as 2 bytes if possible, but // some third party clients such as Frogblast and Heildrun will always send 4 bytes - convertedID, err := byteToInt(t.GetField(fieldNewsArtID).Data) + convertedID, err := byteToInt(t.GetField(FieldNewsArtID).Data) if err != nil { return res, err } @@ -1251,15 +1253,15 @@ func HandleGetNewsArtData(cc *ClientConn, t *Transaction) (res []Transaction, er } res = append(res, cc.NewReply(t, - NewField(fieldNewsArtTitle, []byte(art.Title)), - NewField(fieldNewsArtPoster, []byte(art.Poster)), - NewField(fieldNewsArtDate, art.Date), - NewField(fieldNewsArtPrevArt, art.PrevArt), - NewField(fieldNewsArtNextArt, art.NextArt), - NewField(fieldNewsArtParentArt, art.ParentArt), - NewField(fieldNewsArt1stChildArt, art.FirstChildArt), - NewField(fieldNewsArtDataFlav, []byte("text/plain")), - NewField(fieldNewsArtData, []byte(art.Data)), + NewField(FieldNewsArtTitle, []byte(art.Title)), + NewField(FieldNewsArtPoster, []byte(art.Poster)), + NewField(FieldNewsArtDate, art.Date), + NewField(FieldNewsArtPrevArt, art.PrevArt), + NewField(FieldNewsArtNextArt, art.NextArt), + NewField(FieldNewsArtParentArt, art.ParentArt), + NewField(FieldNewsArt1stChildArt, art.FirstChildArt), + NewField(FieldNewsArtDataFlav, []byte("text/plain")), + NewField(FieldNewsArtData, []byte(art.Data)), )) return res, err } @@ -1270,7 +1272,7 @@ func HandleGetNewsArtData(cc *ClientConn, t *Transaction) (res []Transaction, er // Fields used in the reply: // None func HandleDelNewsItem(cc *ClientConn, t *Transaction) (res []Transaction, err error) { - pathStrs := ReadNewsPath(t.GetField(fieldNewsPath).Data) + pathStrs := ReadNewsPath(t.GetField(FieldNewsPath).Data) cats := cc.Server.ThreadedNews.Categories delName := pathStrs[len(pathStrs)-1] @@ -1309,8 +1311,8 @@ func HandleDelNewsArt(cc *ClientConn, t *Transaction) (res []Transaction, err er // 325 News path // 326 News article ID // 337 News article – recursive delete Delete child articles (1) or not (0) - pathStrs := ReadNewsPath(t.GetField(fieldNewsPath).Data) - ID, err := byteToInt(t.GetField(fieldNewsArtID).Data) + pathStrs := ReadNewsPath(t.GetField(FieldNewsPath).Data) + ID, err := byteToInt(t.GetField(FieldNewsArtID).Data) if err != nil { return res, err } @@ -1345,13 +1347,13 @@ func HandlePostNewsArt(cc *ClientConn, t *Transaction) (res []Transaction, err e return res, err } - pathStrs := ReadNewsPath(t.GetField(fieldNewsPath).Data) + pathStrs := ReadNewsPath(t.GetField(FieldNewsPath).Data) cats := cc.Server.GetNewsCatByPath(pathStrs[:len(pathStrs)-1]) catName := pathStrs[len(pathStrs)-1] cat := cats[catName] - artID, err := byteToInt(t.GetField(fieldNewsArtID).Data) + artID, err := byteToInt(t.GetField(FieldNewsArtID).Data) if err != nil { return res, err } @@ -1360,7 +1362,7 @@ func HandlePostNewsArt(cc *ClientConn, t *Transaction) (res []Transaction, err e binary.BigEndian.PutUint32(bs, convertedArtID) newArt := NewsArtData{ - Title: string(t.GetField(fieldNewsArtTitle).Data), + Title: string(t.GetField(FieldNewsArtTitle).Data), Poster: string(cc.UserName), Date: toHotlineTime(time.Now()), PrevArt: []byte{0, 0, 0, 0}, @@ -1368,7 +1370,7 @@ func HandlePostNewsArt(cc *ClientConn, t *Transaction) (res []Transaction, err e ParentArt: bs, FirstChildArt: []byte{0, 0, 0, 0}, DataFlav: []byte("text/plain"), - Data: string(t.GetField(fieldNewsArtData).Data), + Data: string(t.GetField(FieldNewsArtData).Data), } var keys []int @@ -1416,7 +1418,7 @@ func HandleGetMsgs(cc *ClientConn, t *Transaction) (res []Transaction, err error return res, err } - res = append(res, cc.NewReply(t, NewField(fieldData, cc.Server.FlatNews))) + res = append(res, cc.NewReply(t, NewField(FieldData, cc.Server.FlatNews))) return res, err } @@ -1427,14 +1429,14 @@ func HandleDownloadFile(cc *ClientConn, t *Transaction) (res []Transaction, err return res, err } - fileName := t.GetField(fieldFileName).Data - filePath := t.GetField(fieldFilePath).Data - resumeData := t.GetField(fieldFileResumeData).Data + fileName := t.GetField(FieldFileName).Data + filePath := t.GetField(FieldFilePath).Data + resumeData := t.GetField(FieldFileResumeData).Data var dataOffset int64 var frd FileResumeData if resumeData != nil { - if err := frd.UnmarshalBinary(t.GetField(fieldFileResumeData).Data); err != nil { + if err := frd.UnmarshalBinary(t.GetField(FieldFileResumeData).Data); err != nil { return res, err } // TODO: handle rsrc fork offset @@ -1458,7 +1460,7 @@ func HandleDownloadFile(cc *ClientConn, t *Transaction) (res []Transaction, err // TODO: refactor to remove this if resumeData != nil { var frd FileResumeData - if err := frd.UnmarshalBinary(t.GetField(fieldFileResumeData).Data); err != nil { + if err := frd.UnmarshalBinary(t.GetField(FieldFileResumeData).Data); err != nil { return res, err } ft.fileResumeData = &frd @@ -1467,16 +1469,16 @@ func HandleDownloadFile(cc *ClientConn, t *Transaction) (res []Transaction, err // Optional field for when a HL v1.5+ client requests file preview // Used only for TEXT, JPEG, GIFF, BMP or PICT files // The value will always be 2 - if t.GetField(fieldFileTransferOptions).Data != nil { - ft.options = t.GetField(fieldFileTransferOptions).Data + if t.GetField(FieldFileTransferOptions).Data != nil { + ft.options = t.GetField(FieldFileTransferOptions).Data xferSize = hlFile.ffo.FlatFileDataForkHeader.DataSize[:] } res = append(res, cc.NewReply(t, - NewField(fieldRefNum, ft.refNum[:]), - NewField(fieldWaitingCount, []byte{0x00, 0x00}), // TODO: Implement waiting count - NewField(fieldTransferSize, xferSize), - NewField(fieldFileSize, hlFile.ffo.FlatFileDataForkHeader.DataSize[:]), + NewField(FieldRefNum, ft.refNum[:]), + NewField(FieldWaitingCount, []byte{0x00, 0x00}), // TODO: Implement waiting count + NewField(FieldTransferSize, xferSize), + NewField(FieldFileSize, hlFile.ffo.FlatFileDataForkHeader.DataSize[:]), )) return res, err @@ -1489,7 +1491,7 @@ func HandleDownloadFolder(cc *ClientConn, t *Transaction) (res []Transaction, er return res, err } - fullFilePath, err := readPath(cc.Server.Config.FileRoot, t.GetField(fieldFilePath).Data, t.GetField(fieldFileName).Data) + fullFilePath, err := readPath(cc.Server.Config.FileRoot, t.GetField(FieldFilePath).Data, t.GetField(FieldFileName).Data) if err != nil { return res, err } @@ -1503,19 +1505,19 @@ func HandleDownloadFolder(cc *ClientConn, t *Transaction) (res []Transaction, er return res, err } - fileTransfer := cc.newFileTransfer(FolderDownload, t.GetField(fieldFileName).Data, t.GetField(fieldFilePath).Data, transferSize) + fileTransfer := cc.newFileTransfer(FolderDownload, t.GetField(FieldFileName).Data, t.GetField(FieldFilePath).Data, transferSize) var fp FilePath - _, err = fp.Write(t.GetField(fieldFilePath).Data) + _, err = fp.Write(t.GetField(FieldFilePath).Data) if err != nil { return res, err } res = append(res, cc.NewReply(t, - NewField(fieldRefNum, fileTransfer.ReferenceNumber), - NewField(fieldTransferSize, transferSize), - NewField(fieldFolderItemCount, itemCount), - NewField(fieldWaitingCount, []byte{0x00, 0x00}), // TODO: Implement waiting count + NewField(FieldRefNum, fileTransfer.ReferenceNumber), + NewField(FieldTransferSize, transferSize), + NewField(FieldFolderItemCount, itemCount), + NewField(FieldWaitingCount, []byte{0x00, 0x00}), // TODO: Implement waiting count )) return res, err } @@ -1529,8 +1531,8 @@ func HandleDownloadFolder(cc *ClientConn, t *Transaction) (res []Transaction, er // 204 File transfer options "Optional Currently set to 1" (TODO: ??) func HandleUploadFolder(cc *ClientConn, t *Transaction) (res []Transaction, err error) { var fp FilePath - if t.GetField(fieldFilePath).Data != nil { - if _, err = fp.Write(t.GetField(fieldFilePath).Data); err != nil { + if t.GetField(FieldFilePath).Data != nil { + if _, err = fp.Write(t.GetField(FieldFilePath).Data); err != nil { return res, err } } @@ -1538,20 +1540,20 @@ func HandleUploadFolder(cc *ClientConn, t *Transaction) (res []Transaction, err // Handle special cases for Upload and Drop Box folders if !cc.Authorize(accessUploadAnywhere) { if !fp.IsUploadDir() && !fp.IsDropbox() { - res = append(res, cc.NewErrReply(t, fmt.Sprintf("Cannot accept upload of the folder \"%v\" because you are only allowed to upload to the \"Uploads\" folder.", string(t.GetField(fieldFileName).Data)))) + res = append(res, cc.NewErrReply(t, fmt.Sprintf("Cannot accept upload of the folder \"%v\" because you are only allowed to upload to the \"Uploads\" folder.", string(t.GetField(FieldFileName).Data)))) return res, err } } fileTransfer := cc.newFileTransfer(FolderUpload, - t.GetField(fieldFileName).Data, - t.GetField(fieldFilePath).Data, - t.GetField(fieldTransferSize).Data, + t.GetField(FieldFileName).Data, + t.GetField(FieldFilePath).Data, + t.GetField(FieldTransferSize).Data, ) - fileTransfer.FolderItemCount = t.GetField(fieldFolderItemCount).Data + fileTransfer.FolderItemCount = t.GetField(FieldFolderItemCount).Data - res = append(res, cc.NewReply(t, NewField(fieldRefNum, fileTransfer.ReferenceNumber))) + res = append(res, cc.NewReply(t, NewField(FieldRefNum, fileTransfer.ReferenceNumber))) return res, err } @@ -1568,10 +1570,10 @@ func HandleUploadFile(cc *ClientConn, t *Transaction) (res []Transaction, err er return res, err } - fileName := t.GetField(fieldFileName).Data - filePath := t.GetField(fieldFilePath).Data - transferOptions := t.GetField(fieldFileTransferOptions).Data - transferSize := t.GetField(fieldTransferSize).Data // not sent for resume + fileName := t.GetField(FieldFileName).Data + filePath := t.GetField(FieldFilePath).Data + transferOptions := t.GetField(FieldFileTransferOptions).Data + transferSize := t.GetField(FieldTransferSize).Data // not sent for resume var fp FilePath if filePath != nil { @@ -1599,7 +1601,7 @@ func HandleUploadFile(cc *ClientConn, t *Transaction) (res []Transaction, err er ft := cc.newFileTransfer(FileUpload, fileName, filePath, transferSize) - replyT := cc.NewReply(t, NewField(fieldRefNum, ft.ReferenceNumber)) + replyT := cc.NewReply(t, NewField(FieldRefNum, ft.ReferenceNumber)) // client has requested to resume a partially transferred file if transferOptions != nil { @@ -1620,7 +1622,7 @@ func HandleUploadFile(cc *ClientConn, t *Transaction) (res []Transaction, err er ft.TransferSize = offset - replyT.Fields = append(replyT.Fields, NewField(fieldFileResumeData, b)) + replyT.Fields = append(replyT.Fields, NewField(FieldFileResumeData, b)) } res = append(res, replyT) @@ -1628,17 +1630,17 @@ func HandleUploadFile(cc *ClientConn, t *Transaction) (res []Transaction, err er } func HandleSetClientUserInfo(cc *ClientConn, t *Transaction) (res []Transaction, err error) { - if len(t.GetField(fieldUserIconID).Data) == 4 { - cc.Icon = t.GetField(fieldUserIconID).Data[2:] + if len(t.GetField(FieldUserIconID).Data) == 4 { + cc.Icon = t.GetField(FieldUserIconID).Data[2:] } else { - cc.Icon = t.GetField(fieldUserIconID).Data + cc.Icon = t.GetField(FieldUserIconID).Data } if cc.Authorize(accessAnyName) { - cc.UserName = t.GetField(fieldUserName).Data + cc.UserName = t.GetField(FieldUserName).Data } // the options field is only passed by the client versions > 1.2.3. - options := t.GetField(fieldOptions).Data + options := t.GetField(FieldOptions).Data if options != nil { optBitmap := big.NewInt(int64(binary.BigEndian.Uint16(options))) flagBitmap := big.NewInt(int64(binary.BigEndian.Uint16(cc.Flags))) @@ -1651,7 +1653,7 @@ func HandleSetClientUserInfo(cc *ClientConn, t *Transaction) (res []Transaction, // Check auto response if optBitmap.Bit(autoResponse) == 1 { - cc.AutoReply = t.GetField(fieldAutomaticResponse).Data + cc.AutoReply = t.GetField(FieldAutomaticResponse).Data } else { cc.AutoReply = []byte{} } @@ -1659,12 +1661,12 @@ func HandleSetClientUserInfo(cc *ClientConn, t *Transaction) (res []Transaction, for _, c := range sortedClients(cc.Server.Clients) { res = append(res, *NewTransaction( - tranNotifyChangeUser, + TranNotifyChangeUser, c.ID, - NewField(fieldUserID, *cc.ID), - NewField(fieldUserIconID, cc.Icon), - NewField(fieldUserFlags, cc.Flags), - NewField(fieldUserName, cc.UserName), + NewField(FieldUserID, *cc.ID), + NewField(FieldUserIconID, cc.Icon), + NewField(FieldUserFlags, cc.Flags), + NewField(FieldUserName, cc.UserName), )) } @@ -1683,7 +1685,7 @@ func HandleKeepAlive(cc *ClientConn, t *Transaction) (res []Transaction, err err func HandleGetFileNameList(cc *ClientConn, t *Transaction) (res []Transaction, err error) { fullPath, err := readPath( cc.Server.Config.FileRoot, - t.GetField(fieldFilePath).Data, + t.GetField(FieldFilePath).Data, nil, ) if err != nil { @@ -1691,8 +1693,8 @@ func HandleGetFileNameList(cc *ClientConn, t *Transaction) (res []Transaction, e } var fp FilePath - if t.GetField(fieldFilePath).Data != nil { - if _, err = fp.Write(t.GetField(fieldFilePath).Data); err != nil { + if t.GetField(FieldFilePath).Data != nil { + if _, err = fp.Write(t.GetField(FieldFilePath).Data); err != nil { return res, err } } @@ -1716,14 +1718,14 @@ func HandleGetFileNameList(cc *ClientConn, t *Transaction) (res []Transaction, e // ================================= // Hotline private chat flow // ================================= -// 1. ClientA sends tranInviteNewChat to server with user ID to invite +// 1. ClientA sends TranInviteNewChat to server with user ID to invite // 2. Server creates new ChatID -// 3. Server sends tranInviteToChat to invitee +// 3. Server sends TranInviteToChat to invitee // 4. Server replies to ClientA with new Chat ID // // A dialog box pops up in the invitee client with options to accept or decline the invitation. // If Accepted is clicked: -// 1. ClientB sends tranJoinChat with fieldChatID +// 1. ClientB sends TranJoinChat with FieldChatID // HandleInviteNewChat invites users to new private chat func HandleInviteNewChat(cc *ClientConn, t *Transaction) (res []Transaction, err error) { @@ -1733,7 +1735,7 @@ func HandleInviteNewChat(cc *ClientConn, t *Transaction) (res []Transaction, err } // Client to Invite - targetID := t.GetField(fieldUserID).Data + targetID := t.GetField(FieldUserID).Data newChatID := cc.Server.NewPrivateChat(cc) // Check if target user has "Refuse private chat" flag @@ -1744,33 +1746,33 @@ func HandleInviteNewChat(cc *ClientConn, t *Transaction) (res []Transaction, err if flagBitmap.Bit(userFLagRefusePChat) == 1 { res = append(res, *NewTransaction( - tranServerMsg, + TranServerMsg, cc.ID, - NewField(fieldData, []byte(string(targetClient.UserName)+" does not accept private chats.")), - NewField(fieldUserName, targetClient.UserName), - NewField(fieldUserID, *targetClient.ID), - NewField(fieldOptions, []byte{0, 2}), + NewField(FieldData, []byte(string(targetClient.UserName)+" does not accept private chats.")), + NewField(FieldUserName, targetClient.UserName), + NewField(FieldUserID, *targetClient.ID), + NewField(FieldOptions, []byte{0, 2}), ), ) } else { res = append(res, *NewTransaction( - tranInviteToChat, + TranInviteToChat, &targetID, - NewField(fieldChatID, newChatID), - NewField(fieldUserName, cc.UserName), - NewField(fieldUserID, *cc.ID), + NewField(FieldChatID, newChatID), + NewField(FieldUserName, cc.UserName), + NewField(FieldUserID, *cc.ID), ), ) } res = append(res, cc.NewReply(t, - NewField(fieldChatID, newChatID), - NewField(fieldUserName, cc.UserName), - NewField(fieldUserID, *cc.ID), - NewField(fieldUserIconID, cc.Icon), - NewField(fieldUserFlags, cc.Flags), + NewField(FieldChatID, newChatID), + NewField(FieldUserName, cc.UserName), + NewField(FieldUserID, *cc.ID), + NewField(FieldUserIconID, cc.Icon), + NewField(FieldUserFlags, cc.Flags), ), ) @@ -1784,26 +1786,26 @@ func HandleInviteToChat(cc *ClientConn, t *Transaction) (res []Transaction, err } // Client to Invite - targetID := t.GetField(fieldUserID).Data - chatID := t.GetField(fieldChatID).Data + targetID := t.GetField(FieldUserID).Data + chatID := t.GetField(FieldChatID).Data res = append(res, *NewTransaction( - tranInviteToChat, + TranInviteToChat, &targetID, - NewField(fieldChatID, chatID), - NewField(fieldUserName, cc.UserName), - NewField(fieldUserID, *cc.ID), + NewField(FieldChatID, chatID), + NewField(FieldUserName, cc.UserName), + NewField(FieldUserID, *cc.ID), ), ) res = append(res, cc.NewReply( t, - NewField(fieldChatID, chatID), - NewField(fieldUserName, cc.UserName), - NewField(fieldUserID, *cc.ID), - NewField(fieldUserIconID, cc.Icon), - NewField(fieldUserFlags, cc.Flags), + NewField(FieldChatID, chatID), + NewField(FieldUserName, cc.UserName), + NewField(FieldUserID, *cc.ID), + NewField(FieldUserIconID, cc.Icon), + NewField(FieldUserFlags, cc.Flags), ), ) @@ -1811,7 +1813,7 @@ func HandleInviteToChat(cc *ClientConn, t *Transaction) (res []Transaction, err } func HandleRejectChatInvite(cc *ClientConn, t *Transaction) (res []Transaction, err error) { - chatID := t.GetField(fieldChatID).Data + chatID := t.GetField(FieldChatID).Data chatInt := binary.BigEndian.Uint32(chatID) privChat := cc.Server.PrivateChats[chatInt] @@ -1821,10 +1823,10 @@ func HandleRejectChatInvite(cc *ClientConn, t *Transaction) (res []Transaction, for _, c := range sortedClients(privChat.ClientConn) { res = append(res, *NewTransaction( - tranChatMsg, + TranChatMsg, c.ID, - NewField(fieldChatID, chatID), - NewField(fieldData, resMsg), + NewField(FieldChatID, chatID), + NewField(FieldData, resMsg), ), ) } @@ -1838,29 +1840,29 @@ func HandleRejectChatInvite(cc *ClientConn, t *Transaction) (res []Transaction, // * 300 User name with info (Optional) // * 300 (more user names with info) func HandleJoinChat(cc *ClientConn, t *Transaction) (res []Transaction, err error) { - chatID := t.GetField(fieldChatID).Data + chatID := t.GetField(FieldChatID).Data chatInt := binary.BigEndian.Uint32(chatID) privChat := cc.Server.PrivateChats[chatInt] - // Send tranNotifyChatChangeUser to current members of the chat to inform of new user + // Send TranNotifyChatChangeUser to current members of the chat to inform of new user for _, c := range sortedClients(privChat.ClientConn) { res = append(res, *NewTransaction( - tranNotifyChatChangeUser, + TranNotifyChatChangeUser, c.ID, - NewField(fieldChatID, chatID), - NewField(fieldUserName, cc.UserName), - NewField(fieldUserID, *cc.ID), - NewField(fieldUserIconID, cc.Icon), - NewField(fieldUserFlags, cc.Flags), + NewField(FieldChatID, chatID), + NewField(FieldUserName, cc.UserName), + NewField(FieldUserID, *cc.ID), + NewField(FieldUserIconID, cc.Icon), + NewField(FieldUserFlags, cc.Flags), ), ) } privChat.ClientConn[cc.uint16ID()] = cc - replyFields := []Field{NewField(fieldChatSubject, []byte(privChat.Subject))} + replyFields := []Field{NewField(FieldChatSubject, []byte(privChat.Subject))} for _, c := range sortedClients(privChat.ClientConn) { user := User{ ID: *c.ID, @@ -1869,7 +1871,7 @@ func HandleJoinChat(cc *ClientConn, t *Transaction) (res []Transaction, err erro Name: string(c.UserName), } - replyFields = append(replyFields, NewField(fieldUsernameWithInfo, user.Payload())) + replyFields = append(replyFields, NewField(FieldUsernameWithInfo, user.Payload())) } res = append(res, cc.NewReply(t, replyFields...)) @@ -1878,11 +1880,11 @@ func HandleJoinChat(cc *ClientConn, t *Transaction) (res []Transaction, err erro // HandleLeaveChat is sent from a v1.8+ Hotline client when the user exits a private chat // Fields used in the request: -// - 114 fieldChatID +// - 114 FieldChatID // // Reply is not expected. func HandleLeaveChat(cc *ClientConn, t *Transaction) (res []Transaction, err error) { - chatID := t.GetField(fieldChatID).Data + chatID := t.GetField(FieldChatID).Data chatInt := binary.BigEndian.Uint32(chatID) privChat, ok := cc.Server.PrivateChats[chatInt] @@ -1896,10 +1898,10 @@ func HandleLeaveChat(cc *ClientConn, t *Transaction) (res []Transaction, err err for _, c := range sortedClients(privChat.ClientConn) { res = append(res, *NewTransaction( - tranNotifyChatDeleteUser, + TranNotifyChatDeleteUser, c.ID, - NewField(fieldChatID, chatID), - NewField(fieldUserID, *cc.ID), + NewField(FieldChatID, chatID), + NewField(FieldUserID, *cc.ID), ), ) } @@ -1913,19 +1915,19 @@ func HandleLeaveChat(cc *ClientConn, t *Transaction) (res []Transaction, err err // * 115 Chat subject // Reply is not expected. func HandleSetChatSubject(cc *ClientConn, t *Transaction) (res []Transaction, err error) { - chatID := t.GetField(fieldChatID).Data + chatID := t.GetField(FieldChatID).Data chatInt := binary.BigEndian.Uint32(chatID) privChat := cc.Server.PrivateChats[chatInt] - privChat.Subject = string(t.GetField(fieldChatSubject).Data) + privChat.Subject = string(t.GetField(FieldChatSubject).Data) for _, c := range sortedClients(privChat.ClientConn) { res = append(res, *NewTransaction( - tranNotifyChatSubject, + TranNotifyChatSubject, c.ID, - NewField(fieldChatID, chatID), - NewField(fieldChatSubject, t.GetField(fieldChatSubject).Data), + NewField(FieldChatID, chatID), + NewField(FieldChatSubject, t.GetField(FieldChatSubject).Data), ), ) } @@ -1946,9 +1948,9 @@ func HandleMakeAlias(cc *ClientConn, t *Transaction) (res []Transaction, err err res = append(res, cc.NewErrReply(t, "You are not allowed to make aliases.")) return res, err } - fileName := t.GetField(fieldFileName).Data - filePath := t.GetField(fieldFilePath).Data - fileNewPath := t.GetField(fieldFileNewPath).Data + fileName := t.GetField(FieldFileName).Data + filePath := t.GetField(FieldFilePath).Data + fileNewPath := t.GetField(FieldFileNewPath).Data fullFilePath, err := readPath(cc.Server.Config.FileRoot, filePath, fileName) if err != nil { @@ -1975,8 +1977,8 @@ func HandleMakeAlias(cc *ClientConn, t *Transaction) (res []Transaction, err err // Fields used in the request: // None // Fields used in the reply: -// 107 fieldRefNum Used later for transfer -// 108 fieldTransferSize Size of data to be downloaded +// 107 FieldRefNum Used later for transfer +// 108 FieldTransferSize Size of data to be downloaded func HandleDownloadBanner(cc *ClientConn, t *Transaction) (res []Transaction, err error) { fi, err := cc.Server.FS.Stat(filepath.Join(cc.Server.ConfigDir, cc.Server.Config.BannerFile)) if err != nil { @@ -1988,8 +1990,8 @@ func HandleDownloadBanner(cc *ClientConn, t *Transaction) (res []Transaction, er binary.BigEndian.PutUint32(ft.TransferSize, uint32(fi.Size())) res = append(res, cc.NewReply(t, - NewField(fieldRefNum, ft.refNum[:]), - NewField(fieldTransferSize, ft.TransferSize), + NewField(FieldRefNum, ft.refNum[:]), + NewField(FieldTransferSize, ft.TransferSize), )) return res, err diff --git a/hotline/transaction_handlers_test.go b/hotline/transaction_handlers_test.go index 3f46f64..751590e 100644 --- a/hotline/transaction_handlers_test.go +++ b/hotline/transaction_handlers_test.go @@ -73,8 +73,8 @@ func TestHandleSetChatSubject(t *testing.T) { ID: []byte{0, 0, 0, 1}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldChatID, []byte{0, 0, 0, 1}), - NewField(fieldChatSubject, []byte("Test Subject")), + NewField(FieldChatID, []byte{0, 0, 0, 1}), + NewField(FieldChatSubject, []byte("Test Subject")), }, }, }, @@ -87,8 +87,8 @@ func TestHandleSetChatSubject(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1) ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldChatID, []byte{0, 0, 0, 1}), - NewField(fieldChatSubject, []byte("Test Subject")), + NewField(FieldChatID, []byte{0, 0, 0, 1}), + NewField(FieldChatSubject, []byte("Test Subject")), }, }, { @@ -99,8 +99,8 @@ func TestHandleSetChatSubject(t *testing.T) { ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1) ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldChatID, []byte{0, 0, 0, 1}), - NewField(fieldChatSubject, []byte("Test Subject")), + NewField(FieldChatID, []byte{0, 0, 0, 1}), + NewField(FieldChatSubject, []byte("Test Subject")), }, }, }, @@ -174,7 +174,7 @@ func TestHandleLeaveChat(t *testing.T) { }, }, }, - t: NewTransaction(tranDeleteUser, nil, NewField(fieldChatID, []byte{0, 0, 0, 1})), + t: NewTransaction(TranDeleteUser, nil, NewField(FieldChatID, []byte{0, 0, 0, 1})), }, want: []Transaction{ { @@ -185,8 +185,8 @@ func TestHandleLeaveChat(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1) ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldChatID, []byte{0, 0, 0, 1}), - NewField(fieldUserID, []byte{0, 2}), + NewField(FieldChatID, []byte{0, 0, 0, 1}), + NewField(FieldUserID, []byte{0, 2}), }, }, }, @@ -257,11 +257,11 @@ func TestHandleGetUserNameList(t *testing.T) { ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ NewField( - fieldUsernameWithInfo, + FieldUsernameWithInfo, []byte{00, 01, 00, 02, 00, 03, 00, 02, 00, 04}, ), NewField( - fieldUsernameWithInfo, + FieldUsernameWithInfo, []byte{00, 02, 00, 02, 00, 03, 00, 02, 00, 04}, ), }, @@ -324,7 +324,7 @@ func TestHandleChatSend(t *testing.T) { }, t: &Transaction{ Fields: []Field{ - NewField(fieldData, []byte("hai")), + NewField(FieldData, []byte("hai")), }, }, }, @@ -337,7 +337,7 @@ func TestHandleChatSend(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1) ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}), + NewField(FieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}), }, }, { @@ -348,7 +348,7 @@ func TestHandleChatSend(t *testing.T) { ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1) ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}), + NewField(FieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}), }, }, }, @@ -385,8 +385,8 @@ func TestHandleChatSend(t *testing.T) { }, t: &Transaction{ Fields: []Field{ - NewField(fieldData, []byte("hai")), - NewField(fieldChatID, []byte{0, 0, 0, 0}), + NewField(FieldData, []byte("hai")), + NewField(FieldChatID, []byte{0, 0, 0, 0}), }, }, }, @@ -399,7 +399,7 @@ func TestHandleChatSend(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1) ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}), + NewField(FieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}), }, }, { @@ -410,7 +410,7 @@ func TestHandleChatSend(t *testing.T) { ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1) ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}), + NewField(FieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}), }, }, }, @@ -431,8 +431,8 @@ func TestHandleChatSend(t *testing.T) { }, }, t: NewTransaction( - tranChatSend, &[]byte{0, 1}, - NewField(fieldData, []byte("hai")), + TranChatSend, &[]byte{0, 1}, + NewField(FieldData, []byte("hai")), ), }, want: []Transaction{ @@ -443,14 +443,14 @@ func TestHandleChatSend(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to participate in chat.")), + NewField(FieldError, []byte("You are not allowed to participate in chat.")), }, }, }, wantErr: false, }, { - name: "sends chat msg as emote if fieldChatOptions is set to 1", + name: "sends chat msg as emote if FieldChatOptions is set to 1", args: args{ cc: &ClientConn{ Account: &Account{ @@ -480,8 +480,8 @@ func TestHandleChatSend(t *testing.T) { }, t: &Transaction{ Fields: []Field{ - NewField(fieldData, []byte("performed action")), - NewField(fieldChatOptions, []byte{0x00, 0x01}), + NewField(FieldData, []byte("performed action")), + NewField(FieldChatOptions, []byte{0x00, 0x01}), }, }, }, @@ -494,7 +494,7 @@ func TestHandleChatSend(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldData, []byte("\r*** Testy McTest performed action")), + NewField(FieldData, []byte("\r*** Testy McTest performed action")), }, }, { @@ -505,14 +505,14 @@ func TestHandleChatSend(t *testing.T) { ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldData, []byte("\r*** Testy McTest performed action")), + NewField(FieldData, []byte("\r*** Testy McTest performed action")), }, }, }, wantErr: false, }, { - name: "does not send chat msg as emote if fieldChatOptions is set to 0", + name: "does not send chat msg as emote if FieldChatOptions is set to 0", args: args{ cc: &ClientConn{ Account: &Account{ @@ -542,8 +542,8 @@ func TestHandleChatSend(t *testing.T) { }, t: &Transaction{ Fields: []Field{ - NewField(fieldData, []byte("hello")), - NewField(fieldChatOptions, []byte{0x00, 0x00}), + NewField(FieldData, []byte("hello")), + NewField(FieldChatOptions, []byte{0x00, 0x00}), }, }, }, @@ -556,7 +556,7 @@ func TestHandleChatSend(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldData, []byte("\r Testy McTest: hello")), + NewField(FieldData, []byte("\r Testy McTest: hello")), }, }, { @@ -567,7 +567,7 @@ func TestHandleChatSend(t *testing.T) { ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldData, []byte("\r Testy McTest: hello")), + NewField(FieldData, []byte("\r Testy McTest: hello")), }, }, }, @@ -607,7 +607,7 @@ func TestHandleChatSend(t *testing.T) { }, t: &Transaction{ Fields: []Field{ - NewField(fieldData, []byte("hai")), + NewField(FieldData, []byte("hai")), }, }, }, @@ -620,7 +620,7 @@ func TestHandleChatSend(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1) ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}), + NewField(FieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}), }, }, }, @@ -675,8 +675,8 @@ func TestHandleChatSend(t *testing.T) { }, t: &Transaction{ Fields: []Field{ - NewField(fieldData, []byte("hai")), - NewField(fieldChatID, []byte{0, 0, 0, 1}), + NewField(FieldData, []byte("hai")), + NewField(FieldChatID, []byte{0, 0, 0, 1}), }, }, }, @@ -689,8 +689,8 @@ func TestHandleChatSend(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldChatID, []byte{0, 0, 0, 1}), - NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}), + NewField(FieldChatID, []byte{0, 0, 0, 1}), + NewField(FieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}), }, }, { @@ -701,8 +701,8 @@ func TestHandleChatSend(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldChatID, []byte{0, 0, 0, 1}), - NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}), + NewField(FieldChatID, []byte{0, 0, 0, 1}), + NewField(FieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}), }, }, }, @@ -751,9 +751,9 @@ func TestHandleGetFileInfo(t *testing.T) { }, }, t: NewTransaction( - tranGetFileInfo, nil, - NewField(fieldFileName, []byte("testfile.txt")), - NewField(fieldFilePath, []byte{0x00, 0x00}), + TranGetFileInfo, nil, + NewField(FieldFileName, []byte("testfile.txt")), + NewField(FieldFilePath, []byte{0x00, 0x00}), ), }, wantRes: []Transaction{ @@ -765,14 +765,14 @@ func TestHandleGetFileInfo(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1) ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldFileName, []byte("testfile.txt")), - NewField(fieldFileTypeString, []byte("Text File")), - NewField(fieldFileCreatorString, []byte("ttxt")), - NewField(fieldFileComment, []byte{}), - NewField(fieldFileType, []byte("TEXT")), - NewField(fieldFileCreateDate, make([]byte, 8)), - NewField(fieldFileModifyDate, make([]byte, 8)), - NewField(fieldFileSize, []byte{0x0, 0x0, 0x0, 0x17}), + NewField(FieldFileName, []byte("testfile.txt")), + NewField(FieldFileTypeString, []byte("Text File")), + NewField(FieldFileCreatorString, []byte("ttxt")), + NewField(FieldFileComment, []byte{}), + NewField(FieldFileType, []byte("TEXT")), + NewField(FieldFileCreateDate, make([]byte, 8)), + NewField(FieldFileModifyDate, make([]byte, 8)), + NewField(FieldFileSize, []byte{0x0, 0x0, 0x0, 0x17}), }, }, }, @@ -835,7 +835,7 @@ func TestHandleNewFolder(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to create folders.")), + NewField(FieldError, []byte("You are not allowed to create folders.")), }, }, }, @@ -866,9 +866,9 @@ func TestHandleNewFolder(t *testing.T) { }, }, t: NewTransaction( - tranNewFolder, &[]byte{0, 1}, - NewField(fieldFileName, []byte("testFolder")), - NewField(fieldFilePath, []byte{ + TranNewFolder, &[]byte{0, 1}, + NewField(FieldFileName, []byte("testFolder")), + NewField(FieldFilePath, []byte{ 0x00, 0x01, 0x00, 0x00, 0x03, @@ -913,8 +913,8 @@ func TestHandleNewFolder(t *testing.T) { }, }, t: NewTransaction( - tranNewFolder, &[]byte{0, 1}, - NewField(fieldFileName, []byte("testFolder")), + TranNewFolder, &[]byte{0, 1}, + NewField(FieldFileName, []byte("testFolder")), ), }, wantRes: []Transaction{ @@ -954,9 +954,9 @@ func TestHandleNewFolder(t *testing.T) { }, }, t: NewTransaction( - tranNewFolder, &[]byte{0, 1}, - NewField(fieldFileName, []byte("testFolder")), - NewField(fieldFilePath, []byte{ + TranNewFolder, &[]byte{0, 1}, + NewField(FieldFileName, []byte("testFolder")), + NewField(FieldFilePath, []byte{ 0x00, }), ), @@ -965,7 +965,7 @@ func TestHandleNewFolder(t *testing.T) { wantErr: true, }, { - name: "fieldFileName does not allow directory traversal", + name: "FieldFileName does not allow directory traversal", args: args{ cc: &ClientConn{ Account: &Account{ @@ -989,8 +989,8 @@ func TestHandleNewFolder(t *testing.T) { }, }, t: NewTransaction( - tranNewFolder, &[]byte{0, 1}, - NewField(fieldFileName, []byte("../../testFolder")), + TranNewFolder, &[]byte{0, 1}, + NewField(FieldFileName, []byte("../../testFolder")), ), }, wantRes: []Transaction{ @@ -1005,7 +1005,7 @@ func TestHandleNewFolder(t *testing.T) { }, wantErr: false, }, { - name: "fieldFilePath does not allow directory traversal", + name: "FieldFilePath does not allow directory traversal", args: args{ cc: &ClientConn{ Account: &Account{ @@ -1029,9 +1029,9 @@ func TestHandleNewFolder(t *testing.T) { }, }, t: NewTransaction( - tranNewFolder, &[]byte{0, 1}, - NewField(fieldFileName, []byte("testFolder")), - NewField(fieldFilePath, []byte{ + TranNewFolder, &[]byte{0, 1}, + NewField(FieldFileName, []byte("testFolder")), + NewField(FieldFilePath, []byte{ 0x00, 0x02, 0x00, 0x00, 0x03, @@ -1104,9 +1104,9 @@ func TestHandleUploadFile(t *testing.T) { }, }, t: NewTransaction( - tranUploadFile, &[]byte{0, 1}, - NewField(fieldFileName, []byte("testFile")), - NewField(fieldFilePath, []byte{ + TranUploadFile, &[]byte{0, 1}, + NewField(FieldFileName, []byte("testFile")), + NewField(FieldFilePath, []byte{ 0x00, 0x01, 0x00, 0x00, 0x03, @@ -1122,7 +1122,7 @@ func TestHandleUploadFile(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}), // rand.Seed(1) + NewField(FieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}), // rand.Seed(1) }, }, }, @@ -1140,9 +1140,9 @@ func TestHandleUploadFile(t *testing.T) { }, }, t: NewTransaction( - tranUploadFile, &[]byte{0, 1}, - NewField(fieldFileName, []byte("testFile")), - NewField(fieldFilePath, []byte{ + TranUploadFile, &[]byte{0, 1}, + NewField(FieldFileName, []byte("testFile")), + NewField(FieldFilePath, []byte{ 0x00, 0x01, 0x00, 0x00, 0x03, @@ -1158,7 +1158,7 @@ func TestHandleUploadFile(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to upload files.")), // rand.Seed(1) + NewField(FieldError, []byte("You are not allowed to upload files.")), // rand.Seed(1) }, }, }, @@ -1224,10 +1224,10 @@ func TestHandleMakeAlias(t *testing.T) { }, }, t: NewTransaction( - tranMakeFileAlias, &[]byte{0, 1}, - NewField(fieldFileName, []byte("testFile")), - NewField(fieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))), - NewField(fieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))), + TranMakeFileAlias, &[]byte{0, 1}, + NewField(FieldFileName, []byte("testFile")), + NewField(FieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))), + NewField(FieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))), ), }, wantRes: []Transaction{ @@ -1275,10 +1275,10 @@ func TestHandleMakeAlias(t *testing.T) { }, }, t: NewTransaction( - tranMakeFileAlias, &[]byte{0, 1}, - NewField(fieldFileName, []byte("testFile")), - NewField(fieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))), - NewField(fieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))), + TranMakeFileAlias, &[]byte{0, 1}, + NewField(FieldFileName, []byte("testFile")), + NewField(FieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))), + NewField(FieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))), ), }, wantRes: []Transaction{ @@ -1289,7 +1289,7 @@ func TestHandleMakeAlias(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("Error creating alias")), + NewField(FieldError, []byte("Error creating alias")), }, }, }, @@ -1316,15 +1316,15 @@ func TestHandleMakeAlias(t *testing.T) { }, }, t: NewTransaction( - tranMakeFileAlias, &[]byte{0, 1}, - NewField(fieldFileName, []byte("testFile")), - NewField(fieldFilePath, []byte{ + TranMakeFileAlias, &[]byte{0, 1}, + NewField(FieldFileName, []byte("testFile")), + NewField(FieldFilePath, []byte{ 0x00, 0x01, 0x00, 0x00, 0x03, 0x2e, 0x2e, 0x2e, }), - NewField(fieldFileNewPath, []byte{ + NewField(FieldFileNewPath, []byte{ 0x00, 0x01, 0x00, 0x00, 0x03, @@ -1340,7 +1340,7 @@ func TestHandleMakeAlias(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to make aliases.")), + NewField(FieldError, []byte("You are not allowed to make aliases.")), }, }, }, @@ -1394,8 +1394,8 @@ func TestHandleGetUser(t *testing.T) { }, }, t: NewTransaction( - tranGetUser, &[]byte{0, 1}, - NewField(fieldUserLogin, []byte("guest")), + TranGetUser, &[]byte{0, 1}, + NewField(FieldUserLogin, []byte("guest")), ), }, wantRes: []Transaction{ @@ -1406,10 +1406,10 @@ func TestHandleGetUser(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldUserName, []byte("Guest")), - NewField(fieldUserLogin, negateString([]byte("guest"))), - NewField(fieldUserPassword, []byte("password")), - NewField(fieldUserAccess, []byte{0, 0, 0, 0, 0, 0, 0, 0}), + NewField(FieldUserName, []byte("Guest")), + NewField(FieldUserLogin, negateString([]byte("guest"))), + NewField(FieldUserPassword, []byte("password")), + NewField(FieldUserAccess, []byte{0, 0, 0, 0, 0, 0, 0, 0}), }, }, }, @@ -1430,8 +1430,8 @@ func TestHandleGetUser(t *testing.T) { }, }, t: NewTransaction( - tranGetUser, &[]byte{0, 1}, - NewField(fieldUserLogin, []byte("nonExistentUser")), + TranGetUser, &[]byte{0, 1}, + NewField(FieldUserLogin, []byte("nonExistentUser")), ), }, wantRes: []Transaction{ @@ -1442,7 +1442,7 @@ func TestHandleGetUser(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to view accounts.")), + NewField(FieldError, []byte("You are not allowed to view accounts.")), }, }, }, @@ -1464,8 +1464,8 @@ func TestHandleGetUser(t *testing.T) { }, }, t: NewTransaction( - tranGetUser, &[]byte{0, 1}, - NewField(fieldUserLogin, []byte("nonExistentUser")), + TranGetUser, &[]byte{0, 1}, + NewField(FieldUserLogin, []byte("nonExistentUser")), ), }, wantRes: []Transaction{ @@ -1476,7 +1476,7 @@ func TestHandleGetUser(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("Account does not exist.")), + NewField(FieldError, []byte("Account does not exist.")), }, }, }, @@ -1534,8 +1534,8 @@ func TestHandleDeleteUser(t *testing.T) { }, }, t: NewTransaction( - tranDeleteUser, &[]byte{0, 1}, - NewField(fieldUserLogin, negateString([]byte("testuser"))), + TranDeleteUser, &[]byte{0, 1}, + NewField(FieldUserLogin, negateString([]byte("testuser"))), ), }, wantRes: []Transaction{ @@ -1565,8 +1565,8 @@ func TestHandleDeleteUser(t *testing.T) { }, }, t: NewTransaction( - tranDeleteUser, &[]byte{0, 1}, - NewField(fieldUserLogin, negateString([]byte("testuser"))), + TranDeleteUser, &[]byte{0, 1}, + NewField(FieldUserLogin, negateString([]byte("testuser"))), ), }, wantRes: []Transaction{ @@ -1577,7 +1577,7 @@ func TestHandleDeleteUser(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to delete accounts.")), + NewField(FieldError, []byte("You are not allowed to delete accounts.")), }, }, }, @@ -1623,7 +1623,7 @@ func TestHandleGetMsgs(t *testing.T) { }, }, t: NewTransaction( - tranGetMsgs, &[]byte{0, 1}, + TranGetMsgs, &[]byte{0, 1}, ), }, wantRes: []Transaction{ @@ -1634,7 +1634,7 @@ func TestHandleGetMsgs(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldData, []byte("TEST")), + NewField(FieldData, []byte("TEST")), }, }, }, @@ -1655,7 +1655,7 @@ func TestHandleGetMsgs(t *testing.T) { }, }, t: NewTransaction( - tranGetMsgs, &[]byte{0, 1}, + TranGetMsgs, &[]byte{0, 1}, ), }, wantRes: []Transaction{ @@ -1666,7 +1666,7 @@ func TestHandleGetMsgs(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to read news.")), + NewField(FieldError, []byte("You are not allowed to read news.")), }, }, }, @@ -1711,7 +1711,7 @@ func TestHandleNewUser(t *testing.T) { }, }, t: NewTransaction( - tranNewUser, &[]byte{0, 1}, + TranNewUser, &[]byte{0, 1}, ), }, wantRes: []Transaction{ @@ -1722,7 +1722,7 @@ func TestHandleNewUser(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to create new accounts.")), + NewField(FieldError, []byte("You are not allowed to create new accounts.")), }, }, }, @@ -1744,10 +1744,10 @@ func TestHandleNewUser(t *testing.T) { }, }, t: NewTransaction( - tranNewUser, &[]byte{0, 1}, - NewField(fieldUserLogin, []byte("userB")), + TranNewUser, &[]byte{0, 1}, + NewField(FieldUserLogin, []byte("userB")), NewField( - fieldUserAccess, + FieldUserAccess, func() []byte { var bits accessBitmap bits.Set(accessDisconUser) @@ -1764,7 +1764,7 @@ func TestHandleNewUser(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("Cannot create account with more access than yourself.")), + NewField(FieldError, []byte("Cannot create account with more access than yourself.")), }, }, }, @@ -1809,7 +1809,7 @@ func TestHandleListUsers(t *testing.T) { }, }, t: NewTransaction( - tranNewUser, &[]byte{0, 1}, + TranNewUser, &[]byte{0, 1}, ), }, wantRes: []Transaction{ @@ -1820,7 +1820,7 @@ func TestHandleListUsers(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to view accounts.")), + NewField(FieldError, []byte("You are not allowed to view accounts.")), }, }, }, @@ -1849,8 +1849,8 @@ func TestHandleListUsers(t *testing.T) { }, }, t: NewTransaction( - tranGetClientInfoText, &[]byte{0, 1}, - NewField(fieldUserID, []byte{0, 1}), + TranGetClientInfoText, &[]byte{0, 1}, + NewField(FieldUserID, []byte{0, 1}), ), }, wantRes: []Transaction{ @@ -1861,7 +1861,7 @@ func TestHandleListUsers(t *testing.T) { ID: []byte{0, 0, 0, 0}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldData, []byte{ + NewField(FieldData, []byte{ 0x00, 0x04, 0x00, 0x66, 0x00, 0x05, 0x67, 0x75, 0x65, 0x73, 0x74, 0x00, 0x69, 0x00, 0x05, 0x98, 0x8a, 0x9a, 0x8c, 0x8b, 0x00, 0x6e, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x6a, 0x00, 0x01, 0x78, @@ -1907,7 +1907,7 @@ func TestHandleDownloadFile(t *testing.T) { }, Server: &Server{}, }, - t: NewTransaction(tranDownloadFile, &[]byte{0, 1}), + t: NewTransaction(TranDownloadFile, &[]byte{0, 1}), }, wantRes: []Transaction{ { @@ -1917,7 +1917,7 @@ func TestHandleDownloadFile(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to download files.")), + NewField(FieldError, []byte("You are not allowed to download files.")), }, }, }, @@ -1949,8 +1949,8 @@ func TestHandleDownloadFile(t *testing.T) { t: NewTransaction( accessDownloadFile, &[]byte{0, 1}, - NewField(fieldFileName, []byte("testfile.txt")), - NewField(fieldFilePath, []byte{0x0, 0x00}), + NewField(FieldFileName, []byte("testfile.txt")), + NewField(FieldFilePath, []byte{0x0, 0x00}), ), }, wantRes: []Transaction{ @@ -1961,10 +1961,10 @@ func TestHandleDownloadFile(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}), - NewField(fieldWaitingCount, []byte{0x00, 0x00}), - NewField(fieldTransferSize, []byte{0x00, 0x00, 0x00, 0xa5}), - NewField(fieldFileSize, []byte{0x00, 0x00, 0x00, 0x17}), + NewField(FieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}), + NewField(FieldWaitingCount, []byte{0x00, 0x00}), + NewField(FieldTransferSize, []byte{0x00, 0x00, 0x00, 0xa5}), + NewField(FieldFileSize, []byte{0x00, 0x00, 0x00, 0x17}), }, }, }, @@ -2013,10 +2013,10 @@ func TestHandleDownloadFile(t *testing.T) { t: NewTransaction( accessDownloadFile, &[]byte{0, 1}, - NewField(fieldFileName, []byte("testfile-1k")), - NewField(fieldFilePath, []byte{0x00, 0x00}), + NewField(FieldFileName, []byte("testfile-1k")), + NewField(FieldFilePath, []byte{0x00, 0x00}), NewField( - fieldFileResumeData, + FieldFileResumeData, func() []byte { frd := FileResumeData{ Format: [4]byte{}, @@ -2052,10 +2052,10 @@ func TestHandleDownloadFile(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}), - NewField(fieldWaitingCount, []byte{0x00, 0x00}), - NewField(fieldTransferSize, []byte{0x00, 0x00, 0x03, 0x8d}), - NewField(fieldFileSize, []byte{0x00, 0x00, 0x03, 0x00}), + NewField(FieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}), + NewField(FieldWaitingCount, []byte{0x00, 0x00}), + NewField(FieldTransferSize, []byte{0x00, 0x00, 0x03, 0x8d}), + NewField(FieldFileSize, []byte{0x00, 0x00, 0x03, 0x00}), }, }, }, @@ -2101,24 +2101,24 @@ func TestHandleUpdateUser(t *testing.T) { }, }, t: NewTransaction( - tranUpdateUser, + TranUpdateUser, &[]byte{0, 0}, - NewField(fieldData, []byte{ + NewField(FieldData, []byte{ 0x00, 0x04, // field count - 0x00, 0x69, // fieldUserLogin = 105 + 0x00, 0x69, // FieldUserLogin = 105 0x00, 0x03, 0x9d, 0x9d, 0x9d, - 0x00, 0x6a, // fieldUserPassword = 106 + 0x00, 0x6a, // FieldUserPassword = 106 0x00, 0x03, 0x9c, 0x9c, 0x9c, - 0x00, 0x66, // fieldUserName = 102 + 0x00, 0x66, // FieldUserName = 102 0x00, 0x03, 0x61, 0x61, 0x61, - 0x00, 0x6e, // fieldUserAccess = 110 + 0x00, 0x6e, // FieldUserAccess = 110 0x00, 0x08, 0x60, 0x70, 0x0c, 0x20, 0x03, 0x80, 0x00, 0x00, }), @@ -2132,7 +2132,7 @@ func TestHandleUpdateUser(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to create new accounts.")), + NewField(FieldError, []byte("You are not allowed to create new accounts.")), }, }, }, @@ -2157,24 +2157,24 @@ func TestHandleUpdateUser(t *testing.T) { }, }, t: NewTransaction( - tranUpdateUser, + TranUpdateUser, &[]byte{0, 0}, - NewField(fieldData, []byte{ + NewField(FieldData, []byte{ 0x00, 0x04, // field count - 0x00, 0x69, // fieldUserLogin = 105 + 0x00, 0x69, // FieldUserLogin = 105 0x00, 0x03, 0x9d, 0x9d, 0x9d, - 0x00, 0x6a, // fieldUserPassword = 106 + 0x00, 0x6a, // FieldUserPassword = 106 0x00, 0x03, 0x9c, 0x9c, 0x9c, - 0x00, 0x66, // fieldUserName = 102 + 0x00, 0x66, // FieldUserName = 102 0x00, 0x03, 0x61, 0x61, 0x61, - 0x00, 0x6e, // fieldUserAccess = 110 + 0x00, 0x6e, // FieldUserAccess = 110 0x00, 0x08, 0x60, 0x70, 0x0c, 0x20, 0x03, 0x80, 0x00, 0x00, }), @@ -2188,7 +2188,7 @@ func TestHandleUpdateUser(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to modify accounts.")), + NewField(FieldError, []byte("You are not allowed to modify accounts.")), }, }, }, @@ -2212,9 +2212,9 @@ func TestHandleUpdateUser(t *testing.T) { }, }, t: NewTransaction( - tranUpdateUser, + TranUpdateUser, &[]byte{0, 0}, - NewField(fieldData, []byte{ + NewField(FieldData, []byte{ 0x00, 0x01, 0x00, 0x65, 0x00, 0x03, @@ -2230,7 +2230,7 @@ func TestHandleUpdateUser(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to delete accounts.")), + NewField(FieldError, []byte("You are not allowed to delete accounts.")), }, }, }, @@ -2272,7 +2272,7 @@ func TestHandleDelNewsArt(t *testing.T) { }, }, t: NewTransaction( - tranDelNewsArt, + TranDelNewsArt, &[]byte{0, 0}, ), }, @@ -2284,7 +2284,7 @@ func TestHandleDelNewsArt(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to delete news articles.")), + NewField(FieldError, []byte("You are not allowed to delete news articles.")), }, }, }, @@ -2325,7 +2325,7 @@ func TestHandleDisconnectUser(t *testing.T) { }, }, t: NewTransaction( - tranDelNewsArt, + TranDelNewsArt, &[]byte{0, 0}, ), }, @@ -2337,7 +2337,7 @@ func TestHandleDisconnectUser(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to disconnect users.")), + NewField(FieldError, []byte("You are not allowed to disconnect users.")), }, }, }, @@ -2370,9 +2370,9 @@ func TestHandleDisconnectUser(t *testing.T) { }, }, t: NewTransaction( - tranDelNewsArt, + TranDelNewsArt, &[]byte{0, 0}, - NewField(fieldUserID, []byte{0, 1}), + NewField(FieldUserID, []byte{0, 1}), ), }, wantRes: []Transaction{ @@ -2383,7 +2383,7 @@ func TestHandleDisconnectUser(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("unnamed is not allowed to be disconnected.")), + NewField(FieldError, []byte("unnamed is not allowed to be disconnected.")), }, }, }, @@ -2424,7 +2424,7 @@ func TestHandleSendInstantMsg(t *testing.T) { }, }, t: NewTransaction( - tranDelNewsArt, + TranDelNewsArt, &[]byte{0, 0}, ), }, @@ -2436,7 +2436,7 @@ func TestHandleSendInstantMsg(t *testing.T) { ID: []byte{0, 0, 0, 0}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to send private messages.")), + NewField(FieldError, []byte("You are not allowed to send private messages.")), }, }, }, @@ -2465,20 +2465,20 @@ func TestHandleSendInstantMsg(t *testing.T) { }, }, t: NewTransaction( - tranSendInstantMsg, + TranSendInstantMsg, &[]byte{0, 1}, - NewField(fieldData, []byte("hai")), - NewField(fieldUserID, []byte{0, 2}), + NewField(FieldData, []byte("hai")), + NewField(FieldUserID, []byte{0, 2}), ), }, wantRes: []Transaction{ *NewTransaction( - tranServerMsg, + TranServerMsg, &[]byte{0, 2}, - NewField(fieldData, []byte("hai")), - NewField(fieldUserName, []byte("User1")), - NewField(fieldUserID, []byte{0, 1}), - NewField(fieldOptions, []byte{0, 1}), + NewField(FieldData, []byte("hai")), + NewField(FieldUserName, []byte("User1")), + NewField(FieldUserID, []byte{0, 1}), + NewField(FieldOptions, []byte{0, 1}), ), { clientID: &[]byte{0, 1}, @@ -2517,28 +2517,28 @@ func TestHandleSendInstantMsg(t *testing.T) { }, }, t: NewTransaction( - tranSendInstantMsg, + TranSendInstantMsg, &[]byte{0, 1}, - NewField(fieldData, []byte("hai")), - NewField(fieldUserID, []byte{0, 2}), + NewField(FieldData, []byte("hai")), + NewField(FieldUserID, []byte{0, 2}), ), }, wantRes: []Transaction{ *NewTransaction( - tranServerMsg, + TranServerMsg, &[]byte{0, 2}, - NewField(fieldData, []byte("hai")), - NewField(fieldUserName, []byte("User1")), - NewField(fieldUserID, []byte{0, 1}), - NewField(fieldOptions, []byte{0, 1}), + NewField(FieldData, []byte("hai")), + NewField(FieldUserName, []byte("User1")), + NewField(FieldUserID, []byte{0, 1}), + NewField(FieldOptions, []byte{0, 1}), ), *NewTransaction( - tranServerMsg, + TranServerMsg, &[]byte{0, 1}, - NewField(fieldData, []byte("autohai")), - NewField(fieldUserName, []byte("User2")), - NewField(fieldUserID, []byte{0, 2}), - NewField(fieldOptions, []byte{0, 1}), + NewField(FieldData, []byte("autohai")), + NewField(FieldUserName, []byte("User2")), + NewField(FieldUserID, []byte{0, 2}), + NewField(FieldOptions, []byte{0, 1}), ), { clientID: &[]byte{0, 1}, @@ -2576,20 +2576,20 @@ func TestHandleSendInstantMsg(t *testing.T) { }, }, t: NewTransaction( - tranSendInstantMsg, + TranSendInstantMsg, &[]byte{0, 1}, - NewField(fieldData, []byte("hai")), - NewField(fieldUserID, []byte{0, 2}), + NewField(FieldData, []byte("hai")), + NewField(FieldUserID, []byte{0, 2}), ), }, wantRes: []Transaction{ *NewTransaction( - tranServerMsg, + TranServerMsg, &[]byte{0, 1}, - NewField(fieldData, []byte("User2 does not accept private messages.")), - NewField(fieldUserName, []byte("User2")), - NewField(fieldUserID, []byte{0, 2}), - NewField(fieldOptions, []byte{0, 2}), + NewField(FieldData, []byte("User2 does not accept private messages.")), + NewField(FieldUserName, []byte("User2")), + NewField(FieldUserID, []byte{0, 2}), + NewField(FieldOptions, []byte{0, 2}), ), { clientID: &[]byte{0, 1}, @@ -2662,9 +2662,9 @@ func TestHandleDeleteFile(t *testing.T) { }, }, t: NewTransaction( - tranDeleteFile, &[]byte{0, 1}, - NewField(fieldFileName, []byte("testfile")), - NewField(fieldFilePath, []byte{ + TranDeleteFile, &[]byte{0, 1}, + NewField(FieldFileName, []byte("testfile")), + NewField(FieldFilePath, []byte{ 0x00, 0x01, 0x00, 0x00, 0x03, @@ -2680,7 +2680,7 @@ func TestHandleDeleteFile(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to delete files.")), + NewField(FieldError, []byte("You are not allowed to delete files.")), }, }, }, @@ -2727,9 +2727,9 @@ func TestHandleDeleteFile(t *testing.T) { }, }, t: NewTransaction( - tranDeleteFile, &[]byte{0, 1}, - NewField(fieldFileName, []byte("testfile")), - NewField(fieldFilePath, []byte{ + TranDeleteFile, &[]byte{0, 1}, + NewField(FieldFileName, []byte("testfile")), + NewField(FieldFilePath, []byte{ 0x00, 0x01, 0x00, 0x00, 0x03, @@ -2776,7 +2776,7 @@ func TestHandleGetFileNameList(t *testing.T) { wantErr assert.ErrorAssertionFunc }{ { - name: "when fieldFilePath is a drop box, but user does not have accessViewDropBoxes ", + name: "when FieldFilePath is a drop box, but user does not have accessViewDropBoxes ", args: args{ cc: &ClientConn{ Account: &Account{ @@ -2796,8 +2796,8 @@ func TestHandleGetFileNameList(t *testing.T) { }, }, t: NewTransaction( - tranGetFileNameList, &[]byte{0, 1}, - NewField(fieldFilePath, []byte{ + TranGetFileNameList, &[]byte{0, 1}, + NewField(FieldFilePath, []byte{ 0x00, 0x01, 0x00, 0x00, 0x08, @@ -2813,7 +2813,7 @@ func TestHandleGetFileNameList(t *testing.T) { ID: []byte{0, 0, 0, 0}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to view drop boxes.")), + NewField(FieldError, []byte("You are not allowed to view drop boxes.")), }, }, }, @@ -2833,8 +2833,8 @@ func TestHandleGetFileNameList(t *testing.T) { }, }, t: NewTransaction( - tranGetFileNameList, &[]byte{0, 1}, - NewField(fieldFilePath, []byte{ + TranGetFileNameList, &[]byte{0, 1}, + NewField(FieldFilePath, []byte{ 0x00, 0x00, 0x00, 0x00, }), @@ -2849,7 +2849,7 @@ func TestHandleGetFileNameList(t *testing.T) { ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ NewField( - fieldFileNameWithInfo, + FieldFileNameWithInfo, func() []byte { fnwi := FileNameWithInfo{ fileNameWithInfoHeader: fileNameWithInfoHeader{ @@ -2910,8 +2910,8 @@ func TestHandleGetClientInfoText(t *testing.T) { }, }, t: NewTransaction( - tranGetClientInfoText, &[]byte{0, 1}, - NewField(fieldUserID, []byte{0, 1}), + TranGetClientInfoText, &[]byte{0, 1}, + NewField(FieldUserID, []byte{0, 1}), ), }, wantRes: []Transaction{ @@ -2922,7 +2922,7 @@ func TestHandleGetClientInfoText(t *testing.T) { ID: []byte{0, 0, 0, 0}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to get client info.")), + NewField(FieldError, []byte("You are not allowed to get client info.")), }, }, }, @@ -2969,8 +2969,8 @@ func TestHandleGetClientInfoText(t *testing.T) { }, }, t: NewTransaction( - tranGetClientInfoText, &[]byte{0, 1}, - NewField(fieldUserID, []byte{0, 1}), + TranGetClientInfoText, &[]byte{0, 1}, + NewField(FieldUserID, []byte{0, 1}), ), }, wantRes: []Transaction{ @@ -2981,7 +2981,7 @@ func TestHandleGetClientInfoText(t *testing.T) { ID: []byte{0, 0, 0, 0}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldData, []byte( + NewField(FieldData, []byte( strings.Replace(`Nickname: Testy McTest Name: test Account: test @@ -3009,7 +3009,7 @@ None. `, "\n", "\r", -1)), ), - NewField(fieldUserName, []byte("Testy McTest")), + NewField(FieldUserName, []byte("Testy McTest")), }, }, }, @@ -3061,10 +3061,10 @@ func TestHandleTranAgreed(t *testing.T) { }, }, t: NewTransaction( - tranAgreed, nil, - NewField(fieldUserName, []byte("username")), - NewField(fieldUserIconID, []byte{0, 1}), - NewField(fieldOptions, []byte{0, 0}), + TranAgreed, nil, + NewField(FieldUserName, []byte("username")), + NewField(FieldUserIconID, []byte{0, 1}), + NewField(FieldOptions, []byte{0, 0}), ), }, wantRes: []Transaction{ @@ -3076,7 +3076,7 @@ func TestHandleTranAgreed(t *testing.T) { ID: []byte{0, 0, 0, 0}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldBannerType, []byte("JPEG")), + NewField(FieldBannerType, []byte("JPEG")), }, }, { @@ -3136,9 +3136,9 @@ func TestHandleSetClientUserInfo(t *testing.T) { }, }, t: NewTransaction( - tranSetClientUserInfo, nil, - NewField(fieldUserIconID, []byte{0, 1}), - NewField(fieldUserName, []byte("NOPE")), + TranSetClientUserInfo, nil, + NewField(FieldUserIconID, []byte{0, 1}), + NewField(FieldUserName, []byte("NOPE")), ), }, wantRes: []Transaction{ @@ -3150,10 +3150,10 @@ func TestHandleSetClientUserInfo(t *testing.T) { ID: []byte{0, 0, 0, 0}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldUserID, []byte{0, 1}), - NewField(fieldUserIconID, []byte{0, 1}), - NewField(fieldUserFlags, []byte{0, 1}), - NewField(fieldUserName, []byte("Guest"))}, + NewField(FieldUserID, []byte{0, 1}), + NewField(FieldUserIconID, []byte{0, 1}), + NewField(FieldUserFlags, []byte{0, 1}), + NewField(FieldUserName, []byte("Guest"))}, }, }, wantErr: assert.NoError, @@ -3202,8 +3202,8 @@ func TestHandleDelNewsItem(t *testing.T) { }, }, t: NewTransaction( - tranDelNewsItem, nil, - NewField(fieldNewsPath, + TranDelNewsItem, nil, + NewField(FieldNewsPath, []byte{ 0, 1, 0, 0, @@ -3222,7 +3222,7 @@ func TestHandleDelNewsItem(t *testing.T) { ID: []byte{0, 0, 0, 0}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to delete news categories.")), + NewField(FieldError, []byte("You are not allowed to delete news categories.")), }, }, }, @@ -3248,8 +3248,8 @@ func TestHandleDelNewsItem(t *testing.T) { }, }, t: NewTransaction( - tranDelNewsItem, nil, - NewField(fieldNewsPath, + TranDelNewsItem, nil, + NewField(FieldNewsPath, []byte{ 0, 1, 0, 0, @@ -3268,7 +3268,7 @@ func TestHandleDelNewsItem(t *testing.T) { ID: []byte{0, 0, 0, 0}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to delete news folders.")), + NewField(FieldError, []byte("You are not allowed to delete news folders.")), }, }, }, @@ -3304,8 +3304,8 @@ func TestHandleDelNewsItem(t *testing.T) { }, }, t: NewTransaction( - tranDelNewsItem, nil, - NewField(fieldNewsPath, + TranDelNewsItem, nil, + NewField(FieldNewsPath, []byte{ 0, 1, 0, 0, @@ -3375,7 +3375,7 @@ func TestHandleDownloadBanner(t *testing.T) { }(), }, }, - t: NewTransaction(tranDownloadBanner, nil), + t: NewTransaction(TranDownloadBanner, nil), }, wantRes: []Transaction{ { @@ -3386,8 +3386,8 @@ func TestHandleDownloadBanner(t *testing.T) { ID: []byte{0, 0, 0, 0}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldRefNum, []byte{1, 2, 3, 4}), - NewField(fieldTransferSize, []byte{0, 0, 0, 0x64}), + NewField(FieldRefNum, []byte{1, 2, 3, 4}), + NewField(FieldTransferSize, []byte{0, 0, 0, 0x64}), }, }, }, @@ -3429,8 +3429,8 @@ func TestHandleTranOldPostNews(t *testing.T) { }, }, t: NewTransaction( - tranOldPostNews, &[]byte{0, 1}, - NewField(fieldData, []byte("hai")), + TranOldPostNews, &[]byte{0, 1}, + NewField(FieldData, []byte("hai")), ), }, wantRes: []Transaction{ @@ -3441,7 +3441,7 @@ func TestHandleTranOldPostNews(t *testing.T) { ID: []byte{0, 0, 0, 0}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to post news.")), + NewField(FieldError, []byte("You are not allowed to post news.")), }, }, }, @@ -3469,8 +3469,8 @@ func TestHandleTranOldPostNews(t *testing.T) { }, }, t: NewTransaction( - tranOldPostNews, &[]byte{0, 1}, - NewField(fieldData, []byte("hai")), + TranOldPostNews, &[]byte{0, 1}, + NewField(FieldData, []byte("hai")), ), }, wantRes: []Transaction{ @@ -3519,7 +3519,7 @@ func TestHandleInviteNewChat(t *testing.T) { }(), }, }, - t: NewTransaction(tranInviteNewChat, &[]byte{0, 1}), + t: NewTransaction(TranInviteNewChat, &[]byte{0, 1}), }, wantRes: []Transaction{ { @@ -3529,7 +3529,7 @@ func TestHandleInviteNewChat(t *testing.T) { ID: []byte{0, 0, 0, 0}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to request private chat.")), + NewField(FieldError, []byte("You are not allowed to request private chat.")), }, }, }, @@ -3562,8 +3562,8 @@ func TestHandleInviteNewChat(t *testing.T) { }, }, t: NewTransaction( - tranInviteNewChat, &[]byte{0, 1}, - NewField(fieldUserID, []byte{0, 2}), + TranInviteNewChat, &[]byte{0, 1}, + NewField(FieldUserID, []byte{0, 2}), ), }, wantRes: []Transaction{ @@ -3575,9 +3575,9 @@ func TestHandleInviteNewChat(t *testing.T) { ID: []byte{0, 0, 0, 0}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}), - NewField(fieldUserName, []byte("UserA")), - NewField(fieldUserID, []byte{0, 1}), + NewField(FieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}), + NewField(FieldUserName, []byte("UserA")), + NewField(FieldUserID, []byte{0, 1}), }, }, @@ -3589,11 +3589,11 @@ func TestHandleInviteNewChat(t *testing.T) { ID: []byte{0, 0, 0, 0}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}), - NewField(fieldUserName, []byte("UserA")), - NewField(fieldUserID, []byte{0, 1}), - NewField(fieldUserIconID, []byte{0, 1}), - NewField(fieldUserFlags, []byte{0, 0}), + NewField(FieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}), + NewField(FieldUserName, []byte("UserA")), + NewField(FieldUserID, []byte{0, 1}), + NewField(FieldUserIconID, []byte{0, 1}), + NewField(FieldUserFlags, []byte{0, 0}), }, }, }, @@ -3626,8 +3626,8 @@ func TestHandleInviteNewChat(t *testing.T) { }, }, t: NewTransaction( - tranInviteNewChat, &[]byte{0, 1}, - NewField(fieldUserID, []byte{0, 2}), + TranInviteNewChat, &[]byte{0, 1}, + NewField(FieldUserID, []byte{0, 2}), ), }, wantRes: []Transaction{ @@ -3639,10 +3639,10 @@ func TestHandleInviteNewChat(t *testing.T) { ID: []byte{0, 0, 0, 0}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldData, []byte("UserB does not accept private chats.")), - NewField(fieldUserName, []byte("UserB")), - NewField(fieldUserID, []byte{0, 2}), - NewField(fieldOptions, []byte{0, 2}), + NewField(FieldData, []byte("UserB does not accept private chats.")), + NewField(FieldUserName, []byte("UserB")), + NewField(FieldUserID, []byte{0, 2}), + NewField(FieldOptions, []byte{0, 2}), }, }, { @@ -3653,11 +3653,11 @@ func TestHandleInviteNewChat(t *testing.T) { ID: []byte{0, 0, 0, 0}, ErrorCode: []byte{0, 0, 0, 0}, Fields: []Field{ - NewField(fieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}), - NewField(fieldUserName, []byte("UserA")), - NewField(fieldUserID, []byte{0, 1}), - NewField(fieldUserIconID, []byte{0, 1}), - NewField(fieldUserFlags, []byte{0, 0}), + NewField(FieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}), + NewField(FieldUserName, []byte("UserA")), + NewField(FieldUserID, []byte{0, 1}), + NewField(FieldUserIconID, []byte{0, 1}), + NewField(FieldUserFlags, []byte{0, 0}), }, }, }, @@ -3702,7 +3702,7 @@ func TestHandleGetNewsArtData(t *testing.T) { }, }, t: NewTransaction( - tranGetNewsArtData, &[]byte{0, 1}, + TranGetNewsArtData, &[]byte{0, 1}, ), }, wantRes: []Transaction{ @@ -3713,7 +3713,7 @@ func TestHandleGetNewsArtData(t *testing.T) { ID: []byte{0x9a, 0xcb, 0x04, 0x42}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to read news.")), + NewField(FieldError, []byte("You are not allowed to read news.")), }, }, }, @@ -3757,7 +3757,7 @@ func TestHandleGetNewsArtNameList(t *testing.T) { }, }, t: NewTransaction( - tranGetNewsArtNameList, &[]byte{0, 1}, + TranGetNewsArtNameList, &[]byte{0, 1}, ), }, wantRes: []Transaction{ @@ -3767,7 +3767,7 @@ func TestHandleGetNewsArtNameList(t *testing.T) { Type: []byte{0, 0}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to read news.")), + NewField(FieldError, []byte("You are not allowed to read news.")), }, }, }, @@ -3812,7 +3812,7 @@ func TestHandleNewNewsFldr(t *testing.T) { }, }, t: NewTransaction( - tranGetNewsArtNameList, &[]byte{0, 1}, + TranGetNewsArtNameList, &[]byte{0, 1}, ), }, wantRes: []Transaction{ @@ -3822,7 +3822,7 @@ func TestHandleNewNewsFldr(t *testing.T) { Type: []byte{0, 0}, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte("You are not allowed to create news folders.")), + NewField(FieldError, []byte("You are not allowed to create news folders.")), }, }, }, @@ -3860,9 +3860,9 @@ func TestHandleNewNewsFldr(t *testing.T) { }, }, t: NewTransaction( - tranGetNewsArtNameList, &[]byte{0, 1}, - NewField(fieldFileName, []byte("testFolder")), - NewField(fieldNewsPath, + TranGetNewsArtNameList, &[]byte{0, 1}, + NewField(FieldFileName, []byte("testFolder")), + NewField(FieldNewsPath, []byte{ 0, 1, 0, 0, @@ -3917,9 +3917,9 @@ func TestHandleNewNewsFldr(t *testing.T) { // }, // }, // t: NewTransaction( - // tranGetNewsArtNameList, &[]byte{0, 1}, - // NewField(fieldFileName, []byte("testFolder")), - // NewField(fieldNewsPath, + // TranGetNewsArtNameList, &[]byte{0, 1}, + // NewField(FieldFileName, []byte("testFolder")), + // NewField(FieldNewsPath, // []byte{ // 0, 1, // 0, 0, @@ -3937,7 +3937,7 @@ func TestHandleNewNewsFldr(t *testing.T) { // Type: []byte{0, 0}, // ErrorCode: []byte{0, 0, 0, 1}, // Fields: []Field{ - // NewField(fieldError, []byte("Error creating news folder.")), + // NewField(FieldError, []byte("Error creating news folder.")), // }, // }, // }, diff --git a/hotline/transaction_test.go b/hotline/transaction_test.go index 4b4f183..65f428a 100644 --- a/hotline/transaction_test.go +++ b/hotline/transaction_test.go @@ -22,10 +22,10 @@ func TestReadFields(t *testing.T) { args: args{ paramCount: []byte{0x00, 0x02}, buf: []byte{ - 0x00, 0x65, // ID: fieldData + 0x00, 0x65, // ID: FieldData 0x00, 0x04, // Size: 2 bytes 0x01, 0x02, 0x03, 0x04, // Data - 0x00, 0x66, // ID: fieldUserName + 0x00, 0x66, // ID: FieldUserName 0x00, 0x02, // Size: 2 bytes 0x00, 0x01, // Data }, @@ -58,7 +58,7 @@ func TestReadFields(t *testing.T) { args: args{ paramCount: []byte{0x00, 0x01}, buf: []byte{ - 0x00, 0x65, // ID: fieldData + 0x00, 0x65, // ID: FieldData 0x00, 0x04, // Size: 4 bytes 0x01, 0x02, 0x03, // Data }, @@ -71,10 +71,10 @@ func TestReadFields(t *testing.T) { args: args{ paramCount: []byte{0x00, 0x01}, buf: []byte{ - 0x00, 0x65, // ID: fieldData + 0x00, 0x65, // ID: FieldData 0x00, 0x02, // Size: 2 bytes 0x01, 0x02, // Data - 0x00, 0x65, // ID: fieldData + 0x00, 0x65, // ID: FieldData 0x00, 0x04, // Size: 4 bytes 0x01, 0x02, 0x03, // Data }, @@ -87,7 +87,7 @@ func TestReadFields(t *testing.T) { args: args{ paramCount: []byte{0x00, 0x01}, buf: []byte{ - 0x00, 0x65, // ID: fieldData + 0x00, 0x65, // ID: FieldData 0x00, 0x02, // Size: 2 bytes 0x01, 0x02, 0x03, // Data }, @@ -163,10 +163,10 @@ func Test_transactionScanner(t *testing.T) { 00, 00, 00, 0x10, 00, 00, 00, 0x10, 00, 02, - 00, 0x6c, // 108 - fieldTransferSize + 00, 0x6c, // 108 - FieldTransferSize 00, 02, 0x63, 0x3b, - 00, 0x6b, // 107 = fieldRefNum + 00, 0x6b, // 107 = FieldRefNum 00, 0x04, 00, 0x02, 0x93, 0x47, }, @@ -182,10 +182,10 @@ func Test_transactionScanner(t *testing.T) { 00, 00, 00, 0x10, 00, 00, 00, 0x10, 00, 02, - 00, 0x6c, // 108 - fieldTransferSize + 00, 0x6c, // 108 - FieldTransferSize 00, 02, 0x63, 0x3b, - 00, 0x6b, // 107 = fieldRefNum + 00, 0x6b, // 107 = FieldRefNum 00, 0x04, 00, 0x02, 0x93, 0x47, }, @@ -203,10 +203,10 @@ func Test_transactionScanner(t *testing.T) { 00, 00, 00, 0x10, 00, 00, 00, 0x10, 00, 02, - 00, 0x6c, // 108 - fieldTransferSize + 00, 0x6c, // 108 - FieldTransferSize 00, 02, 0x63, 0x3b, - 00, 0x6b, // 107 = fieldRefNum + 00, 0x6b, // 107 = FieldRefNum 00, 0x04, 00, 0x02, 0x93, 0x47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -223,10 +223,10 @@ func Test_transactionScanner(t *testing.T) { 00, 00, 00, 0x10, 00, 00, 00, 0x10, 00, 02, - 00, 0x6c, // 108 - fieldTransferSize + 00, 0x6c, // 108 - FieldTransferSize 00, 02, 0x63, 0x3b, - 00, 0x6b, // 107 = fieldRefNum + 00, 0x6b, // 107 = FieldRefNum 00, 0x04, 00, 0x02, 0x93, 0x47, }, @@ -244,10 +244,10 @@ func Test_transactionScanner(t *testing.T) { 00, 00, 00, 0x10, 00, 00, 00, 0x10, 00, 02, - 00, 0x6c, // 108 - fieldTransferSize + 00, 0x6c, // 108 - FieldTransferSize 00, 02, 0x63, 0x3b, - 00, 0x6b, // 107 = fieldRefNum + 00, 0x6b, // 107 = FieldRefNum 00, 0x04, 00, 0x02, 0x93, 0x47, 0, @@ -258,10 +258,10 @@ func Test_transactionScanner(t *testing.T) { 00, 00, 00, 0x10, 00, 00, 00, 0x10, 00, 02, - 00, 0x6c, // 108 - fieldTransferSize + 00, 0x6c, // 108 - FieldTransferSize 00, 02, 0x63, 0x3b, - 00, 0x6b, // 107 = fieldRefNum + 00, 0x6b, // 107 = FieldRefNum 00, 0x04, 00, 0x02, 0x93, 0x47, }, @@ -277,10 +277,10 @@ func Test_transactionScanner(t *testing.T) { 00, 00, 00, 0x10, 00, 00, 00, 0x10, 00, 02, - 00, 0x6c, // 108 - fieldTransferSize + 00, 0x6c, // 108 - FieldTransferSize 00, 02, 0x63, 0x3b, - 00, 0x6b, // 107 = fieldRefNum + 00, 0x6b, // 107 = FieldRefNum 00, 0x04, 00, 0x02, 0x93, 0x47, }, diff --git a/hotline/ui.go b/hotline/ui.go index 8b0a8c5..c005fb4 100644 --- a/hotline/ui.go +++ b/hotline/ui.go @@ -1,7 +1,6 @@ package hotline import ( - "bufio" "fmt" "github.com/gdamore/tcell/v2" "github.com/rivo/tview" @@ -49,8 +48,8 @@ func NewUI(c *Client) *UI { } _ = c.Send( - *NewTransaction(tranChatSend, nil, - NewField(fieldData, []byte(chatInput.GetText())), + *NewTransaction(TranChatSend, nil, + NewField(FieldData, []byte(chatInput.GetText())), ), ) chatInput.SetText("") // clear the input field after chat send @@ -88,7 +87,7 @@ func (ui *UI) showBookmarks() *tview.List { list.Box.SetBorder(true).SetTitle("| Bookmarks |") shortcut := 97 // rune for "a" - for i, srv := range ui.HLClient.pref.Bookmarks { + for i, srv := range ui.HLClient.Pref.Bookmarks { addr := srv.Addr login := srv.Login pass := srv.Password @@ -105,7 +104,7 @@ func (ui *UI) showBookmarks() *tview.List { } func (ui *UI) getTrackerList() *tview.List { - listing, err := GetListing(ui.HLClient.pref.Tracker) + listing, err := GetListing(ui.HLClient.Pref.Tracker) if err != nil { // TODO } @@ -137,27 +136,27 @@ func (ui *UI) getTrackerList() *tview.List { } func (ui *UI) renderSettingsForm() *tview.Flex { - iconStr := strconv.Itoa(ui.HLClient.pref.IconID) + iconStr := strconv.Itoa(ui.HLClient.Pref.IconID) settingsForm := tview.NewForm() - settingsForm.AddInputField("Your Name", ui.HLClient.pref.Username, 0, nil, nil) + settingsForm.AddInputField("Your Name", ui.HLClient.Pref.Username, 0, nil, nil) settingsForm.AddInputField("IconID", iconStr, 0, func(idStr string, _ rune) bool { _, err := strconv.Atoi(idStr) return err == nil }, nil) - settingsForm.AddInputField("Tracker", ui.HLClient.pref.Tracker, 0, nil, nil) - settingsForm.AddCheckbox("Enable Terminal Bell", ui.HLClient.pref.EnableBell, nil) + settingsForm.AddInputField("Tracker", ui.HLClient.Pref.Tracker, 0, nil, nil) + settingsForm.AddCheckbox("Enable Terminal Bell", ui.HLClient.Pref.EnableBell, nil) settingsForm.AddButton("Save", func() { usernameInput := settingsForm.GetFormItem(0).(*tview.InputField).GetText() if len(usernameInput) == 0 { usernameInput = "unnamed" } - ui.HLClient.pref.Username = usernameInput + ui.HLClient.Pref.Username = usernameInput iconStr = settingsForm.GetFormItem(1).(*tview.InputField).GetText() - ui.HLClient.pref.IconID, _ = strconv.Atoi(iconStr) - ui.HLClient.pref.Tracker = settingsForm.GetFormItem(2).(*tview.InputField).GetText() - ui.HLClient.pref.EnableBell = settingsForm.GetFormItem(3).(*tview.Checkbox).IsChecked() + ui.HLClient.Pref.IconID, _ = strconv.Atoi(iconStr) + ui.HLClient.Pref.Tracker = settingsForm.GetFormItem(2).(*tview.InputField).GetText() + ui.HLClient.Pref.EnableBell = settingsForm.GetFormItem(3).(*tview.Checkbox).IsChecked() - out, err := yaml.Marshal(&ui.HLClient.pref) + out, err := yaml.Marshal(&ui.HLClient.Pref) if err != nil { // TODO: handle err } @@ -194,47 +193,25 @@ func (ui *UI) joinServer(addr, login, password string) error { if len(strings.Split(addr, ":")) == 1 { addr += ":5500" } - if err := ui.HLClient.JoinServer(addr, login, password); err != nil { + if err := ui.HLClient.Connect(addr, login, password); err != nil { return fmt.Errorf("Error joining server: %v\n", err) } go func() { - // Create a new scanner for parsing incoming bytes into transaction tokens - scanner := bufio.NewScanner(ui.HLClient.Connection) - scanner.Split(transactionScanner) - - // Scan for new transactions and handle them as they come in. - for scanner.Scan() { - // Make a new []byte slice and copy the scanner bytes to it. This is critical to avoid a data race as the - // scanner re-uses the buffer for subsequent scans. - buf := make([]byte, len(scanner.Bytes())) - copy(buf, scanner.Bytes()) - - var t Transaction - _, err := t.Write(buf) - if err != nil { - break - } - if err := ui.HLClient.HandleTransaction(&t); err != nil { - ui.HLClient.Logger.Errorw("Error handling transaction", "err", err) - } + if err := ui.HLClient.HandleTransactions(); err != nil { + ui.Pages.SwitchToPage("home") } - if scanner.Err() == nil { - loginErrModal := tview.NewModal(). - AddButtons([]string{"Ok"}). - SetText("The server connection has closed."). - SetDoneFunc(func(buttonIndex int, buttonLabel string) { - ui.Pages.SwitchToPage("home") - }) - loginErrModal.Box.SetTitle("Server Connection Error") - - ui.Pages.AddPage("loginErr", loginErrModal, false, true) - ui.App.Draw() - return - } - ui.Pages.SwitchToPage("home") + loginErrModal := tview.NewModal(). + AddButtons([]string{"Ok"}). + SetText("The server connection has closed."). + SetDoneFunc(func(buttonIndex int, buttonLabel string) { + ui.Pages.SwitchToPage("home") + }) + loginErrModal.Box.SetTitle("Server Connection Error") + ui.Pages.AddPage("loginErr", loginErrModal, false, true) + ui.App.Draw() }() return nil @@ -253,8 +230,8 @@ func (ui *UI) renderJoinServerForm(name, server, login, password, backPage strin ui.HLClient.Logger.Infow("saving bookmark") // TODO: Implement bookmark saving - ui.HLClient.pref.AddBookmark(joinServerForm.GetFormItem(0).(*tview.InputField).GetText(), joinServerForm.GetFormItem(0).(*tview.InputField).GetText(), joinServerForm.GetFormItem(1).(*tview.InputField).GetText(), joinServerForm.GetFormItem(2).(*tview.InputField).GetText()) - out, err := yaml.Marshal(ui.HLClient.pref) + ui.HLClient.Pref.AddBookmark(joinServerForm.GetFormItem(0).(*tview.InputField).GetText(), joinServerForm.GetFormItem(0).(*tview.InputField).GetText(), joinServerForm.GetFormItem(1).(*tview.InputField).GetText(), joinServerForm.GetFormItem(2).(*tview.InputField).GetText()) + out, err := yaml.Marshal(ui.HLClient.Pref) if err != nil { panic(err) } @@ -263,7 +240,7 @@ func (ui *UI) renderJoinServerForm(name, server, login, password, backPage strin if err != nil { panic(err) } - // pref := ui.HLClient.pref + // Pref := ui.HLClient.Pref }). AddButton("Cancel", func() { ui.Pages.SwitchToPage(backPage) @@ -360,14 +337,14 @@ func (ui *UI) renderServerUI() *tview.Flex { // List files if event.Key() == tcell.KeyCtrlF { - if err := ui.HLClient.Send(*NewTransaction(tranGetFileNameList, nil)); err != nil { + if err := ui.HLClient.Send(*NewTransaction(TranGetFileNameList, nil)); err != nil { ui.HLClient.Logger.Errorw("err", "err", err) } } // Show News if event.Key() == tcell.KeyCtrlN { - if err := ui.HLClient.Send(*NewTransaction(tranGetMsgs, nil)); err != nil { + if err := ui.HLClient.Send(*NewTransaction(TranGetMsgs, nil)); err != nil { ui.HLClient.Logger.Errorw("err", "err", err) } } @@ -399,8 +376,8 @@ func (ui *UI) renderServerUI() *tview.Flex { return event } err := ui.HLClient.Send( - *NewTransaction(tranOldPostNews, nil, - NewField(fieldData, []byte(newsText)), + *NewTransaction(TranOldPostNews, nil, + NewField(FieldData, []byte(newsText)), ), ) if err != nil { diff --git a/hotline/user.go b/hotline/user.go index f6e4592..a86aeba 100644 --- a/hotline/user.go +++ b/hotline/user.go @@ -12,7 +12,7 @@ const ( userFLagRefusePChat = 3 // User refuses private chat ) -// fieldOptions flags are sent from v1.5+ clients as part of tranAgreed +// FieldOptions flags are sent from v1.5+ clients as part of TranAgreed const ( refusePM = 0 // User has "Refuse private messages" pref set refuseChat = 1 // User has "Refuse private chat" pref set