コード例 #1
0
        public bool ParseStats(byte[] stat)
        {
            try
            {
                if (stat != null)
                {
                    GameStatsRaw = stat;
                    SerializationContext context = new SerializationContext();

                    //Convert replay end of game stats to parsable object
                    context.Register(typeof(EndOfGameStats));
                    context.Register(typeof(PlayerParticipantStatsSummary));
                    context.Register(typeof(RawStatDTO));


                    AmfReader statsReader = new AmfReader(new MemoryStream(stat), context);

                    GameStats = (EndOfGameStats)statsReader.ReadAmf3Item();
                }
                else
                {
                    GameStats = null;
                }
                return(true);
            }
            catch
            {
                return(false);
            }
        }
コード例 #2
0
        static RtmpEvent ReadCommandOrData(AmfReader r, Command command, RtmpHeader header = null)
        {
            var    methodName = (string)r.ReadAmf0Item();
            object temp       = r.ReadAmf0Item();

            if (header != null && methodName == "@setDataFrame")
            {
                command.ConnectionParameters = temp;
            }
            else
            {
                command.InvokeId             = Convert.ToInt32(temp);
                command.ConnectionParameters = r.ReadAmf0Item();
            }


            var parameters = new List <object>();

            while (r.DataAvailable)
            {
                parameters.Add(r.ReadAmf0Item());
            }

            command.MethodCall = new Method(methodName, parameters.ToArray());
            return(command);
        }
コード例 #3
0
        static RtmpEvent ReadCommandOrData(AmfReader r, Command command)
        {
            var methodName = (string)r.ReadAmf0Item();

            var tmp = r.ReadAmf0Item();

            if (tmp is AsObject)
            {
                command.ConnectionParameters = tmp;
//                tmp = r.ReadAmf0Item();
            }
            else
            {
                command.InvokeId             = Convert.ToInt32(tmp);
                command.ConnectionParameters = r.ReadAmf0Item();
            }

            var parameters = new List <object>();

            while (r.DataAvailable)
            {
                parameters.Add(r.ReadAmf0Item());
            }

            command.MethodCall = new Method(methodName, parameters.ToArray());
            return(command);
        }
コード例 #4
0
        private RtmpHeader ReadHeader()
        {
            int       num1          = (int)this._reader.ReadByte();
            AmfReader reader        = this._reader;
            int       chunkStreamId = RtmpPacketReader.GetChunkStreamId((byte)num1, reader);
            int       num2          = 6;
            ChunkMessageHeaderType messageHeaderType = (ChunkMessageHeaderType)(num1 >> num2);
            RtmpHeader             rtmpHeader1       = new RtmpHeader();

            rtmpHeader1.StreamId = chunkStreamId;
            int num3 = (uint)messageHeaderType > 0U ? 1 : 0;

            rtmpHeader1.IsTimerRelative = num3 != 0;
            RtmpHeader rtmpHeader2 = rtmpHeader1;
            RtmpHeader rtmpHeader3;

            if (!this._rtmpHeaders.TryGetValue(chunkStreamId, out rtmpHeader3) && messageHeaderType != ChunkMessageHeaderType.New)
            {
                rtmpHeader3 = rtmpHeader2.Clone();
            }
            switch (messageHeaderType)
            {
            case ChunkMessageHeaderType.New:
                rtmpHeader2.Timestamp       = this._reader.ReadUInt24();
                rtmpHeader2.PacketLength    = this._reader.ReadUInt24();
                rtmpHeader2.MessageType     = (MessageType)this._reader.ReadByte();
                rtmpHeader2.MessageStreamId = this._reader.ReadReverseInt();
                break;

            case ChunkMessageHeaderType.SameSource:
                rtmpHeader2.Timestamp       = this._reader.ReadUInt24();
                rtmpHeader2.PacketLength    = this._reader.ReadUInt24();
                rtmpHeader2.MessageType     = (MessageType)this._reader.ReadByte();
                rtmpHeader2.MessageStreamId = rtmpHeader3.MessageStreamId;
                break;

            case ChunkMessageHeaderType.TimestampAdjustment:
                rtmpHeader2.Timestamp       = this._reader.ReadUInt24();
                rtmpHeader2.PacketLength    = rtmpHeader3.PacketLength;
                rtmpHeader2.MessageType     = rtmpHeader3.MessageType;
                rtmpHeader2.MessageStreamId = rtmpHeader3.MessageStreamId;
                break;

            case ChunkMessageHeaderType.Continuation:
                rtmpHeader2.Timestamp       = rtmpHeader3.Timestamp;
                rtmpHeader2.PacketLength    = rtmpHeader3.PacketLength;
                rtmpHeader2.MessageType     = rtmpHeader3.MessageType;
                rtmpHeader2.MessageStreamId = rtmpHeader3.MessageStreamId;
                rtmpHeader2.IsTimerRelative = rtmpHeader3.IsTimerRelative;
                break;

            default:
                throw new SerializationException("Unexpected header type: " + (object)(int)messageHeaderType);
            }
            if (rtmpHeader2.Timestamp == 16777215)
            {
                rtmpHeader2.Timestamp = this._reader.ReadInt32();
            }
            return(rtmpHeader2);
        }
コード例 #5
0
 public RtmpPacketReader(AmfReader reader)
 {
     this._reader      = reader;
     this._rtmpHeaders = new Dictionary <int, RtmpHeader>();
     this._rtmpPackets = new Dictionary <int, RtmpPacket>();
     this.Continue     = true;
 }
コード例 #6
0
 // part 1: read from the chunk stream, returning true if enough data is here. you must take the value
 // returned at `chunkStreamId`, find the chunk stream snapshot associated with that chunk stream and
 // pass it to the second stage (part2) along with the opaque value.
 public static bool ReadFrom1(AmfReader reader, out int chunkStreamId, out MessageHeader.Type opaque)
 {
     if (BasicHeader.ReadFrom(reader, out var format, out var streamId))
     {
         opaque        = (MessageHeader.Type)format;
         chunkStreamId = streamId;
         return(true);
     }
コード例 #7
0
            static async Task <(uint echoTime, Space <byte> echoRandom)> ReadS2Async(Stream stream)
            {
                var buffer = await stream.ReadBytesAsync(FrameLength);

                var reader = new AmfReader(buffer, EmptyContext);

                var time = reader.ReadUInt32();             // "time":        a copy of c1 time
                var ____ = reader.ReadUInt32();             // "time2":       current local time
                var echo = reader.ReadSpan(RandomLength);   // "random echo": a copy of c1 random

                return(time, echo);
            }
コード例 #8
0
        RtmpEvent ParsePacket(RtmpPacket packet, Func <AmfReader, RtmpEvent> handler)
        {
            var memoryStream = new MemoryStream(packet.Buffer, false);
            var packetReader = new AmfReader(memoryStream, reader.SerializationContext);

            var header  = packet.Header;
            var message = handler(packetReader);

            message.Header    = header;
            message.Timestamp = header.Timestamp;
            return(message);
        }
コード例 #9
0
            static async Task <(uint three, uint time, uint zero, Space <byte> random)> ReadS1Async(Stream stream)
            {
                var buffer = await stream.ReadBytesAsync(C1Length);

                var reader = new AmfReader(buffer, EmptyContext);

                var three  = reader.ReadByte();             // rtmp version (constant 3) [s0]
                var time   = reader.ReadUInt32();           // time                      [s1]
                var zero   = reader.ReadUInt32();           // zero                      [s1]
                var random = reader.ReadSpan(RandomLength); // random bytes              [s1]

                return(three, time, zero, random);
            }
コード例 #10
0
        private RtmpEvent ParsePacket(RtmpPacket packet, Func <AmfReader, RtmpEvent> handler)
        {
            AmfReader  amfReader  = new AmfReader((Stream) new MemoryStream(packet.Buffer, false), this._reader.SerializationContext);
            RtmpHeader header     = packet.Header;
            RtmpEvent  rtmpEvent  = handler(amfReader);
            RtmpHeader rtmpHeader = header;

            rtmpEvent.Header = rtmpHeader;
            int timestamp = header.Timestamp;

            rtmpEvent.Timestamp = timestamp;
            return(rtmpEvent);
        }
コード例 #11
0
        public static async Task <RtmpHandshake> ReadAsync(Stream stream, bool readVersion)
        {
            RtmpHandshake rtmpHandshake;

            using (AmfReader amfReader = new AmfReader((Stream) new MemoryStream(await StreamHelper.ReadBytesAsync(stream, 1536 + (readVersion ? 1 : 0))), (SerializationContext)null))
                rtmpHandshake = new RtmpHandshake()
                {
                    Version = readVersion ? amfReader.ReadByte() : (byte)0,
                    Time    = amfReader.ReadUInt32(),
                    Time2   = amfReader.ReadUInt32(),
                    Random  = amfReader.ReadBytes(1528)
                };
            return(rtmpHandshake);
        }
コード例 #12
0
ファイル: Program.cs プロジェクト: Veraatversus/HZBot
        static void Main(string[] args)
        {
            var       ConstansUrl = "http://hz-static-2.akamaized.net/assets/data/constants.data?cfeb208c39166420a536c2dcc146a277146";
            var       zlibstream  = new System.Net.Http.HttpClient().GetStreamAsync(ConstansUrl).GetAwaiter().GetResult();
            AmfReader amfreader;

            using (var amfstream = new ZlibStream(zlibstream, System.IO.Compression.CompressionMode.Decompress))
            {
                amfreader = new AmfReader(ReadFully(amfstream), new SerializationContext());
            }
            var output = JsonConvert.SerializeObject(amfreader.ReadAmf3Object());

            File.WriteAllText("constantsReadable.json", output);
        }
コード例 #13
0
        public static RtmpHandshake Read(Stream stream, bool readVersion)
        {
            int count = 1536 + (readVersion ? 1 : 0);

            using (AmfReader amfReader = new AmfReader((Stream) new MemoryStream(StreamHelper.ReadBytes(stream, count)), (SerializationContext)null))
            {
                RtmpHandshake rtmpHandshake = new RtmpHandshake();
                rtmpHandshake.Version = readVersion ? amfReader.ReadByte() : (byte)0;
                rtmpHandshake.Time    = amfReader.ReadUInt32();
                rtmpHandshake.Time2   = amfReader.ReadUInt32();
                rtmpHandshake.Random  = amfReader.ReadBytes(1528);
                rtmpHandshake         = rtmpHandshake;
                return(rtmpHandshake);
            }
        }
コード例 #14
0
        public static RtmpHandshake Read(Stream stream, bool readVersion)
        {
            int count = 1536 + (readVersion ? 1 : 0);

            using (AmfReader amfReader = new AmfReader(new MemoryStream(StreamHelper.ReadBytes(stream, count)), null))
            {
                return(new RtmpHandshake()
                {
                    Version = readVersion ? amfReader.ReadByte() : (byte)0,
                    Time = amfReader.ReadUInt32(),
                    Time2 = amfReader.ReadUInt32(),
                    Random = amfReader.ReadBytes(1528)
                });
            }
        }
コード例 #15
0
        private static RtmpEvent ReadCommandOrData(AmfReader r, Command command)
        {
            string methodName = (string)r.ReadAmf0Item();

            command.InvokeId             = Convert.ToInt32(r.ReadAmf0Item());
            command.ConnectionParameters = r.ReadAmf0Item();
            List <object> objectList = new List <object>();

            while (r.DataAvailable)
            {
                objectList.Add(r.ReadAmf0Item());
            }
            command.MethodCall = new Method(methodName, objectList.ToArray(), true, CallStatus.Request);
            return((RtmpEvent)command);
        }
コード例 #16
0
ファイル: RtmpHandshake.cs プロジェクト: dutysok/Sightstone
        public static RtmpHandshake Read(Stream stream, bool readVersion)
        {
            var size   = HandshakeSize + (readVersion ? 1 : 0);
            var buffer = StreamHelper.ReadBytes(stream, size);

            using (var reader = new AmfReader(new MemoryStream(buffer), null))
            {
                return(new RtmpHandshake
                {
                    Version = readVersion ? reader.ReadByte() : default(byte),
                    Time = reader.ReadUInt32(),
                    Time2 = reader.ReadUInt32(),
                    Random = reader.ReadBytes(HandshakeRandomSize)
                });
            }
        }
コード例 #17
0
        private static int GetChunkStreamId(byte chunkBasicHeaderByte, AmfReader reader)
        {
            int num = (int)chunkBasicHeaderByte & 63;

            switch (num)
            {
            case 0:
                return((int)reader.ReadByte() + 64);

            case 1:
                return((int)reader.ReadByte() + (int)reader.ReadByte() * 256 + 64);

            default:
                return(num);
            }
        }
コード例 #18
0
ファイル: RtmpClient.cs プロジェクト: doivosevic/Summoning
            public static async Task <Handshake> ReadAsync(Stream stream, bool readVersion)
            {
                var size   = HandshakeSize + (readVersion ? 1 : 0);
                var buffer = await StreamHelper.ReadBytesAsync(stream, size);

                using (var reader = new AmfReader(new MemoryStream(buffer), null))
                {
                    return(new Handshake()
                    {
                        Version = readVersion ? reader.ReadByte() : default(byte),
                        Time = reader.ReadUInt32(),
                        Time2 = reader.ReadUInt32(),
                        Random = reader.ReadBytes(HandshakeRandomSize)
                    });
                }
            }
コード例 #19
0
            public static bool ReadFrom(AmfReader reader, out int format, out int chunkStreamId)
            {
                format        = 0;
                chunkStreamId = 0;

                if (!reader.HasLength(1))
                {
                    return(false);
                }

                var b0  = reader.ReadByte();
                var v   = b0 & 0x3f;
                var fmt = b0 >> 6;

                switch (v)
                {
                // 2 byte variant
                case 0:
                    if (!reader.HasLength(1))
                    {
                        return(false);
                    }

                    format        = fmt;
                    chunkStreamId = reader.ReadByte() + 64;
                    return(true);

                // 3 byte variant
                case 1:
                    if (!reader.HasLength(2))
                    {
                        return(false);
                    }

                    format        = fmt;
                    chunkStreamId = reader.ReadByte() + reader.ReadByte() * 256 + 64;
                    return(true);

                // 1 byte variant
                default:
                    format        = fmt;
                    chunkStreamId = v;
                    return(true);
                }
            }
コード例 #20
0
        static int GetChunkStreamId(byte chunkBasicHeaderByte, AmfReader reader)
        {
            var chunkStreamId = chunkBasicHeaderByte & 0x3F;

            // 2 bytes
            if (chunkStreamId == 0)
            {
                return(reader.ReadByte() + 64);
            }

            // 3 bytes
            if (chunkStreamId == 1)
            {
                return(reader.ReadByte() + reader.ReadByte() * 256 + 64);
            }

            return(chunkStreamId);
        }
コード例 #21
0
            public Reader(RtmpClient owner, Stream stream, SerializationContext context, CancellationToken cancellationToken)
            {
                this.owner   = owner;
                this.stream  = stream;
                this.context = context;
                this.token   = cancellationToken;

                this.reset    = new AsyncAutoResetEvent();
                this.queue    = new ConcurrentQueue <Builder>();
                this.streams  = new KeyDictionary <int, ChunkStream.Snapshot>();
                this.messages = new KeyDictionary <(int, uint), Builder>();

                this.buffer    = new byte[DefaultBufferLength];
                this.available = 0;

                this.__readSingleFrameReader      = new AmfReader(context);
                this.__readFramesFromBufferReader = new AmfReader(context);
            }
コード例 #22
0
        static int GetChunkStreamId(byte chunkBasicHeaderByte, AmfReader reader)
        {
            var chunkStreamId = chunkBasicHeaderByte & 0x3F;

            switch (chunkStreamId)
            {
            // 2 bytes
            case 0:
                return(reader.ReadByte() + 64);

            // 3 bytes
            case 1:
                return(reader.ReadByte() + reader.ReadByte() * 256 + 64);

            // 1 byte
            default:
                return(chunkStreamId);
            }
        }
コード例 #23
0
        static async Task <int> GetChunkStreamIdAsync(byte chunkBasicHeaderByte, AmfReader reader)
        {
            var chunkStreamId = chunkBasicHeaderByte & 0x3F;

            switch (chunkStreamId)
            {
            // 2 bytes
            case 0:
                return(await reader.ReadByteAsync() + 64);

            // 3 bytes
            case 1:
                return(await reader.ReadByteAsync() + await reader.ReadByteAsync() * 256 + 64);

            // 1 byte
            default:
                return(chunkStreamId);
            }
        }
コード例 #24
0
ファイル: DataInput.cs プロジェクト: yswenli/Wenli.RtmpServer
 public DataInput(AmfReader reader)
 {
     this.reader         = reader;
     this.objectEncoding = ObjectEncoding.Amf3;
 }
コード例 #25
0
        private void UpdateReplays()
        {
            GamePanel.Children.Clear();

            var dir = new DirectoryInfo(Path.Combine(Client.ExecutingDirectory, "cabinet"));
            IOrderedEnumerable <DirectoryInfo> directories = dir.EnumerateDirectories()
                                                             .OrderBy(d => d.CreationTime);

            string[] Replays = Directory.GetDirectories(Path.Combine(Client.ExecutingDirectory, "cabinet"));

            foreach (DirectoryInfo di in directories)
            {
                string d = di.Name;
                if (!File.Exists(Path.Combine(Client.ExecutingDirectory, "cabinet", d, "token")) ||
                    !File.Exists(Path.Combine(Client.ExecutingDirectory, "cabinet", d, "key")) ||
                    !File.Exists(Path.Combine(Client.ExecutingDirectory, "cabinet", d, "endOfGameStats")))
                {
                    continue;
                }

                byte[] base64Stats =
                    Convert.FromBase64String(
                        File.ReadAllText(Path.Combine(Client.ExecutingDirectory, "cabinet", d, "endOfGameStats")));
                var statsReader = new AmfReader(new MemoryStream(base64Stats), context);

                var stats = (EndOfGameStats)statsReader.ReadAmf3Item();

                var item = new ReplayItem();

                //Use unoccupied variable
                stats.Difficulty = d;

                item.Tag         = stats;
                item.GameId.Text = File.Exists(Path.Combine(Client.ExecutingDirectory, "cabinet", d, "name"))
                    ? File.ReadAllText(Path.Combine(Client.ExecutingDirectory, "cabinet", d, "name"))
                    : d;
                item.GameId.Tag       = d;
                item.GameType.Content = stats.GameMode.ToLower();
                item.GameDate.Content = di.CreationTime.ToShortTimeString() + " " + di.CreationTime.ToShortDateString();
                double seconds = stats.GameLength % 60;
                double minutes = stats.GameLength / 60;
                item.GameTime.Content = string.Format("{0:0}:{1:00}", minutes, seconds);
                item.Margin           = new Thickness(0, 5, 0, 0);

                foreach (
                    SmallChampionItem image in stats.TeamPlayerParticipantStats.Select(summary => new SmallChampionItem
                {
                    Width = 38,
                    Height = 38,
                    ChampionImage =
                    {
                        Source = Client.GetImage(Path.Combine(Client.ExecutingDirectory, "Assets", "champion",
                                                              summary.SkinName + ".png"))
                    }
                }))
                {
                    item.TeamOnePanel.Children.Add(image);
                }

                foreach (
                    SmallChampionItem image in
                    stats.OtherTeamPlayerParticipantStats.Select(summary => new SmallChampionItem
                {
                    Width = 38,
                    Height = 38,
                    ChampionImage =
                    {
                        Source = Client.GetImage(Path.Combine(Client.ExecutingDirectory, "Assets", "champion",
                                                              summary.SkinName + ".png"))
                    }
                }))
                {
                    item.TeamTwoPanel.Children.Add(image);
                }

                item.MouseDown += item_MouseDown;
                item.GameId.MouseDoubleClick += GameId_MouseDoubleClick;
                item.GameId.MouseLeave       += GameId_MouseLeave;
                item.KeyDown += item_KeyDown;

                //Insert on top
                GamePanel.Children.Insert(0, item);
            }
        }
コード例 #26
0
        void UpdateReplays()
        {
            GamePanel.Children.Clear();

            var dir = new DirectoryInfo("cabinet");
            var directories = dir.EnumerateDirectories()
                                .OrderBy(d => d.CreationTime);

            string[] Replays = Directory.GetDirectories("cabinet");

            foreach (DirectoryInfo di in directories)
            {
                string d = di.Name;
                if (!File.Exists(Path.Combine("cabinet", d, "token")) ||
                    !File.Exists(Path.Combine("cabinet", d, "key")) ||
                    !File.Exists(Path.Combine("cabinet", d, "endOfGameStats")))
                    continue;

                byte[] Base64Stats = Convert.FromBase64String(File.ReadAllText(Path.Combine("cabinet", d, "endOfGameStats")));
                AmfReader statsReader = new AmfReader(new MemoryStream(Base64Stats), context);

                EndOfGameStats stats = (EndOfGameStats)statsReader.ReadAmf3Item();

                ReplayItem item = new ReplayItem();

                //Use unoccupied variable
                stats.Difficulty = d;

                item.Tag = stats;
                item.GameId.Content = d;
                item.GameType.Content = stats.GameMode.ToLower();
                item.GameDate.Content = di.CreationTime.ToShortTimeString() + " " + di.CreationTime.ToShortDateString();
                double seconds = stats.GameLength % 60;
                double minutes = stats.GameLength / 60;
                item.GameTime.Content = string.Format("{0:0}:{1:00}", minutes, seconds);
                item.Margin = new Thickness(0, 5, 0, 0);

                foreach (PlayerParticipantStatsSummary summary in stats.TeamPlayerParticipantStats)
                {
                    SmallChampionItem image = new SmallChampionItem();
                    image.Width = 38;
                    image.Height = 38;

                    Uri UriSource = new Uri("/LegendaryReplays;component/champion/" + summary.SkinName + ".png", UriKind.RelativeOrAbsolute);
                    image.ChampionImage.Source = new BitmapImage(UriSource);

                    item.TeamOnePanel.Children.Add(image);
                }

                foreach (PlayerParticipantStatsSummary summary in stats.OtherTeamPlayerParticipantStats)
                {
                    SmallChampionItem image = new SmallChampionItem();
                    image.Width = 38;
                    image.Height = 38;

                    Uri UriSource = new Uri("/LegendaryReplays;component/champion/" + summary.SkinName + ".png", UriKind.RelativeOrAbsolute);
                    image.ChampionImage.Source = new BitmapImage(UriSource);

                    item.TeamTwoPanel.Children.Add(image);
                }

                item.MouseDown += item_MouseDown;

                //Insert on top
                GamePanel.Children.Insert(0, item);
            }
        }
コード例 #27
0
            bool ReadSingleFrame(AmfReader reader)
            {
                if (!ChunkStream.ReadFrom1(reader, out var streamId, out var opaque))
                {
                    return(false);
                }

                if (!streams.TryGetValue(streamId, out var previous))
                {
                    previous = new ChunkStream.Snapshot()
                    {
                        ChunkStreamId = streamId
                    }
                }
                ;

                if (!ChunkStream.ReadFrom2(reader, previous, opaque, out var next))
                {
                    return(false);
                }

                streams[streamId] = next;
                context.RequestReadAllocation(next.MessageLength);

                var key     = (next.ChunkStreamId, next.MessageStreamId);
                var builder = messages.TryGetValue(key, out var packet) ? packet : messages[key] = new Builder(next.MessageLength);
                var length  = Math.Min(chunkLength, builder.Remaining);

                if (!reader.HasLength(length))
                {
                    return(false);
                }

                builder.AddData(
                    reader.ReadSpan(length));

                if (builder.Current == builder.Length)
                {
                    messages.Remove(key);

                    using (builder)
                    {
                        var dereader = __readSingleFrameReader;
                        dereader.Rebind(builder.Span);

                        var message = Deserialize(next.ContentType, dereader);
                        DispatchMessage(message);
                    }
                }

                return(true);
            }

            void DispatchMessage(RtmpMessage message)
            {
                switch (message)
                {
                case ChunkLength chunk:
                    Kon.Trace("received: chunk-length", new { length = chunk.Length });

                    if (chunk.Length < 0)
                    {
                        throw new ArgumentException("invalid chunk length");
                    }

                    context.RequestReadAllocation(chunk.Length);
                    chunkLength = chunk.Length;
                    break;

                case WindowAcknowledgementSize acknowledgement:
                    if (acknowledgement.Count < 0)
                    {
                        throw new ArgumentException("invalid acknowledgement window length");
                    }

                    acknowledgementLength = acknowledgement.Count;
                    break;

                case Abort abort:
                    Kon.Trace("received: abort", new { chunk = abort.ChunkStreamId });

                    // delete the chunk stream
                    streams.Remove(abort.ChunkStreamId);

                    // then, delete all message streams associated with that chunk stream
                    foreach (var(key, builder) in messages.FilterArray(x => x.Key.chunkStreamId == abort.ChunkStreamId))
                    {
                        messages.Remove(key);
                        builder.Dispose();
                    }

                    break;

                default:
                    owner.InternalReceiveEvent(message);
                    break;
                }
            }

            // todo: refactor
            RtmpMessage Deserialize(PacketContentType contentType, AmfReader r)
            {
                // (this comment must be kept in sync at rtmpclient.reader.cs and rtmpclient.writer.cs)
                //
                // unsupported type summary:
                //
                // - aggregate:      we have never encountered this packet in the wild
                // - shared objects: we have not found a use case for this
                // - data commands:  we have not found a use case for this, though it should be extremely easy to
                //                       support. it's just a one-way equivalent of command (invoke). that is, we don't
                //                       generate an invoke id for it, and it does not contain headers. other than that,
                //                       they're identical. we can use existing logic and add if statements to surround
                //                       writing the invokeid + headers if needed.

                switch (contentType)
                {
                case PacketContentType.SetChunkSize:
                    return(new ChunkLength(
                               length: r.ReadInt32()));

                case PacketContentType.AbortMessage:
                    return(new Abort(
                               chunkStreamId: r.ReadInt32()));

                case PacketContentType.Acknowledgement:
                    return(new Acknowledgement(
                               read: r.ReadUInt32()));

                case PacketContentType.UserControlMessage:
                    var type   = r.ReadUInt16();
                    var values = EnumerableEx.Range(r.Remaining / 4, r.ReadUInt32);

                    return(new UserControlMessage(
                               type:   (UserControlMessage.Type)type,
                               values: values));

                case PacketContentType.WindowAcknowledgementSize:
                    return(new WindowAcknowledgementSize(
                               count: r.ReadInt32()));

                case PacketContentType.SetPeerBandwith:
                    return(new PeerBandwidth(
                               acknowledgementWindowSize: r.ReadInt32(),
                               type:                 r.ReadByte()));

                case PacketContentType.Audio:
                    return(new AudioData(
                               r.ReadBytes(r.Remaining)));

                case PacketContentType.Video:
                    return(new VideoData(
                               r.ReadBytes(r.Remaining)));

                case PacketContentType.DataAmf0:
                    throw NotSupportedException("data-amf0");

                case PacketContentType.SharedObjectAmf0:
                    throw NotSupportedException("sharedobject-amf0");

                case PacketContentType.CommandAmf0:
                    return(ReadCommand(ObjectEncoding.Amf0, contentType, r));

                case PacketContentType.DataAmf3:
                    throw NotSupportedException("data-amf3");

                case PacketContentType.SharedObjectAmf3:
                    throw NotSupportedException("sharedobject-amf0");

                case PacketContentType.CommandAmf3:
                    var encoding = (ObjectEncoding)r.ReadByte();
                    return(ReadCommand(encoding, contentType, r));

                case PacketContentType.Aggregate:
                    throw NotSupportedException("aggregate");

                default:
                    throw NotSupportedException($"unknown ({contentType})");
                }
            }
コード例 #28
0
            static RtmpMessage ReadCommand(ObjectEncoding encoding, PacketContentType type, AmfReader r)
            {
                var name     = (string)r.ReadAmfObject(encoding);
                var invokeId = Convert.ToUInt32(r.ReadAmfObject(encoding));
                var headers  = r.ReadAmfObject(encoding);

                var args = new List <object>();

                while (r.Remaining > 0)
                {
                    args.Add(r.ReadAmfObject(encoding));
                }

                return(new Invoke(type)
                {
                    MethodName = name, Arguments = args.ToArray(), InvokeId = invokeId, Headers = headers
                });
            }
コード例 #29
0
 public void Init()
 {
     foreach (BootstrapInfo b in BootstrapInfos)
     {
         MemoryStream ms=new MemoryStream(Convert.FromBase64String(b.Text));
         BoxReader reader=new BoxReader(ms);
         b.Info=new BootStrap();
         string name;
         reader.ReadHeader(out name);
         reader.ReadBootStrap(b.Info);
         reader.Dispose();
     }
     foreach (Media m in Medias)
     {
         MemoryStream ms=new MemoryStream(Convert.FromBase64String(m.Metadata));
         AmfReader reader=new AmfReader(ms);
         m.MetadataInfo = reader.ReadObject<Metadata>();
         reader.Dispose();
         m.Info = BootstrapInfos.First(a => a.Id == m.BootstrapInfoId);
     }
 }
コード例 #30
0
            public static bool ReadFrom(AmfReader reader, Type type, ChunkStream.Snapshot previous, out ChunkStream.Snapshot next)
            {
                next               = default(ChunkStream.Snapshot);
                next.Ready         = true;
                next.ChunkStreamId = previous.ChunkStreamId;

                if (!reader.HasLength(TypeByteLengths[(byte)type]))
                {
                    return(false);
                }

                switch (type)
                {
                case Type.Type0:
                    next.Timestamp       = reader.ReadUInt24();
                    next.MessageLength   = (int)reader.ReadUInt24();
                    next.ContentType     = (PacketContentType)reader.ReadByte();
                    next.MessageStreamId = (uint)reader.ReadLittleEndianInt();

                    return(MaybeReadExtraTimestamp(ref next.Timestamp));

                case Type.Type1:
                    next.Timestamp     = reader.ReadUInt24();
                    next.MessageLength = (int)reader.ReadUInt24();
                    next.ContentType   = (PacketContentType)reader.ReadByte();

                    next.MessageStreamId = previous.MessageStreamId;
                    return(MaybeReadExtraTimestamp(ref next.Timestamp));

                case Type.Type2:
                    next.Timestamp = reader.ReadUInt24();

                    next.MessageLength   = previous.MessageLength;
                    next.ContentType     = previous.ContentType;
                    next.MessageStreamId = previous.MessageStreamId;
                    return(MaybeReadExtraTimestamp(ref next.Timestamp));

                case Type.Type3:
                    next.Timestamp       = previous.Timestamp;
                    next.MessageLength   = previous.MessageLength;
                    next.ContentType     = previous.ContentType;
                    next.MessageStreamId = previous.MessageStreamId;
                    return(true);

                default:
                    throw new ArgumentOutOfRangeException(nameof(type), "unknown type");
                }

                bool MaybeReadExtraTimestamp(ref uint timestamp)
                {
                    if (timestamp != ExtendedTimestampSentinel)
                    {
                        return(true);
                    }

                    if (!reader.HasLength(4))
                    {
                        return(false);
                    }

                    timestamp = (uint)reader.ReadInt32();
                    return(true);
                }
            }
コード例 #31
0
ファイル: DataInput.cs プロジェクト: ResQue1980/rtmp-sharp
 public DataInput(AmfReader reader)
 {
     this.reader = reader;
     this.objectEncoding = ObjectEncoding.Amf3;
 }