/** * Helper function for handling updating actor summaries as they require a bit more work. * * @param NetworkStream NetworkStream associated with token * @param TokenReplicateActor Actor token */ private static void HandleActorSummary(NetworkStream NetworkStream, TokenReplicateActor TokenReplicateActor ) { if ( TokenReplicateActor != null ) { int ClassNameIndex = NetworkStream.GetClassNameIndex(TokenReplicateActor.ActorNameIndex); NetworkStream.UpdateSummary(ref NetworkStream.ActorNameToSummary, ClassNameIndex, TokenReplicateActor.GetNumReplicatedBits( new FilterValues() ), TokenReplicateActor.TimeInMS ); } }
/** * Reads the next token from the stream and returns it. * * @param BinaryStream Stream used to serialize from * @param InNetworkStream Network stream this token belongs to * @return Token serialized */ public static TokenBase ReadNextToken(BinaryReader BinaryStream, NetworkStream InNetworkStream) { TokenBase SerializedToken = null; ETokenTypes TokenType = (ETokenTypes) BinaryStream.ReadByte(); // Handle token specific serialization. switch( TokenType ) { case ETokenTypes.FrameMarker: SerializedToken = new TokenFrameMarker( BinaryStream ); break; case ETokenTypes.SocketSendTo: SerializedToken = new TokenSocketSendTo( BinaryStream ); break; case ETokenTypes.SendBunch: SerializedToken = new TokenSendBunch( BinaryStream ); break; case ETokenTypes.SendRPC: SerializedToken = new TokenSendRPC( BinaryStream ); break; case ETokenTypes.ReplicateActor: SerializedToken = new TokenReplicateActor( BinaryStream ); break; case ETokenTypes.ReplicateProperty: SerializedToken = new TokenReplicateProperty( BinaryStream ); break; case ETokenTypes.EndOfStreamMarker: SerializedToken = new TokenEndOfStreamMarker(); break; case ETokenTypes.Event: SerializedToken = new TokenEvent( BinaryStream ); break; case ETokenTypes.RawSocketData: SerializedToken = new TokenRawSocketData( BinaryStream ); break; default: throw new InvalidDataException(); } TokenTypeStats[(int)TokenType]++; SerializedToken.NetworkStream = InNetworkStream; SerializedToken.TokenType = TokenType; return SerializedToken; }
/** * 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 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; }
/** * Parses summaries into a list view using the network stream for name lookup. * * @param NetworkStream Network stream used for name lookup * @param Summaries Summaries to parse into listview * @param ListView List view to parse data into */ public static void ParseStreamIntoListView( NetworkStream NetworkStream, Dictionary<int,TypeSummary> Summaries, ListView ListView ) { ListView.BeginUpdate(); ListView.Items.Clear(); // Columns are total size KByte, count, avg size in bytes, avg size in bits and associated name. var Columns = new string[6]; foreach( var SummaryEntry in Summaries ) { Columns[0] = ((float)SummaryEntry.Value.SizeBits / 8 / 1024).ToString("0.0"); Columns[1] = SummaryEntry.Value.Count.ToString(); Columns[2] = ((float)SummaryEntry.Value.SizeBits / 8 / SummaryEntry.Value.Count).ToString("0.0"); Columns[3] = ((float)SummaryEntry.Value.SizeBits / SummaryEntry.Value.Count).ToString("0.0"); Columns[4] = SummaryEntry.Value.TimeInMS.ToString("0.00"); Columns[5] = NetworkStream.GetName(SummaryEntry.Key); ListView.Items.Add(new ListViewItem(Columns)); } ListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); ListView.EndUpdate(); }
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(); 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["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["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); }
private void ChangeNetworkStream( Stream ParserStream ) { try { CurrentNetworkStream = StreamParser.Parse(ParserStream); StreamParser.ParseStreamIntoListView(CurrentNetworkStream,CurrentNetworkStream.ActorNameToSummary,ActorListView); StreamParser.ParseStreamIntoListView(CurrentNetworkStream,CurrentNetworkStream.PropertyNameToSummary,PropertyListView); StreamParser.ParseStreamIntoListView(CurrentNetworkStream,CurrentNetworkStream.RPCNameToSummary,RPCListView); ChartParser.ParseStreamIntoChart( CurrentNetworkStream, NetworkChart, CurrentActorFilter, CurrentPropertyFilter, CurrentRPCFilter ); } catch (System.Exception) { CurrentNetworkStream = null; foreach( var Series in NetworkChart.Series ) { Series.Points.Clear(); } } }
public void SetCurrentStreamSelection( NetworkStream NetworkStream, PartialNetworkStream Selection, bool bSingleSelect ) { if ( this.InvokeRequired ) { this.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.Nodes, CurrentFilterValues ); } CurrentStreamSelection = Selection; }
/** * 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>(); 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 // 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 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 ); Debug.Assert(LastProperties.Count == 0); // We shouldn't have any properties now 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.NumBits, 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 { 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; }
public void ClearStreamAndChart() { if ( this.InvokeRequired ) { this.Invoke( new Action( () => ClearStreamAndChart() ) ); return; } CurrentNetworkStream = null; foreach ( var Series in NetworkChart.Series ) { Series.Points.Clear(); } }
private void ChangeNetworkStreamWorker( string Filename ) { using ( var ParserStream = File.OpenRead( Filename ) ) { try { CurrentNetworkStream = StreamParser.Parse( this, ParserStream ); ParseStreamForListViews(); ChartParser.ParseStreamIntoChart( this, CurrentNetworkStream, NetworkChart, CurrentFilterValues ); } catch ( System.Threading.ThreadAbortException ) { } catch ( System.Exception ) { ClearStreamAndChart(); } } LoadThread = null; }
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); }
/** * Reads the next token from the stream and returns it. * * @param BinaryStream Stream used to serialize from * @param InNetworkStream Network stream this token belongs to * @return Token serialized */ public static TokenBase ReadNextToken(BinaryReader BinaryStream, NetworkStream InNetworkStream) { TokenBase SerializedToken = null; ETokenTypes TokenType = (ETokenTypes) BinaryStream.ReadByte(); // Handle token specific serialization. switch( TokenType ) { case ETokenTypes.FrameMarker: SerializedToken = new TokenFrameMarker( BinaryStream ); break; case ETokenTypes.SocketSendTo: SerializedToken = new TokenSocketSendTo( BinaryStream ); break; case ETokenTypes.SendBunch: SerializedToken = new TokenSendBunch( BinaryStream ); break; case ETokenTypes.SendRPC: SerializedToken = new TokenSendRPC( BinaryStream ); break; case ETokenTypes.ReplicateActor: SerializedToken = new TokenReplicateActor( BinaryStream ); break; case ETokenTypes.ReplicateProperty: SerializedToken = new TokenReplicateProperty( BinaryStream ); break; case ETokenTypes.EndOfStreamMarker: SerializedToken = new TokenEndOfStreamMarker(); break; case ETokenTypes.Event: SerializedToken = new TokenEvent( BinaryStream ); break; case ETokenTypes.RawSocketData: SerializedToken = new TokenRawSocketData( BinaryStream ); break; case ETokenTypes.SendAck: SerializedToken = new TokenSendAck( BinaryStream ); break; case ETokenTypes.WritePropertyHeader: SerializedToken = new TokenWritePropertyHeader( BinaryStream ); break; case ETokenTypes.ExportBunch: SerializedToken = new TokenExportBunch( BinaryStream ); break; case ETokenTypes.MustBeMappedGuids: SerializedToken = new TokenMustBeMappedGuids( BinaryStream ); break; case ETokenTypes.BeginContentBlock: SerializedToken = new TokenBeginContentBlock( BinaryStream ); break; case ETokenTypes.EndContentBlock: SerializedToken = new TokenEndContentBlock( BinaryStream ); break; case ETokenTypes.WritePropertyHandle: SerializedToken = new TokenWritePropertyHandle( BinaryStream ); break; case ETokenTypes.NameReference: SerializedToken = new TokenNameReference( BinaryStream ); break; case ETokenTypes.ConnectionReference: SerializedToken = new TokenConnectionReference( BinaryStream ); break; case ETokenTypes.ConnectionChange: SerializedToken = new TokenConnectionChanged( BinaryStream ); break; default: throw new InvalidDataException(); } TokenTypeStats[(int)TokenType]++; SerializedToken.NetworkStream = InNetworkStream; SerializedToken.TokenType = TokenType; SerializedToken.ConnectionIndex = InNetworkStream.CurrentConnectionIndex; return SerializedToken; }
/** * Reads the next token from the stream and returns it. * * @param BinaryStream Stream used to serialize from * @param InNetworkStream Network stream this token belongs to * @return Token serialized */ public static TokenBase ReadNextToken(BinaryReader BinaryStream, NetworkStream InNetworkStream) { TokenBase SerializedToken = null; ETokenTypes TokenType = (ETokenTypes)BinaryStream.ReadByte(); // Handle token specific serialization. switch (TokenType) { case ETokenTypes.FrameMarker: SerializedToken = new TokenFrameMarker(BinaryStream); break; case ETokenTypes.SocketSendTo: SerializedToken = new TokenSocketSendTo(BinaryStream); break; case ETokenTypes.SendBunch: SerializedToken = new TokenSendBunch(BinaryStream); break; case ETokenTypes.SendRPC: SerializedToken = new TokenSendRPC(BinaryStream); break; case ETokenTypes.ReplicateActor: SerializedToken = new TokenReplicateActor(BinaryStream); break; case ETokenTypes.ReplicateProperty: SerializedToken = new TokenReplicateProperty(BinaryStream); break; case ETokenTypes.EndOfStreamMarker: SerializedToken = new TokenEndOfStreamMarker(); break; case ETokenTypes.Event: SerializedToken = new TokenEvent(BinaryStream); break; case ETokenTypes.RawSocketData: SerializedToken = new TokenRawSocketData(BinaryStream); break; case ETokenTypes.SendAck: SerializedToken = new TokenSendAck(BinaryStream); break; case ETokenTypes.WritePropertyHeader: SerializedToken = new TokenWritePropertyHeader(BinaryStream); break; case ETokenTypes.ExportBunch: SerializedToken = new TokenExportBunch(BinaryStream); break; case ETokenTypes.MustBeMappedGuids: SerializedToken = new TokenMustBeMappedGuids(BinaryStream); break; case ETokenTypes.BeginContentBlock: SerializedToken = new TokenBeginContentBlock(BinaryStream); break; case ETokenTypes.EndContentBlock: SerializedToken = new TokenEndContentBlock(BinaryStream); break; case ETokenTypes.WritePropertyHandle: SerializedToken = new TokenWritePropertyHandle(BinaryStream); break; case ETokenTypes.NameReference: SerializedToken = new TokenNameReference(BinaryStream); break; case ETokenTypes.ConnectionReference: SerializedToken = new TokenConnectionReference(BinaryStream); break; case ETokenTypes.ConnectionChange: SerializedToken = new TokenConnectionChanged(BinaryStream); break; default: throw new InvalidDataException(); } TokenTypeStats[(int)TokenType]++; SerializedToken.TokenType = TokenType; SerializedToken.ConnectionIndex = InNetworkStream.CurrentConnectionIndex; return(SerializedToken); }