public void Tick() { if (!IsReadyForNextFrame) { throw new InvalidOperationException(); } if (GameSaveLastFrame < NetFrameNumber + FramesAhead) { Connection.Send(NetFrameNumber + FramesAhead, localOrders.Select(o => o.Serialize()).ToList()); } localOrders.Clear(); foreach (var order in frameData.OrdersForFrame(World, NetFrameNumber)) { UnitOrders.ProcessOrder(this, World, order.Client, order.Order); } if (NetFrameNumber + FramesAhead >= GameSaveLastSyncFrame) { Connection.SendSync(NetFrameNumber, OrderIO.SerializeSync(World.SyncHash())); } else { Connection.SendSync(NetFrameNumber, OrderIO.SerializeSync(0)); } if (generateSyncReport) { using (new PerfSample("sync_report")) syncReport.UpdateSyncReport(); } ++NetFrameNumber; }
public void Tick() { if (!IsReadyForNextFrame) { throw new InvalidOperationException(); } Connection.Send(NetFrameNumber + FramesAhead, localOrders.Select(o => o.Serialize()).ToList()); localOrders.Clear(); foreach (var order in frameData.OrdersForFrame(World, NetFrameNumber)) { UnitOrders.ProcessOrder(this, World, order.Client, order.Order); } Connection.SendSync(NetFrameNumber, OrderIO.SerializeSync(World.SyncHash())); if (generateSyncReport) { syncReport.UpdateSyncReport(); } ++NetFrameNumber; }
public void Tick() { if (!IsReadyForNextFrame) { throw new InvalidOperationException(); } if (GameSaveLastFrame < NetFrameNumber + FramesAhead) { Connection.Send(NetFrameNumber + FramesAhead, localOrders.Select(o => o.Serialize()).ToList()); } localOrders.Clear(); var clientOrders = new List <ClientOrder>(); foreach (var(clientId, clientPackets) in pendingPackets) { // The IsReadyForNextFrame check above guarantees that all clients have sent a packet var frameData = clientPackets.Dequeue(); // Orders are synchronised by sending an initial FramesAhead set of empty packets // and then making sure that we enqueue and process exactly one packet for each player each tick. // This may change in the future, so sanity check that the orders are for the frame we expect // and crash early instead of risking desyncs. var frameNumber = BitConverter.ToInt32(frameData, 0); if (frameNumber != NetFrameNumber) { throw new InvalidDataException($"Attempted to process orders from client {clientId} for frame {frameNumber} on frame {NetFrameNumber}"); } foreach (var order in frameData.ToOrderList(World)) { UnitOrders.ProcessOrder(this, World, clientId, order); clientOrders.Add(new ClientOrder { Client = clientId, Order = order }); } } if (NetFrameNumber + FramesAhead >= GameSaveLastSyncFrame) { var defeatState = 0UL; for (var i = 0; i < World.Players.Length; i++) { if (World.Players[i].WinState == WinState.Lost) { defeatState |= 1UL << i; } } Connection.SendSync(NetFrameNumber, OrderIO.SerializeSync(World.SyncHash(), defeatState)); } else { Connection.SendSync(NetFrameNumber, OrderIO.SerializeSync(0, 0)); } if (generateSyncReport) { using (new PerfSample("sync_report")) syncReport.UpdateSyncReport(clientOrders); } ++NetFrameNumber; }