/// <summary> /// /// </summary> /// <param name="server"></param> void DispatchSnapshots(NetServer server, long serverTicks) { // snapshot request is stored in connection's tag.s var debug = game.Network.ShowSnapshots; var conns = server.Connections.ToArray(); var sw = new Stopwatch(); foreach (var conn in conns) { var state = conn.GetState(); if (state == null) { continue; } if (!state.IsSnapshotRequested) { return; } sw.Reset(); sw.Start(); var guid = state.ClientGuid; var queue = state.SnapshotQueue; queue.Push(serverInstance.MakeSnapshot(guid)); var snapID = queue.LatestSnapshotID; var ackSnapID = state.AckSnapshotID; int size = 0; var commandID = state.LastCommandID; var snapshot = queue.Compress(ref ackSnapID, out size); // reset snapshot request : state.IsSnapshotRequested = false; var msg = server.CreateMessage(snapshot.Length + 4 * 4 + 8 + 1); msg.Write((byte)NetCommand.Snapshot); msg.Write(snapID); msg.Write(ackSnapID); msg.Write(commandID); msg.Write(serverTicks); msg.Write(snapshot.Length); msg.Write(snapshot); // append atom table to first snapshot : if (commandID == 0) { serverInstance.Atoms.Write(msg); } // Zero snapshot frame index means that client is waiting for first snapshot. // and snapshot should reach the client. var delivery = ackSnapID == 0 ? NetDeliveryMethod.ReliableOrdered : NetDeliveryMethod.UnreliableSequenced; if (ackSnapID == 0) { Log.Message("SV: Sending initial snapshot to {0}", conn.PeekHailGuid().ToString()); } sw.Stop(); server.SendMessage(msg, conn, delivery, 0); if (debug) { Log.Message("Snapshot: #{0} - #{1} : {2} / {3} to {4} at {5} msec", snapID, ackSnapID, snapshot.Length, size, conn.RemoteEndPoint.ToString(), sw.Elapsed.TotalMilliseconds); } } }