Exemple #1
0
        /// <summary>
        /// Decodes a Lavalink track string.
        /// </summary>
        /// <param name="track">Track string to decode.</param>
        /// <returns>Decoded Lavalink track.</returns>
        public static LavalinkTrack DecodeTrack(string track)
        {
            var raw = Convert.FromBase64String(track);

            var msgval = BitConverter.ToInt32(raw, 0);

            msgval = (int)SwapEndianness((uint)msgval);
            var msgFlags = (int)((msgval & 0xC0000000L) >> 30);
            var msgSize  = msgval & 0x3FFFFFFF;

            var decoded = new LavalinkTrack
            {
                TrackString = track
            };

            using (var ms = new MemoryStream(msgSize))
            {
                ms.Write(raw, 4, msgSize);
                ms.Position = 0;

                using (var br = new BinaryReader(ms))
                {
                    var version = (msgFlags & 1) == 1 ? br.ReadByte() & 0xFF : 1;

                    var len = br.ReadInt16();
                    len           = SwapEndianness(len);
                    raw           = br.ReadBytes(len);
                    decoded.Title = UTF8.GetString(raw, 0, len);

                    len            = br.ReadInt16();
                    len            = SwapEndianness(len);
                    raw            = br.ReadBytes(len);
                    decoded.Author = UTF8.GetString(raw, 0, len);

                    decoded._length = (long)SwapEndianness((ulong)br.ReadInt64());

                    len = br.ReadInt16();
                    len = SwapEndianness(len);
                    raw = br.ReadBytes(len);
                    decoded.Identifier = UTF8.GetString(raw, 0, len);

                    decoded.IsStream = br.ReadBoolean();

                    var isthere = br.ReadBoolean();
                    if (isthere)
                    {
                        len         = br.ReadInt16();
                        len         = SwapEndianness(len);
                        raw         = br.ReadBytes(len);
                        decoded.Uri = version >= 2 ? new Uri(UTF8.GetString(raw, 0, len)) : null;
                    }
                }
            }

            return(decoded);
        }
Exemple #2
0
        /// <summary>
        /// Queues the specified track for playback.
        /// </summary>
        /// <param name="track">Track to play.</param>
        /// <returns></returns>
        public void Play(LavalinkTrack track)
        {
            if (!this.IsConnected)
            {
                throw new InvalidOperationException("This connection is not valid.");
            }

            this.CurrentState.CurrentTrack = track;
            this.Node.SendPayload(new LavalinkPlay(this, track));
        }
        /// <summary>
        /// Queues the specified track for playback.
        /// </summary>
        /// <param name="track">Track to play.</param>
        public async Task PlayAsync(LavalinkTrack track)
        {
            if (!this.IsConnected)
            {
                throw new InvalidOperationException("This connection is not valid.");
            }

            this.CurrentState.CurrentTrack = track;
            await this.Node.SendPayloadAsync(new LavalinkPlay(this, track)).ConfigureAwait(false);
        }
Exemple #4
0
        /// <summary>
        /// Decodes a Lavalink track string.
        /// </summary>
        /// <param name="track">Track string to decode.</param>
        /// <returns>Decoded Lavalink track.</returns>
        public static LavalinkTrack DecodeTrack(string track)
        {
            // https://github.com/sedmelluq/lavaplayer/blob/804cd1038229230052d9b1dee5e6d1741e30e284/main/src/main/java/com/sedmelluq/discord/lavaplayer/player/DefaultAudioPlayerManager.java#L63-L64
            const int TRACK_INFO_VERSIONED = 1;
            //const int TRACK_INFO_VERSION = 2;

            var raw = Convert.FromBase64String(track);

            var decoded = new LavalinkTrack
            {
                TrackString = track
            };

            using (var ms = new MemoryStream(raw))
                using (var br = new JavaBinaryReader(ms))
                {
                    // https://github.com/sedmelluq/lavaplayer/blob/b0c536098c4f92e6d03b00f19221021f8f50b19b/main/src/main/java/com/sedmelluq/discord/lavaplayer/tools/io/MessageInput.java#L37-L39
                    var messageHeader = br.ReadInt32();
                    var messageFlags  = (int)((messageHeader & 0xC0000000L) >> 30);
                    var messageSize   = messageHeader & 0x3FFFFFFF;
                    //if (messageSize != raw.Length)
                    //    Warn($"Size conflict: {messageSize} but was {raw.Length}");

                    // https://github.com/sedmelluq/lavaplayer/blob/804cd1038229230052d9b1dee5e6d1741e30e284/main/src/main/java/com/sedmelluq/discord/lavaplayer/player/DefaultAudioPlayerManager.java#L268

                    // java bytes are signed
                    // https://docs.oracle.com/javase/7/docs/api/java/io/DataInput.html#readByte()
                    var version = (messageFlags & TRACK_INFO_VERSIONED) != 0 ? (br.ReadSByte() & 0xFF) : 1;
                    //if (version != TRACK_INFO_VERSION)
                    //    Warn($"Version conflict: Expected {TRACK_INFO_VERSION} but got {version}");

                    decoded.Title = br.ReadJavaUtf8();

                    decoded.Author = br.ReadJavaUtf8();

                    decoded._length = br.ReadInt64();

                    decoded.Identifier = br.ReadJavaUtf8();

                    decoded.IsStream = br.ReadBoolean();

                    var uri = br.ReadNullableString();
                    if (uri != null && version >= 2)
                    {
                        decoded.Uri = new Uri(uri);
                    }
                    else
                    {
                        decoded.Uri = null;
                    }
                }

            return(decoded);
        }
Exemple #5
0
        /// <summary>
        /// Queues the specified track for playback. The track will be played from specified start timestamp to specified end timestamp.
        /// </summary>
        /// <param name="track">Track to play.</param>
        /// <param name="start">Timestamp to start playback at.</param>
        /// <param name="end">Timestamp to stop playback at.</param>
        /// <returns></returns>
        public void PlayPartial(LavalinkTrack track, TimeSpan start, TimeSpan end)
        {
            if (!this.IsConnected)
            {
                throw new InvalidOperationException("This connection is not valid.");
            }

            if (start.TotalMilliseconds < 0 || end <= start)
            {
                throw new ArgumentException("Both start and end timestamps need to be greater or equal to zero, and the end timestamp needs to be greater than start timestamp.");
            }

            this.CurrentState.CurrentTrack = track;
            this.Node.SendPayload(new LavalinkPlayPartial(this, track, start, end));
        }