From ba704b963d7f52f86c7af2085a781f9536690e5b Mon Sep 17 00:00:00 2001 From: Christopher F Date: Fri, 24 Aug 2018 17:14:58 -0400 Subject: [PATCH] feature: add track decoder --- TODO.txt | 1 - decoder.go | 128 ++++++++++++++++++++++++++++++++++++++++++++++++ decoder_test.go | 17 +++++++ 3 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 decoder.go create mode 100644 decoder_test.go diff --git a/TODO.txt b/TODO.txt index 274bcc7..5db1e1f 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,4 +1,3 @@ - pause state should be reset on a play command - match node balancing against lavalink-client's https://github.com/FredBoat/Lavalink-Client/blob/master/src/main/java/lavalink/client/io/LavalinkLoadBalancer.java#L121-L146 -- track decoder diff --git a/decoder.go b/decoder.go new file mode 100644 index 0000000..fc58795 --- /dev/null +++ b/decoder.go @@ -0,0 +1,128 @@ +package gavalink + +import ( + "bytes" + "encoding/base64" + "encoding/binary" + "io" +) + +const trackInfoVersioned int32 = 1 + +// DecodeString decodes a base64 Lavaplayer string to a TrackInfo +func DecodeString(data string) (*TrackInfo, error) { + b, err := base64.StdEncoding.DecodeString(data) + if err != nil { + return nil, err + } + r := bytes.NewReader(b) + return Decode(r) +} + +// Decode decodes a reader into a TrackInfo +func Decode(r io.Reader) (*TrackInfo, error) { + // https://github.com/serenity-rs/lavalink.rs/blob/master/src/decoder.rs + + var value uint8 + if err := binary.Read(r, binary.LittleEndian, &value); err != nil { + return nil, err + } + + flags := int32(int64(value) & 0xC00000000) + + // irrelevant data? + var ignore [2]byte + if err := binary.Read(r, binary.LittleEndian, &ignore); err != nil { + return nil, err + } + + var version uint8 + if flags&trackInfoVersioned == 0 { + version = 1 + } else { + if err := binary.Read(r, binary.LittleEndian, &version); err != nil { + return nil, err + } + } + + if err := binary.Read(r, binary.LittleEndian, &ignore); err != nil { + return nil, err + } + + title, err := readString(r) + if err != nil { + return nil, err + } + + author, err := readString(r) + if err != nil { + return nil, err + } + + var length uint64 + if err := binary.Read(r, binary.BigEndian, &length); err != nil { + return nil, err + } + + identifier, err := readString(r) + if err != nil { + return nil, err + } + + var stream uint8 + if err := binary.Read(r, binary.LittleEndian, &stream); err != nil { + return nil, err + } + + var hasURL uint8 + if err := binary.Read(r, binary.LittleEndian, &hasURL); err != nil { + return nil, err + } + + var url string + if hasURL == 1 { + url, err = readString(r) + if err != nil { + return nil, err + } + } else { + var size uint8 + if err := binary.Read(r, binary.LittleEndian, &size); err != nil { + return nil, err + } + + ignore := make([]byte, size) + if err := binary.Read(r, binary.LittleEndian, &ignore); err != nil { + return nil, err + } + } + + /*source, err := readString(r) + if err != nil { + return nil, err + }*/ + + track := &TrackInfo{ + Identifier: identifier, + Title: title, + Author: author, + URI: url, + Stream: stream == 1, + Length: int(length), + } + + return track, nil +} + +func readString(r io.Reader) (string, error) { + var size uint16 + if err := binary.Read(r, binary.BigEndian, &size); err != nil { + return "", err + } + buf := make([]byte, size) + if err := binary.Read(r, binary.BigEndian, &buf); err != nil { + return "", err + } + + return string(buf), nil +} diff --git a/decoder_test.go b/decoder_test.go new file mode 100644 index 0000000..789bda1 --- /dev/null +++ b/decoder_test.go @@ -0,0 +1,17 @@ +package gavalink_test + +import ( + "testing" + + "github.com/foxbot/gavalink" +) + +func TestDecoder(t *testing.T) { + data := "QAAAkAIALGxvZmkgaGlwIGhvcCByYWRpbyAtIGJlYXRzIHRvIHJlbGF4L3N0dWR5IHRvAApDaGlsbGVkQ293f/////////8AC2hIVzFvWTI2a3hRAQEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9aEhXMW9ZMjZreFEAB3lvdXR1YmUAAAAAAAAAAA==" + track, err := gavalink.DecodeString(data) + if err != nil { + t.Error(err) + return + } + t.Log(track) +}