Fusion.Engine.Server.SnapshotQueue.Compress C# (CSharp) Method

Compress() public method

public Compress ( uint &prevFrame, int &size ) : byte[]
prevFrame uint
size int
return byte[]
		public byte[] Compress ( ref uint prevFrame, out int size )
		{
			#if DONT_USE_DELTA
				size = queue.Last().Data.Length;
				return NetworkEngine.Compress( queue.Last().Data );
			#endif

			var lastSnapshot	=	queue.Last();
				size			=	lastSnapshot.Data.Length;

			var prevFrameLocal	=	prevFrame;

			var prevSnapshot	=	queue.SingleOrDefault( s => s.Frame == prevFrameLocal );

			if (prevSnapshot==null) {
				prevFrame = 0;
				return NetDeflate.Compress( lastSnapshot.Data );
			}


			var delta	=	new byte[lastSnapshot.Data.Length];
			var minSize	=	Math.Min( delta.Length, prevSnapshot.Data.Length );

			for (int i=0; i<minSize; i++ ) {
				delta[i] = (byte)(lastSnapshot.Data[i] ^ prevSnapshot.Data[i]);
			}

			if (delta.Length > prevSnapshot.Data.Length) {
				for (int i=minSize; i<delta.Length; i++) {
					delta[i] = lastSnapshot.Data[i];
				}
			}

			return NetDeflate.Compress( delta );
		}

Usage Example

		/// <summary>
		/// 
		/// </summary>
		/// <param name="server"></param>
		void SendSnapshot ( NetServer server, SnapshotQueue queue, long serverTicks )
		{
			//	snapshot request is stored in connection's tag.s
			var debug	=	Game.Network.ShowSnapshots;
			var conns	=	server.Connections.Where ( c => c.IsSnapshotRequested() );

			var sw		=	new Stopwatch();

			foreach ( var conn in conns ) {

				sw.Reset();
				sw.Start();
					
				var frame		=	queue.LastFrame;
				var prevFrame	=	conn.GetRequestedSnapshotID();
				int size		=	0;
				var commandID	=	conn.GetLastCommandID();
				var snapshot	=	queue.Compress( ref prevFrame, out size);

				//	reset snapshot request :
				conn.ResetRequestSnapshot();

				var msg = server.CreateMessage( snapshot.Length + 4 * 4 + 8 + 1 );
			
				msg.Write( (byte)NetCommand.Snapshot );
				msg.Write( frame );
				msg.Write( prevFrame );
				msg.Write( commandID );
				msg.Write( serverTicks );
				msg.Write( snapshot.Length );
				msg.Write( snapshot ); 

				//	append atom table to first snapshot :
				if (commandID==0) {
					atoms.Write( msg );
				}

				//	Zero snapshot frame index means that client is waiting for first snapshot.
				//	and snapshot should reach the client.
				var delivery	=	prevFrame == 0 ? NetDeliveryMethod.ReliableOrdered : NetDeliveryMethod.UnreliableSequenced;

				if (prevFrame==0) {
					Log.Message("SV: Sending initial snapshot to {0}", conn.GetHailGuid().ToString() );
				}

				sw.Stop();

				server.SendMessage( msg, conn, delivery, 0 );

				if (debug) {
					Log.Message("Snapshot: #{0} - #{1} : {2} / {3} to {4} at {5} msec", 
						frame, prevFrame, snapshot.Length, size, conn.RemoteEndPoint.ToString(), sw.Elapsed.TotalMilliseconds );
				}
			}
		}