Esempio n. 1
0
        public override GGPOErrorCode Idle(int timeout)
        {
            if (sync.InRollback)
            {
                return(GGPOErrorCode.OK);
            }

            poll.Pump(0);
            PollUdpProtocolEvents();

            if (isSynchronizing)
            {
                return(GGPOErrorCode.OK);
            }

            sync.CheckSimulation(timeout);

            // notify all of our endpoints of their local frame number for their
            // next connection quality report
            for (int i = 0; i < numPlayers; i++)
            {
                endpoints[i].SetLocalFrameNumber(sync.FrameCount);
            }

            int lastConfirmedFrame;

            if (numPlayers <= 2)
            {
                lastConfirmedFrame = Poll2Players(sync.FrameCount);
            }
            else
            {
                lastConfirmedFrame = PollNPlayers(sync.FrameCount);
            }

            Log($"last confirmed frame in p2p backend is {lastConfirmedFrame}.");

            if (lastConfirmedFrame >= 0)
            {
                Debug.Assert(lastConfirmedFrame != int.MaxValue);
                if (numSpectators > 0)
                {
                    while (nextSpectatorFrame <= lastConfirmedFrame)
                    {
                        Log($"pushing frame {nextSpectatorFrame} to spectators.");

                        var input = new GameInput
                        {
                            frame = nextSpectatorFrame,
                            size  = (uint)(inputSize * numPlayers),
                        };
                        sync.GetConfirmedInputs(input.bits, nextSpectatorFrame);

                        for (int i = 0; i < numSpectators; i++)
                        {
                            spectators[i].SendInput(ref input);
                        }
                        nextSpectatorFrame++;
                    }
                }

                Log($"setting confirmed frame in sync to {lastConfirmedFrame}.");
                sync.SetLastConfirmedFrame(lastConfirmedFrame);
            }

            // Send timesync notifications if now is the proper time
            if (sync.FrameCount > nextRecommendedSleep)
            {
                int interval = 0;
                for (int i = 0; i < numPlayers; i++)
                {
                    interval = Math.Max(interval, endpoints[i].RecommendFrameDelay());
                }

                if (interval > 0)
                {
                    callbacks.OnTimeSync(interval);
                    nextRecommendedSleep = sync.FrameCount + RecommendationInterval;
                }
            }

            // TODO: What does this do?
            if (timeout > 0)
            {
                Thread.Sleep(1);
            }

            return(GGPOErrorCode.OK);
        }