func PacketToBytes(pkt ResponsePacket) ([]byte, error) { now := time.Now().UnixNano() marker := pkt.Marker() echotime, recvtime, stmptime := pkt.EchoTime() if echotime { if recvtime+30*int64(time.Second) < now { echotime = false } else { marker += 0x04 } } w := xio.NewPacketWriter(nil) if err := w.SetOffset(6); err != nil { return nil, errors.New("packet.skip header") } if err := w.Write8(marker); err != nil { return nil, errors.New("packet.write marker") } const div = int64(time.Millisecond) if err := w.Write16(uint16(now / div)); err != nil { return nil, errors.New("packet.write time.now") } if echotime { if err := w.Write16(stmptime + uint16((now-recvtime)/div)); err != nil { return nil, errors.New("packet.write time.ping") } } for _, rsp := range pkt.Messages() { if err := w.Write8(rsp.Code()); err != nil { return nil, errors.New("message.write code") } pos := w.Offset() if err := w.Skip(2); err != nil { return nil, errors.New("message.skip size") } if err := rsp.WriteTo(w); err != nil { return nil, errors.New("message.write content") } beg, end := pos+2, w.Offset() if err := w.SetOffset(pos); err != nil { return nil, errors.New("message.skip back") } if end < beg || end > beg+0xffff { return nil, errors.New("message.bad content length") } else if err := w.Write16(uint16(end - beg)); err != nil { return nil, errors.New("message.write size") } if err := w.SetOffset(end); err != nil { return nil, errors.New("message.skip to end") } } return w.Bytes(), nil }
func newAmfBytesWriter(name string) (*amf0.Writer, error) { w := amf0.NewWriter(xio.NewPacketWriter(nil)) if err := w.Write8(0x0f); err != nil { return nil, errors.New("message.amf.write code") } if err := w.Write8(0); err != nil { return nil, errors.New("message.amf.write useless1") } if err := w.Write32(0); err != nil { return nil, errors.New("message.amf.write useless2") } if err := w.WriteString(name); err != nil { return nil, errors.New("message.amf.write name") } return w, nil }
func (h *connHandler) newSetBufferTime(sid uint32) error { w := xio.NewPacketWriter(nil) if err := w.Write8(0x04); err != nil { return err } if err := w.Write32(0); err != nil { return err } if err := w.Write16(0); err != nil { return err } if err := w.Write32(sid); err != nil { return err } h.fw.AddFragments(true, split(w.Bytes())...) return nil }
func EncodePacket(engine AESEngine, yid uint32, data []byte) ([]byte, error) { if len(data) < 6 { return nil, errors.New("packet.too small") } w := xio.NewPacketWriter(data) if n := (w.Len() - 4) % AESBlockSize; n != 0 { if err := w.WriteBytes(paddings[n]); err != nil { return nil, err } } sum := checksum(w.Bytes()[6:]) if err := w.SetOffset(4); err != nil { return nil, err } if err := w.Write8(uint8(sum >> 8)); err != nil { return nil, err } if err := w.Write8(uint8(sum)); err != nil { return nil, err } data = w.Bytes() if err := engine.Encode(data[4:]); err != nil { return nil, err } r := xio.NewPacketReader(data) if err := r.SetOffset(4); err != nil { return nil, err } for i := 0; i < 2; i++ { if v, err := r.Read32(); err != nil { return nil, err } else { yid ^= v } } w.SetBytes(data) if err := w.SetOffset(0); err != nil { return nil, err } if err := w.Write32(yid); err != nil { return nil, err } return w.Bytes(), nil }
func newAmfMessageWriter(name string, callback float64) (*amf0.Writer, error) { w := amf0.NewWriter(xio.NewPacketWriter(nil)) if err := w.Write8(0x14); err != nil { return nil, errors.New("message.amf.write code") } if err := w.Write32(0); err != nil { return nil, errors.New("message.amf.write useless") } if err := w.WriteString(name); err != nil { return nil, errors.New("message.amf.write name") } if err := w.WriteNumber(callback); err != nil { return nil, errors.New("message.amf.write callback") } if err := w.WriteNull(); err != nil { return nil, errors.New("message.amf.write null") } return w, nil }
func (h *streamHandler) newPlayBoundResponse(bound uint32) error { w := xio.NewPacketWriter(nil) if err := w.Write8(0x04); err != nil { return err } if err := w.Write32(0); err != nil { return err } if err := w.Write16(0x22); err != nil { return err } if err := w.Write32(bound); err != nil { return err } if err := w.Write32(1); err != nil { return err } h.fw.AddFragments(true, split(w.Bytes())...) return nil }
func (h *connHandler) newKeepAliveResponse(keepAliveServer, keepAlivePeer uint32) error { w := xio.NewPacketWriter(nil) if err := w.Write8(0x04); err != nil { return err } if err := w.Write32(0); err != nil { return err } if err := w.Write16(0x29); err != nil { return err } if err := w.Write32(keepAliveServer); err != nil { return err } if err := w.Write32(keepAlivePeer); err != nil { return err } h.fw.AddFragments(true, split(w.Bytes())...) return nil }