X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/blobdiff_plain/c6a3fa2cdbf7eb78964a5df7622482cdd8782d74..5954ccad9c87063231f3a8bb3e5d01675a9865ca:/hotline/client_conn.go diff --git a/hotline/client_conn.go b/hotline/client_conn.go index 6a27977..e21d8b1 100644 --- a/hotline/client_conn.go +++ b/hotline/client_conn.go @@ -3,9 +3,9 @@ package hotline import ( "encoding/binary" "fmt" - "go.uber.org/zap" "golang.org/x/crypto/bcrypt" "io" + "log/slog" "math/big" "sort" "strings" @@ -31,21 +31,20 @@ type ClientConn struct { Connection io.ReadWriteCloser RemoteAddr string ID *[]byte - Icon *[]byte - Flags *[]byte + Icon []byte + Flags []byte UserName []byte Account *Account IdleTime int Server *Server - Version *[]byte + Version []byte Idle bool AutoReply []byte transfersMU sync.Mutex transfers map[int]map[[4]byte]*FileTransfer - Agreed bool - logger *zap.SugaredLogger + logger *slog.Logger } func (cc *ClientConn) sendAll(t int, fields ...Field) { @@ -54,15 +53,15 @@ func (cc *ClientConn) sendAll(t int, fields ...Field) { } } -func (cc *ClientConn) handleTransaction(transaction *Transaction) error { +func (cc *ClientConn) handleTransaction(transaction Transaction) error { requestNum := binary.BigEndian.Uint16(transaction.Type) if handler, ok := TransactionHandlers[requestNum]; ok { for _, reqField := range handler.RequiredFields { field := transaction.GetField(reqField.ID) // Validate that required field is present - if field.ID == nil { - cc.logger.Errorw( + if field.ID == [2]byte{0, 0} { + cc.logger.Error( "Missing required field", "RequestType", handler.Name, "FieldID", reqField.ID, ) @@ -70,7 +69,7 @@ func (cc *ClientConn) handleTransaction(transaction *Transaction) error { } if len(field.Data) < reqField.minLen { - cc.logger.Infow( + cc.logger.Info( "Field does not meet minLen", "RequestType", handler.Name, "FieldID", reqField.ID, ) @@ -78,9 +77,9 @@ func (cc *ClientConn) handleTransaction(transaction *Transaction) error { } } - cc.logger.Infow("Received Transaction", "RequestType", handler.Name) + cc.logger.Debug("Received Transaction", "RequestType", handler.Name) - transactions, err := handler.Handler(cc, transaction) + transactions, err := handler.Handler(cc, &transaction) if err != nil { return err } @@ -88,31 +87,31 @@ func (cc *ClientConn) handleTransaction(transaction *Transaction) error { cc.Server.outbox <- t } } else { - cc.logger.Errorw( + cc.logger.Error( "Unimplemented transaction type received", "RequestID", requestNum) } cc.Server.mux.Lock() defer cc.Server.mux.Unlock() - if requestNum != tranKeepAlive { + if requestNum != TranKeepAlive { // reset the user idle timer cc.IdleTime = 0 // if user was previously idle, mark as not idle and notify other connected clients that // the user is no longer away if cc.Idle { - flagBitmap := big.NewInt(int64(binary.BigEndian.Uint16(*cc.Flags))) - flagBitmap.SetBit(flagBitmap, userFlagAway, 0) - binary.BigEndian.PutUint16(*cc.Flags, uint16(flagBitmap.Int64())) + flagBitmap := big.NewInt(int64(binary.BigEndian.Uint16(cc.Flags))) + flagBitmap.SetBit(flagBitmap, UserFlagAway, 0) + binary.BigEndian.PutUint16(cc.Flags, uint16(flagBitmap.Int64())) 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), ) } } @@ -135,9 +134,7 @@ func (cc *ClientConn) uint16ID() uint16 { // Authorize checks if the user account has the specified permission func (cc *ClientConn) Authorize(access int) bool { - i := big.NewInt(int64(binary.BigEndian.Uint64(*cc.Account.Access))) - - return i.Bit(63-access) == 1 + return cc.Account.Access.IsSet(access) } // Disconnect notifies other clients that a client has disconnected @@ -147,19 +144,19 @@ 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 } if err := cc.Connection.Close(); err != nil { - cc.Server.Logger.Errorw("error closing client connection", "RemoteAddr", cc.RemoteAddr) + cc.Server.Logger.Error("error closing client connection", "RemoteAddr", cc.RemoteAddr) } } // notifyOthers sends transaction t to other clients connected to the server func (cc *ClientConn) notifyOthers(t Transaction) (trans []Transaction) { for _, c := range sortedClients(cc.Server.Clients) { - if c.ID != cc.ID && c.Agreed { + if c.ID != cc.ID { t.clientID = c.ID trans = append(trans, t) } @@ -169,30 +166,26 @@ func (cc *ClientConn) notifyOthers(t Transaction) (trans []Transaction) { // NewReply returns a reply Transaction with fields for the ClientConn func (cc *ClientConn) NewReply(t *Transaction, fields ...Field) Transaction { - reply := Transaction{ - Flags: 0x00, + return Transaction{ IsReply: 0x01, - Type: t.Type, + Type: []byte{0x00, 0x00}, ID: t.ID, clientID: cc.ID, ErrorCode: []byte{0, 0, 0, 0}, Fields: fields, } - - return reply } // NewErrReply returns an error reply Transaction with errMsg func (cc *ClientConn) NewErrReply(t *Transaction, errMsg string) Transaction { return Transaction{ clientID: cc.ID, - Flags: 0x00, IsReply: 0x01, Type: []byte{0, 0}, ID: t.ID, ErrorCode: []byte{0, 0, 0, 1}, Fields: []Field{ - NewField(fieldError, []byte(errMsg)), + NewField(FieldError, []byte(errMsg)), }, } } @@ -257,5 +250,5 @@ func (cc *ClientConn) String() string { "None.\n", ) - return strings.Replace(template, "\n", "\r", -1) + return strings.ReplaceAll(template, "\n", "\r") }