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;
        }
Exemple #2
0
        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;
        }
Exemple #3
0
        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;
        }