From 49c704bc679e5dbc24d1f7e3bed38e9016e9d50b Mon Sep 17 00:00:00 2001 From: Vasiliy Tolstov Date: Tue, 13 Jun 2017 16:20:35 +0300 Subject: [PATCH] complete proxy support Signed-off-by: Vasiliy Tolstov --- client.go | 138 ++++++++++++++++++++++-------------------- encoding.go | 41 +++++++++---- example/proxy/main.go | 73 ++++++++++------------ handlers.go | 12 +++- image.go | 17 +++--- pixel_format.go | 42 ++++++++++--- server.go | 129 ++++++++++++++++++--------------------- 7 files changed, 244 insertions(+), 208 deletions(-) diff --git a/client.go b/client.go index 8897c91..e9af07b 100644 --- a/client.go +++ b/client.go @@ -59,7 +59,6 @@ func (c *ClientConn) SetProtoVersion(pv string) { func (c *ClientConn) SetEncodings(encs []EncodingType) error { msg := &SetEncodings{ - MsgType: SetEncodingsMsgType, EncNum: uint16(len(encs)), Encodings: encs, } @@ -201,17 +200,16 @@ const ( // SetPixelFormat holds the wire format message. type SetPixelFormat struct { - MsgType ClientMessageType - _ [3]byte // padding - PF PixelFormat // pixel-format + _ [3]byte // padding + PF PixelFormat // pixel-format } -func (msg *SetPixelFormat) Type() ClientMessageType { +func (*SetPixelFormat) Type() ClientMessageType { return SetPixelFormatMsgType } func (msg *SetPixelFormat) Write(c Conn) error { - if err := binary.Write(c, binary.BigEndian, msg.MsgType); err != nil { + if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { return err } @@ -225,50 +223,51 @@ func (msg *SetPixelFormat) Write(c Conn) error { c.SetColorMap(&ColorMap{}) } - return nil + return c.Flush() } -func (msg *SetPixelFormat) Read(c Conn) error { - return binary.Read(c, binary.BigEndian, &msg) +func (*SetPixelFormat) Read(c Conn) (ClientMessage, error) { + msg := SetPixelFormat{} + if err := binary.Read(c, binary.BigEndian, &msg); err != nil { + return nil, err + } + return &msg, nil } // SetEncodings holds the wire format message, sans encoding-type field. type SetEncodings struct { - MsgType ClientMessageType _ [1]byte // padding EncNum uint16 // number-of-encodings Encodings []EncodingType } -func (msg *SetEncodings) Type() ClientMessageType { +func (*SetEncodings) Type() ClientMessageType { return SetEncodingsMsgType } -func (msg *SetEncodings) Read(c Conn) error { - if err := binary.Read(c, binary.BigEndian, &msg.MsgType); err != nil { - return err - } +func (*SetEncodings) Read(c Conn) (ClientMessage, error) { + msg := SetEncodings{} var pad [1]byte if err := binary.Read(c, binary.BigEndian, &pad); err != nil { - return err + return nil, err } if err := binary.Read(c, binary.BigEndian, &msg.EncNum); err != nil { - return err + return nil, err } var enc EncodingType for i := uint16(0); i < msg.EncNum; i++ { if err := binary.Read(c, binary.BigEndian, &enc); err != nil { - return err + return nil, err } msg.Encodings = append(msg.Encodings, enc) } c.SetEncodings(msg.Encodings) - return nil + return &msg, nil } func (msg *SetEncodings) Write(c Conn) error { - if err := binary.Write(c, binary.BigEndian, msg.MsgType); err != nil { + if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { return err } @@ -280,11 +279,9 @@ func (msg *SetEncodings) Write(c Conn) error { if uint16(len(msg.Encodings)) > msg.EncNum { msg.EncNum = uint16(len(msg.Encodings)) } - if err := binary.Write(c, binary.BigEndian, msg.EncNum); err != nil { return err } - for _, enc := range msg.Encodings { if err := binary.Write(c, binary.BigEndian, enc); err != nil { return err @@ -295,21 +292,27 @@ func (msg *SetEncodings) Write(c Conn) error { // FramebufferUpdateRequest holds the wire format message. type FramebufferUpdateRequest struct { - MsgType ClientMessageType Inc uint8 // incremental X, Y uint16 // x-, y-position Width, Height uint16 // width, height } -func (msg *FramebufferUpdateRequest) Type() ClientMessageType { +func (*FramebufferUpdateRequest) Type() ClientMessageType { return FramebufferUpdateRequestMsgType } -func (msg *FramebufferUpdateRequest) Read(c Conn) error { - return binary.Read(c, binary.BigEndian, &msg) +func (*FramebufferUpdateRequest) Read(c Conn) (ClientMessage, error) { + msg := FramebufferUpdateRequest{} + if err := binary.Read(c, binary.BigEndian, &msg); err != nil { + return nil, err + } + return &msg, nil } func (msg *FramebufferUpdateRequest) Write(c Conn) error { + if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { + return err + } if err := binary.Write(c, binary.BigEndian, msg); err != nil { return err } @@ -318,21 +321,27 @@ func (msg *FramebufferUpdateRequest) Write(c Conn) error { // KeyEvent holds the wire format message. type KeyEvent struct { - MsgType ClientMessageType // message-type - Down uint8 // down-flag - _ [2]byte // padding - Key Key // key + Down uint8 // down-flag + _ [2]byte // padding + Key Key // key } -func (msg *KeyEvent) Type() ClientMessageType { +func (*KeyEvent) Type() ClientMessageType { return KeyEventMsgType } -func (msg *KeyEvent) Read(c Conn) error { - return binary.Read(c, binary.BigEndian, &msg) +func (*KeyEvent) Read(c Conn) (ClientMessage, error) { + msg := KeyEvent{} + if err := binary.Read(c, binary.BigEndian, &msg); err != nil { + return nil, err + } + return &msg, nil } func (msg *KeyEvent) Write(c Conn) error { + if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { + return err + } if err := binary.Write(c, binary.BigEndian, msg); err != nil { return err } @@ -341,20 +350,26 @@ func (msg *KeyEvent) Write(c Conn) error { // PointerEventMessage holds the wire format message. type PointerEvent struct { - MsgType ClientMessageType // message-type - Mask uint8 // button-mask - X, Y uint16 // x-, y-position + Mask uint8 // button-mask + X, Y uint16 // x-, y-position } -func (msg *PointerEvent) Type() ClientMessageType { +func (*PointerEvent) Type() ClientMessageType { return PointerEventMsgType } -func (msg *PointerEvent) Read(c Conn) error { - return binary.Read(c, binary.BigEndian, &msg) +func (*PointerEvent) Read(c Conn) (ClientMessage, error) { + msg := PointerEvent{} + if err := binary.Read(c, binary.BigEndian, &msg); err != nil { + return nil, err + } + return &msg, nil } func (msg *PointerEvent) Write(c Conn) error { + if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { + return err + } if err := binary.Write(c, binary.BigEndian, msg); err != nil { return err } @@ -363,40 +378,35 @@ func (msg *PointerEvent) Write(c Conn) error { // ClientCutText holds the wire format message, sans the text field. type ClientCutText struct { - MsgType ClientMessageType // message-type - _ [3]byte // padding - Length uint32 // length - Text []byte + _ [3]byte // padding + Length uint32 // length + Text []byte } -func (msg *ClientCutText) Type() ClientMessageType { +func (*ClientCutText) Type() ClientMessageType { return ClientCutTextMsgType } -func (msg *ClientCutText) Read(c Conn) error { - if err := binary.Read(c, binary.BigEndian, &msg.MsgType); err != nil { - return err - } - +func (*ClientCutText) Read(c Conn) (ClientMessage, error) { + msg := ClientCutText{} var pad [3]byte if err := binary.Read(c, binary.BigEndian, &pad); err != nil { - return err + return nil, err } if err := binary.Read(c, binary.BigEndian, &msg.Length); err != nil { - return err + return nil, err } - text := make([]uint8, msg.Length) - if err := binary.Read(c, binary.BigEndian, &text); err != nil { - return err + msg.Text = make([]byte, msg.Length) + if err := binary.Read(c, binary.BigEndian, &msg.Text); err != nil { + return nil, err } - msg.Text = text - return nil + return &msg, nil } func (msg *ClientCutText) Write(c Conn) error { - if err := binary.Write(c, binary.BigEndian, msg.MsgType); err != nil { + if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { return err } @@ -457,25 +467,21 @@ func (c *ClientConn) Handle() error { if err = binary.Read(c, binary.BigEndian, &messageType); err != nil { return err } - if err := c.UnreadByte(); err != nil { - return err - } + msg, ok := serverMessages[messageType] if !ok { return fmt.Errorf("unknown message-type: %v", messageType) } - if err = msg.Read(c); err != nil { + + parsedMsg, err := msg.Read(c) + if err != nil { return err } - if c.cfg.ServerMessageCh == nil { - continue - } - c.cfg.ServerMessageCh <- msg + c.cfg.ServerMessageCh <- parsedMsg } } }() wg.Wait() - fmt.Printf("tttt\n") return err } diff --git a/encoding.go b/encoding.go index 020cc74..9df8d3c 100644 --- a/encoding.go +++ b/encoding.go @@ -45,19 +45,31 @@ type RawEncoding struct { } func (enc *RawEncoding) Write(c Conn, rect *Rectangle) error { - /* - for _, cl := range enc.Colors { - bytes, err := cl.Marshal() - if err != nil { - return err - } - if err := binary.Write(c, binary.BigEndian, bytes); err != nil { - return err - } + buf := bytes.NewBuffer(nil) + defer buf.Reset() + n := 0 + for _, c := range enc.Colors { + bytes, err := c.Marshal() + if err != nil { + return err } - */ - return nil + n += len(bytes) + if err := binary.Write(buf, binary.BigEndian, bytes); err != nil { + return err + } + + /* + if _, err := buf.Write(bytes); err != nil { + return err + } + */ + } + fmt.Printf("w %d\n", n) + //return binary.Write(c, binary.BigEndian, buf.Bytes()) + fmt.Printf("w %v\n", buf.Bytes()) + _, err := c.Write(buf.Bytes()) + return err } // Read implements the Encoding interface. @@ -68,12 +80,13 @@ func (enc *RawEncoding) Read(c Conn, rect *Rectangle) error { bytesPerPixel := int(pf.BPP / 8) n := rect.Area() * bytesPerPixel data := make([]byte, n) - fmt.Printf("eeee\n") + fmt.Printf("r %d\n", n) if err := binary.Read(c, binary.BigEndian, &data); err != nil { return err } buf.Write(data) defer buf.Reset() + fmt.Printf("r %v\n", buf.Bytes()) colors := make([]Color, rect.Area()) for y := uint16(0); y < rect.Height; y++ { for x := uint16(0); x < rect.Width; x++ { @@ -94,6 +107,8 @@ func (*RawEncoding) Type() EncodingType { return EncRaw } // DesktopSizePseudoEncoding represents a desktop size message from the server. type DesktopSizePseudoEncoding struct{} +func (*DesktopSizePseudoEncoding) Type() EncodingType { return EncDesktopSizePseudo } + // Read implements the Encoding interface. func (*DesktopSizePseudoEncoding) Read(c Conn, rect *Rectangle) error { c.SetWidth(rect.Width) @@ -102,6 +117,6 @@ func (*DesktopSizePseudoEncoding) Read(c Conn, rect *Rectangle) error { return nil } -func (enc *DesktopSizePseudoEncoding) Write(c *ServerConn, rect *Rectangle) error { +func (enc *DesktopSizePseudoEncoding) Write(c Conn, rect *Rectangle) error { return nil } diff --git a/example/proxy/main.go b/example/proxy/main.go index 3388d68..12ee014 100644 --- a/example/proxy/main.go +++ b/example/proxy/main.go @@ -14,8 +14,8 @@ func main() { log.Fatalf("Error listen. %v", err) } - schServer := make(chan vnc.ClientMessage) - schClient := make(chan vnc.ServerMessage) + schClient := make(chan vnc.ClientMessage) + schServer := make(chan vnc.ServerMessage) scfg := &vnc.ServerConfig{ Width: 800, @@ -26,15 +26,13 @@ func main() { ClientInitHandler: vnc.ServerClientInitHandler, ServerInitHandler: vnc.ServerServerInitHandler, Encodings: []vnc.Encoding{&vnc.RawEncoding{}}, - PixelFormat: vnc.PixelFormat24bit, - ClientMessageCh: schServer, - ServerMessageCh: schClient, + PixelFormat: vnc.PixelFormat32bit, + ClientMessageCh: schClient, + ServerMessageCh: schServer, ClientMessages: vnc.DefaultClientMessages, DesktopName: []byte("vnc proxy"), } - go vnc.Serve(context.Background(), ln, scfg) - - c, err := net.Dial("tcp", "127.0.0.1:5944") + c, err := net.Dial("tcp", "127.0.0.1:5995") if err != nil { log.Fatalf("Error dial. %v", err) } @@ -47,7 +45,7 @@ func main() { SecurityHandlers: []vnc.SecurityHandler{&vnc.ClientAuthNone{}}, ClientInitHandler: vnc.ClientClientInitHandler, ServerInitHandler: vnc.ClientServerInitHandler, - PixelFormat: vnc.PixelFormat24bit, + PixelFormat: vnc.PixelFormat32bit, ClientMessageCh: cchClient, ServerMessageCh: cchServer, ServerMessages: vnc.DefaultServerMessages, @@ -58,54 +56,49 @@ func main() { if err != nil { log.Fatalf("Error dial. %v", err) } + + scfg.Width = cc.Width() + scfg.Height = cc.Height() + scfg.PixelFormat = cc.PixelFormat() + go vnc.Serve(context.Background(), ln, scfg) + defer cc.Close() go cc.Handle() for { select { - case msg := <-cchClient: - switch msg.Type() { - default: - log.Printf("00 Received message type:%v msg:%v\n", msg.Type(), msg) - } case msg := <-cchServer: switch msg.Type() { default: - log.Printf("01 Received message type:%v msg:%v\n", msg.Type(), msg) + schServer <- msg } case msg := <-schClient: - switch msg.Type() { - default: - log.Printf("10 Received message type:%v msg:%v\n", msg.Type(), msg) - } - case msg := <-schServer: - log.Printf("11 Received message type:%v msg:%v\n", msg.Type(), msg) switch msg.Type() { case vnc.SetEncodingsMsgType: + msg0 := &vnc.SetPixelFormat{ + PF: *vnc.PixelFormat32bit, + } + cchClient <- msg0 + encRaw := &vnc.RawEncoding{} msg1 := &vnc.SetEncodings{ - MsgType: vnc.SetEncodingsMsgType, - EncNum: 1, Encodings: []vnc.EncodingType{encRaw.Type()}, } - if err := msg1.Write(cc); err != nil { - log.Fatalf("err %v\n", err) - } - msg2 := &vnc.FramebufferUpdateRequest{ - MsgType: vnc.FramebufferUpdateRequestMsgType, - Inc: 0, - X: 0, - Y: 0, - Width: cc.Width(), - Height: cc.Height(), - } - if err := msg2.Write(cc); err != nil { - log.Fatalf("err %v\n", err) - } + cchClient <- msg1 + /* + msg2 := &vnc.FramebufferUpdateRequest{ + Inc: 0, + X: 0, + Y: 0, + Width: cc.Width(), + Height: cc.Height(), + } + cchClient <- msg2 + */ + case vnc.SetPixelFormatMsgType: + cchClient <- msg default: - if err := msg.Write(cc); err != nil { - log.Fatalf("err %v\n", err) - } + cchClient <- msg } } } diff --git a/handlers.go b/handlers.go index 8cade5e..8c6a58f 100644 --- a/handlers.go +++ b/handlers.go @@ -8,14 +8,14 @@ import ( // ClientMessage is the interface type ClientMessage interface { Type() ClientMessageType - Read(Conn) error + Read(Conn) (ClientMessage, error) Write(Conn) error } // ServerMessage is the interface type ServerMessage interface { Type() ServerMessageType - Read(Conn) error + Read(Conn) (ServerMessage, error) Write(Conn) error } @@ -262,7 +262,13 @@ func ServerServerInitHandler(cfg *ServerConfig, c Conn) error { } func ClientClientInitHandler(cfg *ClientConfig, c Conn) error { - if err := binary.Write(c, binary.BigEndian, cfg.Exclusive); err != nil { + var shared uint8 + if cfg.Exclusive { + shared = 0 + } else { + shared = 1 + } + if err := binary.Write(c, binary.BigEndian, shared); err != nil { return err } return c.Flush() diff --git a/image.go b/image.go index 24d4da7..f40dac3 100644 --- a/image.go +++ b/image.go @@ -114,19 +114,21 @@ func colorsToImage(x, y, width, height uint16, colors []Color) *image.RGBA64 { // Marshal implements the Marshaler interface. func (r *Rectangle) Write(c Conn) error { - if err := binary.Write(c, binary.BigEndian, r.X); err != nil { + var err error + fmt.Printf("w rect %#+v\n", r) + if err = binary.Write(c, binary.BigEndian, r.X); err != nil { return err } - if err := binary.Write(c, binary.BigEndian, r.Y); err != nil { + if err = binary.Write(c, binary.BigEndian, r.Y); err != nil { return err } - if err := binary.Write(c, binary.BigEndian, r.Width); err != nil { + if err = binary.Write(c, binary.BigEndian, r.Width); err != nil { return err } - if err := binary.Write(c, binary.BigEndian, r.Height); err != nil { + if err = binary.Write(c, binary.BigEndian, r.Height); err != nil { return err } - if err := binary.Write(c, binary.BigEndian, r.EncType); err != nil { + if err = binary.Write(c, binary.BigEndian, r.EncType); err != nil { return err } @@ -137,8 +139,8 @@ func (r *Rectangle) Write(c Conn) error { } func (r *Rectangle) Read(c Conn) error { - fmt.Printf("qqq\n") var err error + if err = binary.Read(c, binary.BigEndian, &r.X); err != nil { return err } @@ -154,12 +156,11 @@ func (r *Rectangle) Read(c Conn) error { if err = binary.Read(c, binary.BigEndian, &r.EncType); err != nil { return err } - fmt.Printf("rrrr %#+v\n", r) switch r.EncType { case EncRaw: r.Enc = &RawEncoding{} } - + fmt.Printf("r rect %#+v\n", r) return r.Enc.Read(c, r) } diff --git a/pixel_format.go b/pixel_format.go index 9f11084..b0d23fb 100644 --- a/pixel_format.go +++ b/pixel_format.go @@ -7,13 +7,11 @@ import ( "encoding/binary" "fmt" "io" - "math" ) var ( PixelFormat8bit *PixelFormat = NewPixelFormat(8) PixelFormat16bit *PixelFormat = NewPixelFormat(16) - PixelFormat24bit *PixelFormat = NewPixelFormat(24) PixelFormat32bit *PixelFormat = NewPixelFormat(32) ) @@ -28,44 +26,70 @@ type PixelFormat struct { _ [3]byte // padding } +/* +qemu: + + + + + + +*/ + +/* + + + + + + +*/ const pixelFormatLen = 16 // NewPixelFormat returns a populated PixelFormat structure. func NewPixelFormat(bpp uint8) *PixelFormat { bigEndian := uint8(0) - rgbMax := uint16(math.Exp2(float64(bpp))) - 1 + // rgbMax := uint16(math.Exp2(float64(bpp))) - 1 + rMax := uint16(255) + gMax := uint16(255) + bMax := uint16(255) var ( tc = uint8(1) rs, gs, bs uint8 + depth uint8 ) switch bpp { case 8: tc = 0 + depth = 8 rs, gs, bs = 0, 0, 0 case 16: + depth = 16 rs, gs, bs = 0, 4, 8 case 32: - rs, gs, bs = 0, 8, 16 + depth = 24 + // rs, gs, bs = 0, 8, 16 + rs, gs, bs = 16, 8, 0 } - return &PixelFormat{bpp, bpp, bigEndian, tc, rgbMax, rgbMax, rgbMax, rs, gs, bs, [3]byte{}} + return &PixelFormat{bpp, depth, bigEndian, tc, rMax, gMax, bMax, rs, gs, bs, [3]byte{}} } // Marshal implements the Marshaler interface. func (pf *PixelFormat) Marshal() ([]byte, error) { // Validation checks. switch pf.BPP { - case 8, 16, 24, 32: + case 8, 16, 32: default: - return nil, fmt.Errorf("Invalid BPP value %v; must be 8, 16, 24 or 32.", pf.BPP) + return nil, fmt.Errorf("Invalid BPP value %v; must be 8, 16, or 32.", pf.BPP) } if pf.Depth < pf.BPP { return nil, fmt.Errorf("Invalid Depth value %v; cannot be < BPP", pf.Depth) } switch pf.Depth { - case 8, 16, 24, 32: + case 8, 16, 32: default: - return nil, fmt.Errorf("Invalid Depth value %v; must be 8, 16, 24 or 32.", pf.Depth) + return nil, fmt.Errorf("Invalid Depth value %v; must be 8, 16, or 32.", pf.Depth) } // Create the slice of bytes diff --git a/server.go b/server.go index fc48496..5f868e9 100644 --- a/server.go +++ b/server.go @@ -137,43 +137,43 @@ const ( // FramebufferUpdate holds a FramebufferUpdate wire format message. type FramebufferUpdate struct { - MsgType ServerMessageType - _ [1]byte // pad - NumRect uint16 // number-of-rectangles - Rects []Rectangle // rectangles + _ [1]byte // pad + NumRect uint16 // number-of-rectangles + Rects []*Rectangle // rectangles } -func (msg *FramebufferUpdate) Type() ServerMessageType { +func (*FramebufferUpdate) Type() ServerMessageType { return FramebufferUpdateMsgType } -func (msg *FramebufferUpdate) Read(c Conn) error { - if err := binary.Read(c, binary.BigEndian, msg.MsgType); err != nil { - return err - } - fmt.Printf("qqqqq\n") +func (*FramebufferUpdate) Read(c Conn) (ServerMessage, error) { + msg := FramebufferUpdate{} var pad [1]byte if err := binary.Read(c, binary.BigEndian, &pad); err != nil { - return err + return nil, err } - if err := binary.Read(c, binary.BigEndian, msg.NumRect); err != nil { - return err + if err := binary.Read(c, binary.BigEndian, &msg.NumRect); err != nil { + return nil, err } - msg.Rects = make([]Rectangle, msg.NumRect) + fmt.Printf("%#+v\n", msg) for i := uint16(0); i < msg.NumRect; i++ { - rect := NewRectangle() + rect := &Rectangle{} if err := rect.Read(c); err != nil { - return err + return nil, err } - msg.Rects = append(msg.Rects, *rect) + msg.Rects = append(msg.Rects, rect) } - - return nil + fmt.Printf("r fb %d %d %v\n", msg.NumRect, uint16(len(msg.Rects)), msg.Rects) + if msg.NumRect != uint16(len(msg.Rects)) { + panic("rects not equal") + } + return &msg, nil } func (msg *FramebufferUpdate) Write(c Conn) error { - if err := binary.Write(c, binary.BigEndian, msg.MsgType); err != nil { + fmt.Printf("w fb %d %d %v\n", msg.NumRect, uint16(len(msg.Rects)), msg.Rects) + if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { return err } var pad [1]byte @@ -341,22 +341,19 @@ func (c *ServerConn) Handle() error { if err := binary.Read(c, binary.BigEndian, &messageType); err != nil { return err } - - if err := c.UnreadByte(); err != nil { - return err - } - + fmt.Printf("srv r %s\n", messageType) msg, ok := clientMessages[messageType] if !ok { return fmt.Errorf("unsupported message-type: %v", messageType) } - - if err := msg.Read(c); err != nil { + parsedMsg, err := msg.Read(c) + fmt.Printf("srv r %#+v\n", parsedMsg) + if err != nil { + fmt.Printf("srv err %s\n", err.Error()) return err } - - c.cfg.ClientMessageCh <- msg + c.cfg.ClientMessageCh <- parsedMsg } } }() @@ -366,40 +363,36 @@ func (c *ServerConn) Handle() error { } type ServerCutText struct { - MsgType ServerMessageType - _ [1]byte - Length uint32 - Text []byte + _ [1]byte + Length uint32 + Text []byte } -func (msg *ServerCutText) Type() ServerMessageType { +func (*ServerCutText) Type() ServerMessageType { return ServerCutTextMsgType } -func (msg *ServerCutText) Read(c Conn) error { - if err := binary.Read(c, binary.BigEndian, msg.MsgType); err != nil { - return err - } +func (*ServerCutText) Read(c Conn) (ServerMessage, error) { + msg := ServerCutText{} + var pad [1]byte if err := binary.Read(c, binary.BigEndian, &pad); err != nil { - return err + return nil, err } - var length uint32 - if err := binary.Read(c, binary.BigEndian, &length); err != nil { - return err + if err := binary.Read(c, binary.BigEndian, &msg.Length); err != nil { + return nil, err } - text := make([]byte, length) - if err := binary.Read(c, binary.BigEndian, &text); err != nil { - return err + msg.Text = make([]byte, msg.Length) + if err := binary.Read(c, binary.BigEndian, &msg.Text); err != nil { + return nil, err } - msg.Text = text - return nil + return &msg, nil } func (msg *ServerCutText) Write(c Conn) error { - if err := binary.Write(c, binary.BigEndian, msg.MsgType); err != nil { + if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { return err } var pad [1]byte @@ -407,6 +400,9 @@ func (msg *ServerCutText) Write(c Conn) error { return err } + if msg.Length < uint32(len(msg.Text)) { + msg.Length = uint32(len(msg.Text)) + } if err := binary.Write(c, binary.BigEndian, msg.Length); err != nil { return err } @@ -417,52 +413,47 @@ func (msg *ServerCutText) Write(c Conn) error { return nil } -type Bell struct { - MsgType ServerMessageType -} +type Bell struct{} -func (msg *Bell) Type() ServerMessageType { +func (*Bell) Type() ServerMessageType { return BellMsgType } -func (msg *Bell) Read(c Conn) error { - return binary.Read(c, binary.BigEndian, msg.MsgType) +func (*Bell) Read(c Conn) (ServerMessage, error) { + return &Bell{}, nil } func (msg *Bell) Write(c Conn) error { - if err := binary.Write(c, binary.BigEndian, msg.MsgType); err != nil { + if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { return err } return c.Flush() } type SetColorMapEntries struct { - MsgType ServerMessageType _ [1]byte FirstColor uint16 ColorsNum uint16 Colors []Color } -func (msg *SetColorMapEntries) Type() ServerMessageType { +func (*SetColorMapEntries) Type() ServerMessageType { return SetColorMapEntriesMsgType } -func (msg *SetColorMapEntries) Read(c Conn) error { - if err := binary.Read(c, binary.BigEndian, msg.MsgType); err != nil { - return err - } +func (*SetColorMapEntries) Read(c Conn) (ServerMessage, error) { + msg := SetColorMapEntries{} var pad [1]byte if err := binary.Read(c, binary.BigEndian, &pad); err != nil { - return err + return nil, err } - if err := binary.Read(c, binary.BigEndian, msg.FirstColor); err != nil { - return err + if err := binary.Read(c, binary.BigEndian, &msg.FirstColor); err != nil { + return nil, err } - if err := binary.Read(c, binary.BigEndian, msg.ColorsNum); err != nil { - return err + if err := binary.Read(c, binary.BigEndian, &msg.ColorsNum); err != nil { + return nil, err } msg.Colors = make([]Color, msg.ColorsNum) @@ -471,16 +462,16 @@ func (msg *SetColorMapEntries) Read(c Conn) error { for i := uint16(0); i < msg.ColorsNum; i++ { color := &msg.Colors[i] if err := binary.Read(c, binary.BigEndian, &color); err != nil { - return err + return nil, err } colorMap[msg.FirstColor+i] = *color } c.SetColorMap(colorMap) - return nil + return &msg, nil } func (msg *SetColorMapEntries) Write(c Conn) error { - if err := binary.Write(c, binary.BigEndian, msg.MsgType); err != nil { + if err := binary.Write(c, binary.BigEndian, msg.Type()); err != nil { return err } var pad [1]byte