예제 #1
0
        public PartialNetworkStream(MainWindow InMainWindow, List <PartialNetworkStream> InStreams, int InStartFrame, int InEndFrame, int InNameIndexUnreal, FilterValues InFilterValues, float InDeltaTime)
        {
            NameIndexUnreal     = InNameIndexUnreal;
            FirstFrameDeltaTime = InDeltaTime;

            InMainWindow.ShowProgress(true);
            InMainWindow.UpdateProgress(0);

            // Merge tokens from passed in streams.
            for (int i = InStartFrame; i < InEndFrame; i++)
            {
                PartialNetworkStream Stream = InStreams[i];

                if (i % 10 == 0)
                {
                    float Percent = (float)(i - InStartFrame) / (float)(InEndFrame - InStartFrame);
                    InMainWindow.UpdateProgress(( int )(Percent * 100));
                }

                // Merge tokens from passed in stream based on filter criteria.
                foreach (var Token in Stream.Tokens)
                {
                    if (Token.MatchesFilters(InFilterValues))
                    {
                        Tokens.Add(Token);
                        UpdateSummary(Token, InFilterValues);
                    }
                }
            }

            InMainWindow.ShowProgress(false);

            EndTime += InDeltaTime;
        }
예제 #2
0
 public void AddStream(PartialNetworkStream InStream)
 {
     // Merge tokens from passed in stream based on filter criteria.
     foreach (var Token in InStream.Tokens)
     {
         Tokens.Add(Token);
         UpdateSummary(Token, new FilterValues());
     }
 }
예제 #3
0
        /**
         * Constructor, duplicating the passed in stream while applying the passed in filters.
         *
         * @param	InStream		Stream to duplicate
         * @param	ActorFilter		Actor filter to match against
         * @param	PropertyFilter	Property filter to match against
         * @param	RPCFilter		RPC filter to match against
         */
        public PartialNetworkStream(PartialNetworkStream InStream, string InActorFilter, string InPropertyFilter, string InRPCFilter)
        {
            NameIndexUnreal     = InStream.NameIndexUnreal;
            FirstFrameDeltaTime = InStream.FirstFrameDeltaTime;

            // Merge tokens from passed in stream based on filter criteria.
            foreach (var Token in InStream.Tokens)
            {
                if (Token.MatchesFilters(InActorFilter, InPropertyFilter, InRPCFilter))
                {
                    Tokens.Add(Token);
                }
            }
            CreateSummary(NameIndexUnreal, FirstFrameDeltaTime, InActorFilter, InPropertyFilter, InRPCFilter);
        }
예제 #4
0
        /**
         * Constructor, duplicating the passed in stream while applying the passed in filters.
         *
         * @param	InStream		Stream to duplicate
         * @param	ActorFilter		Actor filter to match against
         * @param	PropertyFilter	Property filter to match against
         * @param	RPCFilter		RPC filter to match against
         */
        public PartialNetworkStream(PartialNetworkStream InStream, FilterValues InFilterValues)
        {
            NameIndexUnreal     = InStream.NameIndexUnreal;
            FirstFrameDeltaTime = InStream.FirstFrameDeltaTime;

            // Merge tokens from passed in stream based on filter criteria.
            foreach (var Token in InStream.Tokens)
            {
                if (Token.MatchesFilters(InFilterValues))
                {
                    Tokens.Add(Token);
                }
            }
            CreateSummary(NameIndexUnreal, FirstFrameDeltaTime, InFilterValues);
        }
        private void SelectRangeWorker(int SelectionStart, int SelectionEnd)
        {
            // Create a partial network stream with the new selection to get the summary.
            PartialNetworkStream Selection = new PartialNetworkStream(
                this,
                CurrentNetworkStream.Frames,
                SelectionStart,
                SelectionEnd,
                CurrentNetworkStream.NameIndexUnreal,
                CurrentFilterValues,
                1 / 30.0f
                );

            SetCurrentStreamSelection(CurrentNetworkStream, Selection, false);
            SelectRangeThread = null;
        }
        public void SetCurrentStreamSelection(NetworkStream NetworkStream, PartialNetworkStream Selection, bool bSingleSelect)
        {
            if (Dispatcher.CheckAccess() == false)
            {
                Dispatcher.Invoke(new Action(() => SetCurrentStreamSelection(NetworkStream, Selection, bSingleSelect)));
                return;
            }

            ActorPerfPropsDetailsListView.Items.Clear();

            Selection.ToActorSummaryView(NetworkStream, ActorSummaryView);
            Selection.ToActorPerformanceView(NetworkStream, ActorPerfPropsListView, ActorPerfPropsDetailsListView, CurrentFilterValues);

            // Below is way too slow for range select right now, so we just do this for single frame selection
            if (bSingleSelect)
            {
                Selection.ToDetailedTreeView(TokenDetailsView.Items, CurrentFilterValues);
            }

            CurrentStreamSelection = Selection;
        }
예제 #7
0
        /**
         * Selection dragging on the X axis will update the summary to be current selection.
         */
        private void NetworkChart_SelectionRangeChanged(object sender, CursorEventArgs e)
        {
            if ((CurrentNetworkStream == null) || (CurrentNetworkStream.Frames.Count == 0))
            {
                return;
            }

            if (e.Axis.AxisName == AxisName.X)
            {
                int SelectionStart = Math.Max(
                    0,
                    (int)NetworkChart.ChartAreas["DefaultChartArea"].AxisX.ScaleView.ViewMinimum);
                int SelectionEnd = Math.Min(
                    CurrentNetworkStream.Frames.Count,
                    (int)NetworkChart.ChartAreas["DefaultChartArea"].AxisX.ScaleView.ViewMaximum);

                // Create a partial network stream with the new selection to get the summary.
                PartialNetworkStream Selection = new PartialNetworkStream(
                    CurrentNetworkStream.Frames.GetRange(SelectionStart, SelectionEnd - SelectionStart),
                    CurrentNetworkStream.NameIndexUnreal,
                    1 / 30.0f);
                SummaryTextBox.Lines = Selection.Filter(CurrentActorFilter, CurrentPropertyFilter, CurrentRPCFilter).ToStringArray();
            }
        }
예제 #8
0
        public static void ParseStreamIntoChart(NetworkStream NetworkStream, Chart NetworkChart, string ActorFilter, string PropertyFilter, string RPCFilter)
        {
            var StartTime = DateTime.UtcNow;

            NetworkChart.BeginInit();

            // Reset existing data.
            foreach (var Series in NetworkChart.Series)
            {
                Series.Points.Clear();
            }
            NetworkChart.ResetAutoValues();
            NetworkChart.Invalidate();

            NetworkChart.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = false;
            NetworkChart.ChartAreas[0].AxisX.ScrollBar.ButtonStyle        = ScrollBarButtonStyles.All;
            NetworkChart.ChartAreas[0].AxisX.ScrollBar.Size        = 15;
            NetworkChart.ChartAreas[0].AxisX.ScrollBar.ButtonColor = Color.LightGray;

            NetworkChart.ChartAreas[0].AxisY.ScrollBar.IsPositionedInside = false;
            NetworkChart.ChartAreas[0].AxisY.ScrollBar.ButtonStyle        = ScrollBarButtonStyles.All;
            NetworkChart.ChartAreas[0].AxisY.ScrollBar.Size        = 15;
            NetworkChart.ChartAreas[0].AxisY.ScrollBar.ButtonColor = Color.LightGray;

            int FrameCounter = 0;

            foreach (PartialNetworkStream RawFrame in NetworkStream.Frames)
            {
                PartialNetworkStream Frame = RawFrame.Filter(ActorFilter, PropertyFilter, RPCFilter);

                if (Frame.EndTime == Frame.StartTime)
                {
                    throw new InvalidOperationException();
                }
                float OneOverDeltaTime = 1 / (Frame.EndTime - Frame.StartTime);

                NetworkChart.Series["ActorCount"].Points.AddXY(FrameCounter, Frame.ActorCount);
                NetworkChart.Series["ActorCountSec"].Points.AddXY(FrameCounter, Frame.ActorCount * OneOverDeltaTime);
                NetworkChart.Series["PropertyCount"].Points.AddXY(FrameCounter, Frame.PropertyCount);
                NetworkChart.Series["PropertyCountSec"].Points.AddXY(FrameCounter, Frame.PropertyCount * OneOverDeltaTime);
                NetworkChart.Series["PropertySize"].Points.AddXY(FrameCounter, Frame.ReplicatedSizeBits / 8);
                NetworkChart.Series["PropertySizeSec"].Points.AddXY(FrameCounter, Frame.ReplicatedSizeBits / 8 * OneOverDeltaTime);
                NetworkChart.Series["RPCCount"].Points.AddXY(FrameCounter, Frame.RPCCount);
                NetworkChart.Series["RPCCountSec"].Points.AddXY(FrameCounter, Frame.RPCCount * OneOverDeltaTime);
                NetworkChart.Series["RPCSize"].Points.AddXY(FrameCounter, Frame.RPCSizeBits / 8);
                NetworkChart.Series["RPCSizeSec"].Points.AddXY(FrameCounter, Frame.RPCSizeBits / 8 * OneOverDeltaTime);
                NetworkChart.Series["ExportBunchCount"].Points.AddXY(FrameCounter, Frame.ExportBunchCount);
                NetworkChart.Series["ExportBunchSize"].Points.AddXY(FrameCounter, Frame.ExportBunchSizeBits / 8);
                NetworkChart.Series["MustBeMappedGuidsCount"].Points.AddXY(FrameCounter, Frame.MustBeMappedGuidCount / 8);
                NetworkChart.Series["MustBeMappedGuidsSize"].Points.AddXY(FrameCounter, Frame.MustBeMappedGuidSizeBits / 8);
                NetworkChart.Series["SendAckCount"].Points.AddXY(FrameCounter, Frame.SendAckCount);
                NetworkChart.Series["SendAckCountSec"].Points.AddXY(FrameCounter, Frame.SendAckCount * OneOverDeltaTime);
                NetworkChart.Series["SendAckSize"].Points.AddXY(FrameCounter, Frame.SendAckSizeBits / 8);
                NetworkChart.Series["SendAckSizeSec"].Points.AddXY(FrameCounter, Frame.SendAckSizeBits / 8 * OneOverDeltaTime);
                NetworkChart.Series["ContentBlockHeaderSize"].Points.AddXY(FrameCounter, Frame.ContentBlockHeaderSizeBits / 8);
                NetworkChart.Series["ContentBlockFooterSize"].Points.AddXY(FrameCounter, Frame.ContentBlockFooterSizeBits / 8);
                NetworkChart.Series["PropertyHandleSize"].Points.AddXY(FrameCounter, Frame.PropertyHandleSizeBits / 8);
                NetworkChart.Series["SendBunchCount"].Points.AddXY(FrameCounter, Frame.SendBunchCount);
                NetworkChart.Series["SendBunchCountSec"].Points.AddXY(FrameCounter, Frame.SendBunchCount * OneOverDeltaTime);
                NetworkChart.Series["SendBunchSize"].Points.AddXY(FrameCounter, Frame.SendBunchSizeBits / 8);
                NetworkChart.Series["SendBunchSizeSec"].Points.AddXY(FrameCounter, Frame.SendBunchSizeBits / 8 * OneOverDeltaTime);
                NetworkChart.Series["SendBunchHeaderSize"].Points.AddXY(FrameCounter, Frame.SendBunchHeaderSizeBits / 8);
                NetworkChart.Series["GameSocketSendSize"].Points.AddXY(FrameCounter, Frame.UnrealSocketSize);
                NetworkChart.Series["GameSocketSendSizeSec"].Points.AddXY(FrameCounter, Frame.UnrealSocketSize * OneOverDeltaTime);
                NetworkChart.Series["GameSocketSendCount"].Points.AddXY(FrameCounter, Frame.UnrealSocketCount);
                NetworkChart.Series["GameSocketSendCountSec"].Points.AddXY(FrameCounter, Frame.UnrealSocketCount * OneOverDeltaTime);
                NetworkChart.Series["MiscSocketSendSize"].Points.AddXY(FrameCounter, Frame.OtherSocketSize);
                NetworkChart.Series["MiscSocketSendSizeSec"].Points.AddXY(FrameCounter, Frame.OtherSocketSize * OneOverDeltaTime);
                NetworkChart.Series["MiscSocketSendCount"].Points.AddXY(FrameCounter, Frame.OtherSocketCount);
                NetworkChart.Series["MiscSocketSendCountSec"].Points.AddXY(FrameCounter, Frame.OtherSocketCount * OneOverDeltaTime);
                int OutgoingBandwidth = Frame.UnrealSocketSize + Frame.OtherSocketSize + NetworkStream.PacketOverhead * (Frame.UnrealSocketCount + Frame.OtherSocketCount);
                NetworkChart.Series["OutgoingBandwidthSize"].Points.AddXY(FrameCounter, OutgoingBandwidth);
                NetworkChart.Series["OutgoingBandwidthSizeSec"].Points.AddXY(FrameCounter, OutgoingBandwidth * OneOverDeltaTime);
                NetworkChart.Series["ActorReplicateTimeInMS"].Points.AddXY(FrameCounter, Frame.ActorReplicateTimeInMS);

                if (Frame.NumEvents > 0)
                {
                    NetworkChart.Series["Events"].Points.AddXY(FrameCounter, 0);
                }

                FrameCounter++;
            }

            NetworkChart.DataManipulator.FinancialFormula(FinancialFormula.MovingAverage, "30", "GameSocketSendSizeSec", "GameSocketSendSizeAvgSec");
            NetworkChart.DataManipulator.FinancialFormula(FinancialFormula.MovingAverage, "30", "OutgoingBandwidthSizeSec", "OutgoingBandwidthSizeAvgSec");

            NetworkChart.ChartAreas["DefaultChartArea"].RecalculateAxesScale();

            NetworkChart.EndInit();

            Console.WriteLine("Adding data to chart took {0} seconds", (DateTime.UtcNow - StartTime).TotalSeconds);
        }
예제 #9
0
        public static void ParseStreamIntoChart(MainWindow InMainWindow, NetworkStream NetworkStream, Chart NetworkChart, FilterValues InFilterValues)
        {
            var StartTime = DateTime.UtcNow;

            InMainWindow.ShowProgress(true);

            // Save old scroll position
            double OldPosition = NetworkChart.ChartAreas["DefaultChartArea"].AxisX.ScaleView.Position;

            NetworkChart.BeginInit();

            // Reset existing data.
            for (int i = 0; i < NetworkChart.Series.Count; i++)
            {
                float Percent = ( float )i / ( float )NetworkChart.Series.Count;
                InMainWindow.UpdateProgress(( int )(Percent * 100));

                NetworkChart.Series[i].Points.Clear();
            }

            InMainWindow.ShowProgress(true);

            NetworkChart.ResetAutoValues();
            NetworkChart.Invalidate();

            NetworkChart.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = false;
            NetworkChart.ChartAreas[0].AxisX.ScrollBar.ButtonStyle        = ScrollBarButtonStyles.All;
            NetworkChart.ChartAreas[0].AxisX.ScrollBar.Size        = 15;
            NetworkChart.ChartAreas[0].AxisX.ScrollBar.ButtonColor = Color.LightGray;

            NetworkChart.ChartAreas[0].AxisY.ScrollBar.IsPositionedInside = false;
            NetworkChart.ChartAreas[0].AxisY.ScrollBar.ButtonStyle        = ScrollBarButtonStyles.All;
            NetworkChart.ChartAreas[0].AxisY.ScrollBar.Size        = 15;
            NetworkChart.ChartAreas[0].AxisY.ScrollBar.ButtonColor = Color.LightGray;

            int FrameCounter = 0;

            foreach (PartialNetworkStream RawFrame in NetworkStream.Frames)
            {
                if (FrameCounter % 1000 == 0)
                {
                    float Percent = ( float )FrameCounter / ( float )NetworkStream.Frames.Count;
                    InMainWindow.UpdateProgress(( int )(Percent * 100));
                }

                PartialNetworkStream Frame = RawFrame.Filter(InFilterValues);

                if (Frame.EndTime == Frame.StartTime)
                {
                    throw new InvalidOperationException();
                }

                float OneOverDeltaTime = 1 / (Frame.EndTime - Frame.StartTime);

                int OutgoingBandwidth = Frame.UnrealSocketSize + Frame.OtherSocketSize + NetworkStream.PacketOverhead * (Frame.UnrealSocketCount + Frame.OtherSocketCount);

                InMainWindow.AddChartPoint(SeriesType.OutgoingBandwidthSize, FrameCounter, OutgoingBandwidth);
                InMainWindow.AddChartPoint(SeriesType.OutgoingBandwidthSizeSec, FrameCounter, OutgoingBandwidth * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.ActorCount, FrameCounter, Frame.ActorCount);
                InMainWindow.AddChartPoint(SeriesType.PropertySize, FrameCounter, Frame.ReplicatedSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.PropertySizeSec, FrameCounter, Frame.ReplicatedSizeBits / 8 * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.RPCSize, FrameCounter, Frame.RPCSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.RPCSizeSec, FrameCounter, Frame.RPCSizeBits / 8 * OneOverDeltaTime);

#if true
                InMainWindow.AddChartPoint(SeriesType.ActorCountSec, FrameCounter, Frame.ActorCount * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.PropertyCount, FrameCounter, Frame.PropertyCount);
                InMainWindow.AddChartPoint(SeriesType.PropertyCountSec, FrameCounter, Frame.PropertyCount * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.RPCCount, FrameCounter, Frame.RPCCount);
                InMainWindow.AddChartPoint(SeriesType.RPCCountSec, FrameCounter, Frame.RPCCount * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.ExportBunchCount, FrameCounter, Frame.ExportBunchCount);
                InMainWindow.AddChartPoint(SeriesType.ExportBunchSize, FrameCounter, Frame.ExportBunchSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.MustBeMappedGuidsCount, FrameCounter, Frame.MustBeMappedGuidCount / 8);
                InMainWindow.AddChartPoint(SeriesType.MustBeMappedGuidsSize, FrameCounter, Frame.MustBeMappedGuidSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.SendAckCount, FrameCounter, Frame.SendAckCount);
                InMainWindow.AddChartPoint(SeriesType.SendAckCountSec, FrameCounter, Frame.SendAckCount * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.SendAckSize, FrameCounter, Frame.SendAckSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.SendAckSizeSec, FrameCounter, Frame.SendAckSizeBits / 8 * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.ContentBlockHeaderSize, FrameCounter, Frame.ContentBlockHeaderSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.ContentBlockFooterSize, FrameCounter, Frame.ContentBlockFooterSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.PropertyHandleSize, FrameCounter, Frame.PropertyHandleSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.SendBunchCount, FrameCounter, Frame.SendBunchCount);
                InMainWindow.AddChartPoint(SeriesType.SendBunchCountSec, FrameCounter, Frame.SendBunchCount * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.SendBunchSize, FrameCounter, Frame.SendBunchSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.SendBunchSizeSec, FrameCounter, Frame.SendBunchSizeBits / 8 * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.SendBunchHeaderSize, FrameCounter, Frame.SendBunchHeaderSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.GameSocketSendSize, FrameCounter, Frame.UnrealSocketSize);
                InMainWindow.AddChartPoint(SeriesType.GameSocketSendSizeSec, FrameCounter, Frame.UnrealSocketSize * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.GameSocketSendCount, FrameCounter, Frame.UnrealSocketCount);
                InMainWindow.AddChartPoint(SeriesType.GameSocketSendCountSec, FrameCounter, Frame.UnrealSocketCount * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.ActorReplicateTimeInMS, FrameCounter, Frame.ActorReplicateTimeInMS);
#endif

#if false
                InMainWindow.AddChartPoint(SeriesType.MiscSocketSendSize, FrameCounter, Frame.OtherSocketSize);
                InMainWindow.AddChartPoint(SeriesType.MiscSocketSendSizeSec, FrameCounter, Frame.OtherSocketSize * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.MiscSocketSendCount, FrameCounter, Frame.OtherSocketCount);
                InMainWindow.AddChartPoint(SeriesType.MiscSocketSendCountSec, FrameCounter, Frame.OtherSocketCount * OneOverDeltaTime);
#endif

                if (Frame.NumEvents > 0)
                {
                    InMainWindow.AddChartPoint(SeriesType.Events, FrameCounter, 0);
                }

                FrameCounter++;
            }

            //NetworkChart.DataManipulator.FinancialFormula( FinancialFormula.MovingAverage, "30", SeriesType.GameSocketSendSizeSec, SeriesType.GameSocketSendSizeAvgSec );
            NetworkChart.DataManipulator.FinancialFormula(FinancialFormula.MovingAverage, "30", SeriesType.OutgoingBandwidthSizeSec.ToString(), SeriesType.OutgoingBandwidthSizeAvgSec.ToString());

            NetworkChart.ChartAreas["DefaultChartArea"].RecalculateAxesScale();

            NetworkChart.ChartAreas["DefaultChartArea"].AxisX.ScaleView.Position = OldPosition;

            NetworkChart.EndInit();

            InMainWindow.ShowProgress(false);

            Console.WriteLine("Adding data to chart took {0} seconds", (DateTime.UtcNow - StartTime).TotalSeconds);
        }
예제 #10
0
        /**
         * Parses passed in data stream into a network stream container class
         *
         * @param	ParserStream	Raw data stream, needs to support seeking
         * @return	NetworkStream data was parsed into
         */
        public static NetworkStream Parse(Stream ParserStream)
        {
            var StartTime = DateTime.UtcNow;

            // Network stream the file is parsed into.
            NetworkStream NetworkStream = new NetworkStream();

            // Serialize the header. This will also return an endian-appropriate binary reader to
            // be used for reading the data.
            BinaryReader BinaryStream = null;
            var          Header       = StreamHeader.ReadHeader(ParserStream, out BinaryStream);

            // Keep track of token stream offset as name table is at end of file.
            long TokenStreamOffset = ParserStream.Position;

            // Seek to name table and serialize it.
            ParserStream.Seek(Header.NameTableOffset, SeekOrigin.Begin);
            for (int NameIndex = 0; NameIndex < Header.NameTableEntries; NameIndex++)
            {
                UInt32 Length = BinaryStream.ReadUInt32();
                NetworkStream.NameArray.Add(new string(BinaryStream.ReadChars((int)Length)));

                // Find "Unreal" name index used for misc socket parsing optimizations.
                if (NetworkStream.NameArray[NameIndex] == "Unreal")
                {
                    NetworkStream.NameIndexUnreal = NameIndex;
                }
            }

            // Seek to beginning of token stream.
            ParserStream.Seek(TokenStreamOffset, SeekOrigin.Begin);

            // Scratch variables used for building stream. Required as we emit information in reverse
            // order needed for parsing.
            var CurrentFrameTokens = new List <TokenBase>();
            TokenReplicateActor             LastActorToken      = null;
            List <TokenReplicateProperty>   LastProperties      = new List <TokenReplicateProperty>();
            List <TokenWritePropertyHeader> LastPropertyHeaders = new List <TokenWritePropertyHeader>();

            TokenFrameMarker LastFrameMarker = null;

            // Parse stream till we reach the end, marked by special token.
            bool bHasReachedEndOfStream = false;

            while (bHasReachedEndOfStream == false)
            {
                TokenBase Token = TokenBase.ReadNextToken(BinaryStream, NetworkStream);

                // Convert current tokens to frame if we reach a frame boundary or the end of the stream.
                if (((Token.TokenType == ETokenTypes.FrameMarker) || (Token.TokenType == ETokenTypes.EndOfStreamMarker))
                    // Nothing to do if we don't have any tokens, e.g. first frame.
                    && (CurrentFrameTokens.Count > 0))
                {
                    // Figure out delta time of previous frame. Needed as partial network stream lacks relative
                    // information for last frame. We assume 30Hz for last frame and for the first frame in case
                    // we receive network traffic before the first frame marker.
                    float DeltaTime = 1 / 30.0f;
                    if (Token.TokenType == ETokenTypes.FrameMarker && LastFrameMarker != null)
                    {
                        DeltaTime = ((TokenFrameMarker)Token).RelativeTime - LastFrameMarker.RelativeTime;
                    }

                    // Create per frame partial stream and add it to the full stream.
                    var FrameStream = new PartialNetworkStream(CurrentFrameTokens, NetworkStream.NameIndexUnreal, DeltaTime);
                    NetworkStream.Frames.Add(FrameStream);
                    CurrentFrameTokens.Clear();

                    Debug.Assert(LastProperties.Count == 0);                            // We shouldn't have any properties now
                    Debug.Assert(LastPropertyHeaders.Count == 0);                       // We shouldn't have any property headers now either

                    // Finish up actor summary of last pending actor before switching frames.
                    HandleActorSummary(NetworkStream, LastActorToken);
                    LastActorToken = null;
                }
                // Keep track of last frame marker.
                if (Token.TokenType == ETokenTypes.FrameMarker)
                {
                    LastFrameMarker = (TokenFrameMarker)Token;
                }

                // Bail out if we hit the end. We already flushed tokens above.
                if (Token.TokenType == ETokenTypes.EndOfStreamMarker)
                {
                    Debug.Assert(LastProperties.Count == 0);                            // We shouldn't have any properties now
                    Debug.Assert(LastPropertyHeaders.Count == 0);                       // We shouldn't have any property headers now either
                    bHasReachedEndOfStream = true;
                    // Finish up actor summary of last pending actor at end of stream
                    HandleActorSummary(NetworkStream, LastActorToken);
                }
                // Keep track of per frame tokens.
                else
                {
                    // Keep track of last actor context for property replication.
                    if (Token.TokenType == ETokenTypes.ReplicateActor)
                    {
                        // Encountered a new actor so we can finish up existing one for summary.
                        FinishActorProperties(Token as TokenReplicateActor, LastProperties, LastPropertyHeaders);
                        Debug.Assert(LastProperties.Count == 0);                                // We shouldn't have any properties now
                        Debug.Assert(LastPropertyHeaders.Count == 0);                           // We shouldn't have any property headers now either
                        HandleActorSummary(NetworkStream, LastActorToken);
                        LastActorToken = Token as TokenReplicateActor;
                    }
                    // Keep track of RPC summary
                    else if (Token.TokenType == ETokenTypes.SendRPC)
                    {
                        var TokenSendRPC = Token as TokenSendRPC;
                        NetworkStream.UpdateSummary(ref NetworkStream.RPCNameToSummary, TokenSendRPC.FunctionNameIndex, TokenSendRPC.GetNumTotalBits(), 0.0f);
                    }

                    // Add properties to the actor token instead of network stream and keep track of summary.
                    if (Token.TokenType == ETokenTypes.ReplicateProperty)
                    {
                        var TokenReplicateProperty = Token as TokenReplicateProperty;
                        NetworkStream.UpdateSummary(ref NetworkStream.PropertyNameToSummary, TokenReplicateProperty.PropertyNameIndex, TokenReplicateProperty.NumBits, 0);
                        //LastActorToken.Properties.Add(TokenReplicateProperty);
                        LastProperties.Add(TokenReplicateProperty);
                    }
                    else if (Token.TokenType == ETokenTypes.WritePropertyHeader)
                    {
                        var TokenWritePropertyHeader = Token as TokenWritePropertyHeader;
                        LastPropertyHeaders.Add(TokenWritePropertyHeader);
                    }
                    else
                    {
                        CurrentFrameTokens.Add(Token);
                    }
                }
            }

            // Stats for profiling.
            double ParseTime = (DateTime.UtcNow - StartTime).TotalSeconds;

            Console.WriteLine("Parsing {0} MBytes in stream took {1} seconds", ParserStream.Length / 1024 / 1024, ParseTime);

            // Empty stream will have 0 frames and proper name table. Shouldn't happen as we only
            // write out stream in engine if there are any events.
            return(NetworkStream);
        }
예제 #11
0
        /**
         * Parses passed in data stream into a network stream container class
         *
         * @param	ParserStream	Raw data stream, needs to support seeking
         * @return	NetworkStream data was parsed into
         */
        public static NetworkStream Parse(MainWindow InMainWindow, Stream ParserStream)
        {
            var StartTime = DateTime.UtcNow;

            // Network stream the file is parsed into.
            NetworkStream = new NetworkStream();

            // Serialize the header. This will also return an endian-appropriate binary reader to
            // be used for reading the data.
            BinaryReader BinaryStream = null;
            var          Header       = StreamHeader.ReadHeader(ParserStream, out BinaryStream);

            // Scratch variables used for building stream. Required as we emit information in reverse
            // order needed for parsing.
            var CurrentFrameTokens = new List <TokenBase>();
            TokenReplicateActor             LastActorToken      = null;
            List <TokenReplicateProperty>   LastProperties      = new List <TokenReplicateProperty>();
            List <TokenWritePropertyHeader> LastPropertyHeaders = new List <TokenWritePropertyHeader>();

            TokenFrameMarker LastFrameMarker = null;

            InMainWindow.ShowProgress(true);

            int Count = 0;

            var AllFrames = new PartialNetworkStream(NetworkStream.NameIndexUnreal, 1.0f / 30.0f);

            int EarlyOutMinutes = InMainWindow.GetMaxProfileMinutes();

            // Parse stream till we reach the end, marked by special token.
            bool bHasReachedEndOfStream = false;

            List <TokenBase> TokenList = new List <TokenBase>();

            float FrameStartTime = -1.0f;
            float FrameEndTime   = -1.0f;

            while (bHasReachedEndOfStream == false)
            {
                if (Count++ % 1000 == 0)
                {
                    float Percent = ( float )ParserStream.Position / ( float )ParserStream.Length;
                    InMainWindow.UpdateProgress(( int )(Percent * 100));
                }

                if (ParserStream.Position == ParserStream.Length)
                {
                    // We reached stream early (must not have been finalized properly, but we can still read it)
                    break;
                }

                TokenBase Token = null;

                try
                {
                    Token = TokenBase.ReadNextToken(BinaryStream, NetworkStream);
                }
                catch (System.IO.EndOfStreamException)
                {
                    // We reached stream early (must not have been finalized properly, but we can still read it)
                    break;
                }

                if (Token.TokenType == ETokenTypes.NameReference)
                {
                    NetworkStream.NameArray.Add((Token as TokenNameReference).Name);

                    // Find "Unreal" name index used for misc socket parsing optimizations.
                    if (NetworkStream.NameArray[NetworkStream.NameArray.Count - 1] == "Unreal")
                    {
                        NetworkStream.NameIndexUnreal = NetworkStream.NameArray.Count - 1;
                    }
                    continue;
                }

                if (Token.TokenType == ETokenTypes.ConnectionReference)
                {
                    NetworkStream.AddressArray.Add((Token as TokenConnectionReference).Address);
                    continue;
                }

                if (Token.TokenType == ETokenTypes.ConnectionChange)
                {
                    // We need to setup CurrentConnectionIndex, since it's used in ReadNextToken
                    NetworkStream.CurrentConnectionIndex = (Token as TokenConnectionChanged).AddressIndex;
                    continue;
                }

                TokenList.Add(Token);

                // Track frame start/end times manually so we can bail out when we hit the amount of time we want to load
                if (Token.TokenType == ETokenTypes.FrameMarker)
                {
                    var TokenFrameMarker = ( TokenFrameMarker )Token;

                    if (FrameStartTime < 0)
                    {
                        FrameStartTime = TokenFrameMarker.RelativeTime;
                        FrameEndTime   = TokenFrameMarker.RelativeTime;
                    }
                    else
                    {
                        FrameEndTime = TokenFrameMarker.RelativeTime;
                    }
                }

                if (EarlyOutMinutes > 0 && ((FrameEndTime - FrameStartTime) > 60 * EarlyOutMinutes))
                {
                    break;
                }
            }

            for (int i = 0; i < TokenList.Count; i++)
            {
                if (i % 1000 == 0)
                {
                    float Percent = ( float )(i + 1) / ( float )(TokenList.Count);
                    InMainWindow.UpdateProgress(( int )(Percent * 100));
                }

                TokenBase Token = TokenList[i];

                // Convert current tokens to frame if we reach a frame boundary or the end of the stream.
                if (((Token.TokenType == ETokenTypes.FrameMarker) || (Token.TokenType == ETokenTypes.EndOfStreamMarker))
                    // Nothing to do if we don't have any tokens, e.g. first frame.
                    && (CurrentFrameTokens.Count > 0))
                {
                    // Figure out delta time of previous frame. Needed as partial network stream lacks relative
                    // information for last frame. We assume 30Hz for last frame and for the first frame in case
                    // we receive network traffic before the first frame marker.
                    float DeltaTime = 1 / 30.0f;
                    if (Token.TokenType == ETokenTypes.FrameMarker && LastFrameMarker != null)
                    {
                        DeltaTime = ((TokenFrameMarker)Token).RelativeTime - LastFrameMarker.RelativeTime;
                    }

                    // Create per frame partial stream and add it to the full stream.
                    var FrameStream = new PartialNetworkStream(CurrentFrameTokens, NetworkStream.NameIndexUnreal, DeltaTime);

                    AllFrames.AddStream(FrameStream);

                    NetworkStream.Frames.Add(FrameStream);
                    CurrentFrameTokens.Clear();

                    Debug.Assert(LastProperties.Count == 0);                            // We shouldn't have any properties now
                    Debug.Assert(LastPropertyHeaders.Count == 0);                       // We shouldn't have any property headers now either

                    // Finish up actor summary of last pending actor before switching frames.
                    HandleActorSummary(NetworkStream, LastActorToken);
                    LastActorToken = null;
                }
                // Keep track of last frame marker.
                if (Token.TokenType == ETokenTypes.FrameMarker)
                {
                    LastFrameMarker = (TokenFrameMarker)Token;
                }

                // Bail out if we hit the end. We already flushed tokens above.
                if (Token.TokenType == ETokenTypes.EndOfStreamMarker)
                {
                    Debug.Assert(LastProperties.Count == 0);                            // We shouldn't have any properties now
                    Debug.Assert(LastPropertyHeaders.Count == 0);                       // We shouldn't have any property headers now either
                    bHasReachedEndOfStream = true;
                    // Finish up actor summary of last pending actor at end of stream
                    HandleActorSummary(NetworkStream, LastActorToken);
                }
                // Keep track of per frame tokens.
                else
                {
                    // Keep track of last actor context for property replication.
                    if (Token.TokenType == ETokenTypes.ReplicateActor)
                    {
                        // Encountered a new actor so we can finish up existing one for summary.
                        FinishActorProperties(Token as TokenReplicateActor, LastProperties, LastPropertyHeaders);
                        Debug.Assert(LastProperties.Count == 0);                                // We shouldn't have any properties now
                        Debug.Assert(LastPropertyHeaders.Count == 0);                           // We shouldn't have any property headers now either
                        HandleActorSummary(NetworkStream, LastActorToken);
                        LastActorToken = Token as TokenReplicateActor;
                    }
                    // Keep track of RPC summary
                    else if (Token.TokenType == ETokenTypes.SendRPC)
                    {
                        var TokenSendRPC = Token as TokenSendRPC;
                        NetworkStream.UpdateSummary(ref NetworkStream.RPCNameToSummary, TokenSendRPC.FunctionNameIndex, TokenSendRPC.GetNumTotalBits(), 0.0f);
                    }

                    // Add properties to the actor token instead of network stream and keep track of summary.
                    if (Token.TokenType == ETokenTypes.ReplicateProperty)
                    {
                        var TokenReplicateProperty = Token as TokenReplicateProperty;
                        NetworkStream.UpdateSummary(ref NetworkStream.PropertyNameToSummary, TokenReplicateProperty.PropertyNameIndex, TokenReplicateProperty.NumBits, 0);
                        //LastActorToken.Properties.Add(TokenReplicateProperty);
                        LastProperties.Add(TokenReplicateProperty);
                    }
                    else if (Token.TokenType == ETokenTypes.WritePropertyHeader)
                    {
                        var TokenWritePropertyHeader = Token as TokenWritePropertyHeader;
                        LastPropertyHeaders.Add(TokenWritePropertyHeader);
                    }
                    else
                    {
                        CurrentFrameTokens.Add(Token);
                    }
                }
            }

            InMainWindow.SetCurrentStreamSelection(NetworkStream, AllFrames, false);

            InMainWindow.ShowProgress(false);

            // Stats for profiling.
            double ParseTime = (DateTime.UtcNow - StartTime).TotalSeconds;

            Console.WriteLine("Parsing {0} MBytes in stream took {1} seconds", ParserStream.Length / 1024 / 1024, ParseTime);

            // Empty stream will have 0 frames and proper name table. Shouldn't happen as we only
            // write out stream in engine if there are any events.
            return(NetworkStream);
        }
예제 #12
0
        public static void ParseStreamIntoChart(MainWindow InMainWindow, NetworkStream InStream, WpfPlot NetworkChart, FilterValues InFilterValues)
        {
            var StartTime = DateTime.UtcNow;

            InMainWindow.ShowProgress(true);
            NetworkChart.Plot.Clear();

            for (int i = 0; i < InMainWindow.DefaultSeriesTypes.Count; i++)
            {
                float Percent = (float)i / (float)InMainWindow.DefaultSeriesTypes.Count;
                InMainWindow.UpdateProgress((int)(Percent * 100));
                InMainWindow.DefaultSeriesTypes[i].Reset();
            }

            int FrameCounter = 0;

            foreach (PartialNetworkStream RawFrame in InStream.Frames)
            {
                if (FrameCounter % 1000 == 0)
                {
                    float Percent = (float)FrameCounter / (float)InStream.Frames.Count;
                    InMainWindow.UpdateProgress((int)(Percent * 100));
                }

                PartialNetworkStream Frame = RawFrame.Filter(InFilterValues);
                if (Frame.EndTime == Frame.StartTime)
                {
                    throw new InvalidOperationException("End time and Start time cannot be same.");
                }

                float OneOverDeltaTime  = 1 / (Frame.EndTime - Frame.StartTime);
                int   OutgoingBandwidth = Frame.UnrealSocketSize + Frame.OtherSocketSize + NetworkStream.PacketOverhead * (Frame.UnrealSocketCount + Frame.OtherSocketCount);

                InMainWindow.AddChartPoint(SeriesType.OutgoingBandwidthSize, FrameCounter, OutgoingBandwidth);
                InMainWindow.AddChartPoint(SeriesType.OutgoingBandwidthSizeSec, FrameCounter, OutgoingBandwidth * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.ActorCount, FrameCounter, Frame.ActorCount);
                InMainWindow.AddChartPoint(SeriesType.PropertySize, FrameCounter, Frame.ReplicatedSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.PropertySizeSec, FrameCounter, Frame.ReplicatedSizeBits / 8 * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.RPCSize, FrameCounter, Frame.RPCSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.RPCSizeSec, FrameCounter, Frame.RPCSizeBits / 8 * OneOverDeltaTime);

#if true
                InMainWindow.AddChartPoint(SeriesType.ActorCountSec, FrameCounter, Frame.ActorCount * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.PropertyCount, FrameCounter, Frame.PropertyCount);
                InMainWindow.AddChartPoint(SeriesType.PropertyCountSec, FrameCounter, Frame.PropertyCount * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.RPCCount, FrameCounter, Frame.RPCCount);
                InMainWindow.AddChartPoint(SeriesType.RPCCountSec, FrameCounter, Frame.RPCCount * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.ExportBunchCount, FrameCounter, Frame.ExportBunchCount);
                InMainWindow.AddChartPoint(SeriesType.ExportBunchSize, FrameCounter, Frame.ExportBunchSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.MustBeMappedGuidsCount, FrameCounter, Frame.MustBeMappedGuidCount / 8);
                InMainWindow.AddChartPoint(SeriesType.MustBeMappedGuidsSize, FrameCounter, Frame.MustBeMappedGuidSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.SendAckCount, FrameCounter, Frame.SendAckCount);
                InMainWindow.AddChartPoint(SeriesType.SendAckCountSec, FrameCounter, Frame.SendAckCount * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.SendAckSize, FrameCounter, Frame.SendAckSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.SendAckSizeSec, FrameCounter, Frame.SendAckSizeBits / 8 * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.ContentBlockHeaderSize, FrameCounter, Frame.ContentBlockHeaderSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.ContentBlockFooterSize, FrameCounter, Frame.ContentBlockFooterSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.PropertyHandleSize, FrameCounter, Frame.PropertyHandleSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.SendBunchCount, FrameCounter, Frame.SendBunchCount);
                InMainWindow.AddChartPoint(SeriesType.SendBunchCountSec, FrameCounter, Frame.SendBunchCount * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.SendBunchSize, FrameCounter, Frame.SendBunchSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.SendBunchSizeSec, FrameCounter, Frame.SendBunchSizeBits / 8 * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.SendBunchHeaderSize, FrameCounter, Frame.SendBunchHeaderSizeBits / 8);
                InMainWindow.AddChartPoint(SeriesType.GameSocketSendSize, FrameCounter, Frame.UnrealSocketSize);
                InMainWindow.AddChartPoint(SeriesType.GameSocketSendSizeSec, FrameCounter, Frame.UnrealSocketSize * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.GameSocketSendCount, FrameCounter, Frame.UnrealSocketCount);
                InMainWindow.AddChartPoint(SeriesType.GameSocketSendCountSec, FrameCounter, Frame.UnrealSocketCount * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.ActorReplicateTimeInMS, FrameCounter, Frame.ActorReplicateTimeInMS);
#endif

#if false
                InMainWindow.AddChartPoint(SeriesType.MiscSocketSendSize, FrameCounter, Frame.OtherSocketSize);
                InMainWindow.AddChartPoint(SeriesType.MiscSocketSendSizeSec, FrameCounter, Frame.OtherSocketSize * OneOverDeltaTime);
                InMainWindow.AddChartPoint(SeriesType.MiscSocketSendCount, FrameCounter, Frame.OtherSocketCount);
                InMainWindow.AddChartPoint(SeriesType.MiscSocketSendCountSec, FrameCounter, Frame.OtherSocketCount * OneOverDeltaTime);
#endif

                if (Frame.NumEvents > 0)
                {
                    InMainWindow.AddChartPoint(SeriesType.Events, FrameCounter, 0);
                }

                FrameCounter++;
            }

            InMainWindow.ShowProgress(false);
            Console.WriteLine("Adding data to chart took {0} seconds", (DateTime.UtcNow - StartTime).TotalSeconds);
            InMainWindow.Dispatcher.Invoke(new Action(() => InMainWindow.UpdateNetworkChart()));
        }