/// <summary> /// /// </summary> /// <param name="frameId"></param> /// <param name="prevFrameId"></param> /// <param name="snapshot"></param> /// <returns></returns> public byte[] Decompress(uint prevFrameId, byte[] snapshot) { #if DONT_USE_DELTA return(NetworkEngine.Decompress(snapshot)); #endif if (prevFrameId == 0) { return(NetDeflate.Decompress(snapshot)); } var prevSnapshot = queue.SingleOrDefault(s => s.Frame == prevFrameId); if (prevSnapshot == null) { Log.Warning("Missing snapshot #{0}. Waiting for full snapshot.", prevFrameId); return(null); } var delta = NetDeflate.Decompress(snapshot); var minSize = Math.Min(delta.Length, prevSnapshot.Data.Length); var newSnapshot = new byte[delta.Length]; for (int i = 0; i < minSize; i++) { newSnapshot[i] = (byte)(delta[i] ^ prevSnapshot.Data[i]); } if (delta.Length > prevSnapshot.Data.Length) { for (int i = minSize; i < delta.Length; i++) { newSnapshot[i] = delta[i]; } } return(newSnapshot); }
/// <summary> /// /// </summary> /// <param name="prevFrame"></param> /// <returns></returns> 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)); }
public override void DataReceived(NetCommand command, NetIncomingMessage msg) { if (command == NetCommand.Snapshot) { var frame = msg.ReadUInt32(); var prevFrame = msg.ReadUInt32(); var ackCmdID = msg.ReadUInt32(); var serverTicks = msg.ReadInt64(); var size = msg.ReadInt32(); //Log.Warning("{0}", offsetTicks ); if (prevFrame != 0) { Log.Warning("Bad initial snapshot. Previous frame does not equal zero."); return; } if (ackCmdID != 0) { Log.Warning("Bad command ID {0}. Command ID for initial snapshot must be zero.", ackCmdID); return; } // read snapshot : var snapshot = NetDeflate.Decompress(msg.ReadBytes(size)); // initial snapshot contains atom table : context.Instance.FeedAtoms(new AtomCollection(msg)); gameClient.SetState(new Active(context, frame, snapshot, serverTicks)); } if (command == NetCommand.Notification) { context.Instance.FeedNotification(msg.ReadString()); } }