예제 #1
0
        public void SendInputFrameDeltas(SWBytes inputFrameDeltas, int count, byte inputSize)
        {
            for (int i = 0; i < count; i++)
            {
                int playerFrameNumber    = inputFrameDeltas.PopInt();
                int predictedFrameNumber = inputFrameDeltas.PopInt();

                byte length = inputFrameDeltas.PopByte();

                if (playerFrameNumber == _lastReceivedPlayerFrameNumber + 1)
                {
                    int correctPredictedFrameNumber = 0;

                    if (predictedFrameNumber != 0)
                    {
                        correctPredictedFrameNumber = _lastPredictedFrameNumber + 1;
                        _predictedFrameNumber       = predictedFrameNumber;
                        _correctFrameNumber         = correctPredictedFrameNumber;
                        SWConsole.Info($"MOCK: SendInputFrameDeltas playerFrameNumber={playerFrameNumber} correctPredictedFrameNumber={correctPredictedFrameNumber} _predictedFrameNumber={_predictedFrameNumber}");
                    }

                    InputFrameDelta delta = new InputFrameDelta();
                    delta.frameNumber = playerFrameNumber;
                    inputFrameDeltas.PopByteBuffer(delta.bytes, 0, length);
                    _receivedInputFrameDeltas.Enqueue(delta);
                    _lastReceivedPlayerFrameNumber = playerFrameNumber;
                    _lastPredictedFrameNumber      = correctPredictedFrameNumber;
                }
                else
                {
                    SWConsole.Info($"MOCK: SendInputFrameDeltas SKIP playerFrameNumber={playerFrameNumber}");
                    inputFrameDeltas.SkipRead(length);
                }
            }
        }
예제 #2
0
        //should include startFrame, include endframe
        public void HandleInputFramesInBackground(SWBytes initialInputFramesData, int startFrameNumber, int endFrameNumber)
        {
            lock (FRAME_SYNC_LOCK)
            {
                if (_game.gameState == FrameSyncGameState.Stopped)
                {
                    return;
                }
                SWConsole.Info($"HandleInputFramesInBackground startFrameNumber={startFrameNumber} endFrameNumber={endFrameNumber}");
                _startFrameNumber = startFrameNumber;
                _endFrameNumber   = endFrameNumber;
                _initialInputFrameDeltas.Clear();
                _initialInputFramesData = initialInputFramesData;
                for (int i = startFrameNumber; i < endFrameNumber; i++)
                {
                    InputFrameDelta delta  = new InputFrameDelta();
                    byte            length = initialInputFramesData.PopByte();
                    initialInputFramesData.PopByteBuffer(delta.bytes, 0, length);
                    _initialInputFrameDeltas.Add(delta);
                }

                int expected = endFrameNumber - startFrameNumber;
                int got      = _initialInputFrameDeltas.Count;
                //reset read index, we will save the data to disk later
                _initialInputFramesData.SetReadIndex(0);
                if (expected != got)
                {
                    SWConsole.Error($"HandleInputFramesInBackground got={got} expected={expected}");
                }
            }
        }
예제 #3
0
        int Simulate(int frameNumber)
        {
            SWConsole.Crit($"Engine: Simulate frameNumber={frameNumber}");

            InputFrame lastInputFrame = inputFrames[frameNumber - 1];

            InputFrameDelta lastInputFrameDelta = inputFrameDeltas[frameNumber - 1];

            int playerFrameNumber = lastInputFrameDelta.playerFrameNumber;

            InputFrame inputFrame = inputFrames[frameNumber];

            if (inputFrame == null)
            {
                inputFrame = new InputFrame(frameNumber);
                inputFrames[frameNumber] = inputFrame;
            }

            inputFrame.FrameNumber = frameNumber;
            inputFrame.ResetBytes();

            if (lastInputFrame == null || _input == null || inputFrame == null || lastInputFrameDelta == null)
            {
                SWConsole.Error($"Engine: Simulate input data is nil {lastInputFrame} {_input} {inputFrame} {lastInputFrameDelta}");
            }

            lastInputFrameDelta.Apply(_input, lastInputFrame, inputFrame);

            FrameSyncUpdateType updateType = FrameSyncUpdateType.Normal;

            DoSimulate(updateType, inputFrame, frameNumber);

            return(playerFrameNumber);
        }
예제 #4
0
        void FlushInputOnlinePrediction()
        {
            InputFrameDelta previousInputDelta = localInputFrameDeltas[_currentLocalInputFrameDeltaNumber];

            _currentLocalInputFrameDeltaNumber++;

            if (_nextPlayerFrameNumberToConfirm == 0)
            {
                _nextPlayerFrameNumberToConfirm = _currentLocalInputFrameDeltaNumber;
            }

            InputFrameDelta inputFrameDelta = localInputFrameDeltas[_currentLocalInputFrameDeltaNumber];

            if (inputFrameDelta == null)
            {
                inputFrameDelta = new InputFrameDelta(_currentLocalInputFrameDeltaNumber);
                localInputFrameDeltas[_currentLocalInputFrameDeltaNumber] = inputFrameDelta;
            }

            inputFrameDelta.frameNumber = _currentLocalInputFrameDeltaNumber;
            inputFrameDelta.resend      = FrameSyncConstant.LOCAL_INPUT_FRAME_RESEND_COUNT;
            inputFrameDelta.ResetBytes();
            _input.ExportInput(inputFrameDelta.bytes);

            bool inputChanged = false;

            if (previousInputDelta == null)
            {
                inputChanged = true;
            }
            else
            {
                bool sameInput = previousInputDelta.IsSameInput(inputFrameDelta);
                inputChanged = !sameInput;
            }

            if (!inputChanged)
            {
                SWConsole.Crit($"Engine: FlushInputOnlinePrediction Input did NOT Change: localFN={_currentLocalInputFrameDeltaNumber}");
                //_currentLocalInputFrameDeltaNumber--;
                //send an empty frame to keep the fixed delta time adjustment running
                inputFrameDelta.ResetBytes();
            }
            else
            {
                SWConsole.Crit($"Engine: FlushInputOnlinePrediction Input changed: localFN={_currentLocalInputFrameDeltaNumber}");
            }

            SendLocalInputs();
        }
예제 #5
0
        void FlushInputOffline()
        {
            //write directly to inputFrameDeltas
            InputFrameDelta inputFrameDelta = inputFrameDeltas[_currentInputFrameNumber];

            if (inputFrameDelta == null)
            {
                inputFrameDelta = new InputFrameDelta(_currentInputFrameNumber);
                inputFrameDeltas[_currentInputFrameNumber] = inputFrameDelta;
            }
            inputFrameDelta.frameNumber = _currentInputFrameNumber;

            inputFrameDelta.ResetBytes();
            _input.ExportInput(inputFrameDelta.bytes);
        }
예제 #6
0
        void WaitingForRoomFrame()
        {
            if (_firstFrameReceived > 0)
            {
                SWConsole.Crit($"WaitingForRoomFrame _firstFrameReceived={_firstFrameReceived}");
                InputFrameDelta delta = inputFrameDeltas[_firstFrameReceived];

                if (delta != null)
                {
                    SWConsole.Crit($"WaitingForRoomFrame delta not null Delta.frameNumber = {delta.frameNumber}");
                    if (delta.frameNumber == _firstFrameReceived)
                    {
                        if (_firstFrameReceived > 1)
                        {
                            _game.gameState = FrameSyncGameState.WaitingForInitialSystemData;
                            SWConsole.Crit($"WaitingForRoomFrame RequestInputFrames end={_firstFrameReceived}");

                            _io.RequestInputFrames(1, _firstFrameReceived);
                            SWConsole.Crit($"WaitingForRoomFrame game WaitingForInitialSystemData now");
                        }
                        else
                        {
                            //start from 1st frame
                            _currentInputFrameNumber = 1;

                            //create an empty input frame to start with
                            inputFrames[_currentInputFrameNumber] = new InputFrame(_currentInputFrameNumber);
                            _game.gameState = FrameSyncGameState.Running;
                            SetSaveHandler(0);
                            SWConsole.Crit($"WaitingForRoomFrame game running now");
                        }

                        ResetTimeStamp();
                        return;
                    }
                }
            }
            if (CheckInterval(FrameSyncConstant.SERVER_FRAME_INITIALIZATION_INTERVAL))
            {
                SWBytes buffer = new SWBytes(32);

                buffer.Push(0); //frame number
                buffer.Push(0); //predict
                byte length = 0;
                buffer.Push(length);
                _io.SendInputFrameDeltas(buffer, 1, _input.Size);
            }
        }
예제 #7
0
        bool Predict(int localFrameDeltaNumber, int frameNumber)
        {
            SWConsole.Crit($"Engine: Predict localFrameDeltaNumber={localFrameDeltaNumber} frameNumber={frameNumber}");

            InputFrameDelta inputFrameDelta = localInputFrameDeltas[localFrameDeltaNumber];

            _inputFrameForPrediction.FrameNumber = frameNumber;
            _inputFrameForPrediction.ResetBytes();

            inputFrameDelta.Apply(_input, _lastInputFrameForPrediction, _inputFrameForPrediction);

            _input.ApplyPredictionModifier(_inputFrameForPrediction.bytes);

            FrameSyncUpdateType updateType = FrameSyncUpdateType.Prediction;

            DoSimulate(updateType, _inputFrameForPrediction, frameNumber);

            return(true);
        }
예제 #8
0
        public void FlushInputOnline()
        {
            InputFrameDelta previousInputDelta = localInputFrameDeltas[_currentLocalInputFrameDeltaNumber];

            _currentLocalInputFrameDeltaNumber++;

            InputFrameDelta inputFrameDelta = localInputFrameDeltas[_currentLocalInputFrameDeltaNumber];

            if (inputFrameDelta == null)
            {
                inputFrameDelta = new InputFrameDelta(_currentLocalInputFrameDeltaNumber);
                localInputFrameDeltas[_currentLocalInputFrameDeltaNumber] = inputFrameDelta;
            }

            inputFrameDelta.frameNumber = _currentLocalInputFrameDeltaNumber;
            inputFrameDelta.resend      = FrameSyncConstant.LOCAL_INPUT_FRAME_RESEND_COUNT;
            inputFrameDelta.ResetBytes();
            _input.ExportInput(inputFrameDelta.bytes);

            bool inputChanged = false;

            if (previousInputDelta == null)
            {
                inputChanged = true;
            }
            else
            {
                bool sameInput = previousInputDelta.IsSameInput(inputFrameDelta);
                inputChanged = !sameInput;
            }

            if (!inputChanged)
            {
                SWConsole.Crit("Engine: Input did NOT Change");
                _currentLocalInputFrameDeltaNumber--;
            }
            else
            {
                SWConsole.Crit("Engine: Input Changed");
            }

            SendLocalInputs();
        }
예제 #9
0
        void SendLocalInputs()
        {
            if (_localInputFrameDeltaNumberToSend == 0)
            {
                _localInputFrameDeltaNumberToSend = _currentLocalInputFrameDeltaNumber;
            }

            _sendLocalInputDeltaBuffer.Reset();

            int end = _localInputFrameDeltaNumberToSend + FrameSyncConstant.LOCAL_INPUT_FRAME_RESEND_COUNT;

            if (end > _currentLocalInputFrameDeltaNumber)
            {
                end = _currentLocalInputFrameDeltaNumber;
            }

            int count = 0;

            for (int i = _localInputFrameDeltaNumberToSend; i <= end; i++)
            {
                InputFrameDelta inputFrameDelta = localInputFrameDeltas[i];
                _sendLocalInputDeltaBuffer.Push(inputFrameDelta.frameNumber);

                byte length = (byte)inputFrameDelta.bytes.DataLength;
                _sendLocalInputDeltaBuffer.Push(length);
                _sendLocalInputDeltaBuffer.PushAll(inputFrameDelta.bytes);

                count++;
                inputFrameDelta.resend = inputFrameDelta.resend - 1;
                if (inputFrameDelta.resend == 0)
                {
                    _localInputFrameDeltaNumberToSend++;
                }
            }

            if (count > 0)
            {
                _io.SendInputFrameDeltas(_sendLocalInputDeltaBuffer, count, _input.Size);
            }
        }
예제 #10
0
        public void RequestInputFrames(int startFrameNumber, int endFrameNumber)
        {
            if (startFrameNumber <= endFrameNumber)
            {
                if (startFrameNumber > 0 && endFrameNumber <= _frameNumber)
                {
                    _largeData.Reset();

                    for (int i = startFrameNumber; i < endFrameNumber; i++)
                    {
                        InputFrameDelta delta = _inputFrameDeltas[i];
                        if (delta == null)
                        {
                            delta             = new InputFrameDelta();
                            delta.frameNumber = 0; //playerFrameNumber
                        }

                        delta.Export(_largeData);
                    }

                    _handler.HandleInputFramesInBackground(_largeData, startFrameNumber, endFrameNumber);
                }
            }
        }
예제 #11
0
        public void HandleInputFrameInBackground(SWBytes inputFrame, int playerFrameCountOnServer, int roomStep, int playerFrameNumber)
        {
            lock (FRAME_SYNC_LOCK)
            {
                SWConsole.Crit($"<<<======Engine: HandleInputFrameInBackground roomStep={roomStep} playerFrameCountOnServer={playerFrameCountOnServer} playerFrameNumber={playerFrameNumber}");

                if (_game.gameState == FrameSyncGameState.Stopped)
                {
                    SWConsole.Crit($"Engine: HandleInputFrameInBackground game stopped");
                    return;
                }

                _playerFrameCountOnServer = playerFrameCountOnServer;

                if (_lastReceivedInputFrameDeltaNumber == 0)
                {
                    int startIndex = roomStep - 10;
                    if (startIndex < 0)
                    {
                        startIndex = 0;
                    }

                    InitializeFrames(startIndex);
                    _lastReceivedInputFrameDeltaNumber = roomStep;

                    InputFrameDelta firstDelta = new InputFrameDelta(roomStep);
                    firstDelta.playerFrameNumber = playerFrameNumber;
                    byte length = inputFrame.PopByte();
                    SWBytes.Copy(inputFrame, firstDelta.bytes, length);
                    inputFrameDeltas[roomStep]         = firstDelta;
                    _currentInputFrameNumber           = 0; //will be updated in the waiting for room frame state
                    _currentLocalInputFrameDeltaNumber = 0;
                    SWConsole.Crit($"Engine: HandleInputFrameInBackground startIndex={startIndex}");
                    return;
                }

                InputFrameDelta delta = inputFrameDeltas[roomStep];

                if (delta == null)
                {
                    delta = new InputFrameDelta();
                    inputFrameDeltas[roomStep] = delta;
                }

                if (delta.frameNumber == roomStep)
                {
                    SWConsole.Crit($"HandleInputFrameInBackground already has {roomStep}");
                }
                else
                {
                    delta.frameNumber       = roomStep;
                    delta.playerFrameNumber = playerFrameNumber;
                    SWConsole.Crit($"HandleInputFrameInBackground copy roomStep={roomStep}");// bytes={inputFrame.FullString()}");
                    byte length = inputFrame.PopByte();

                    SWBytes.Copy(inputFrame, delta.bytes, length);
                }

                //SWConsole.Crit($"Engine: HandleInputFrameInBackground roomStep={roomStep} _lastReceivedInputFrameDeltaNumber={_lastReceivedInputFrameDeltaNumber}");

                if (roomStep == _lastReceivedInputFrameDeltaNumber + 1)
                {
                    if (_firstFrameReceived == 0)
                    {   //set firstFrameReceived when we have subsequence room steps
                        _firstFrameReceived = _lastReceivedInputFrameDeltaNumber;
                    }

                    _lastReceivedInputFrameDeltaNumber = roomStep;

                    //check if there is any more received frames
                    bool shouldContinue  = true;
                    int  nextFrameNumber = roomStep + 1;
                    while (shouldContinue)
                    {
                        InputFrameDelta nextDelta = inputFrameDeltas[nextFrameNumber];

                        if (nextDelta == null)
                        {
                            break;
                        }

                        if (nextDelta.frameNumber != nextFrameNumber)
                        {
                            break;
                        }

                        _lastReceivedInputFrameDeltaNumber = nextFrameNumber;

                        nextFrameNumber++;
                    }
                }
            }
        }
예제 #12
0
 internal bool IsSameInput(InputFrameDelta other)
 {
     return(Util.ByteArrayCompare(bytes.RawData(), other.bytes.RawData()));
 }
예제 #13
0
        void DoTick()
        {
            _frameNumber++;
            _sealedFrameNumber = _frameNumber - 10;
            if (_sealedFrameNumber < 1)
            {
                _sealedFrameNumber = 1;
            }

            if (_receivedInputFrameDeltas.Count > 0)
            {
                SWConsole.Crit($"MockIO: DoTick playerFrameCount={_receivedInputFrameDeltas.Count}");
                InputFrameDelta delta = _receivedInputFrameDeltas.Peek();

                if (true)
                {
                    delta = _receivedInputFrameDeltas.Dequeue();
                    //SWConsole.Crit($"MockIO: DoTick playerFrameCount 1 ={_receivedInputFrameDeltas.Count}");
                    _inputFrameDeltas[_frameNumber] = delta;

                    _data.Reset();

                    byte length = (byte)delta.bytes.DataLength;
                    _data.Push(length);
                    _data.PushAll(delta.bytes);

                    SWConsole.Crit($"MockIO: DoTick send PLAYER={delta.frameNumber} roomStep={_frameNumber}");

                    MockHandleInputFrameOperaion operation = new MockHandleInputFrameOperaion(_handler, _pingMilliseconds);
                    operation.inputFrameData = SWBytes.Clone(_data);
                    operation.playerLastInputFrameOnServer = _receivedInputFrameDeltas.Count;
                    operation.predictionFrameNumber        = _predictedFrameNumber;
                    operation.correctFrameNumber           = _correctFrameNumber;
                    operation.roomStep          = _frameNumber;
                    operation.sealedFrameNumber = _sealedFrameNumber;
                    _operationQueue.AddOperation(operation);
                    return;
                }
                //else if(delta.predictedServerFrameNumber < _frameNumber)
                //{
                //    delta = _receivedInputFrameDeltas.Dequeue();
                //    delta.version = 1;
                //    _inputFrameDeltas[delta.predictedServerFrameNumber] = delta;

                //    _data.Reset();

                //    byte length = (byte)delta.bytes.DataLength;
                //    _data.Push(length);
                //    _data.Push(delta.bytes, 0);

                //    SWConsole.Crit($"MockIO: DoTick send PLAYER={delta.frameNumber} roomStep={_frameNumber} prediction={delta.predictedServerFrameNumber}");
                //    _frameNumber--;
                //    _sealedFrameNumber = _frameNumber - 10;
                //    if (_sealedFrameNumber < 1)
                //    {
                //        _sealedFrameNumber = 1;
                //    }
                //    MockHandleInputFrameOperaion operation = new MockHandleInputFrameOperaion(_handler, _pingMilliseconds);
                //    operation.inputFrameData = SWBytes.Clone(_data);
                //    operation.playerLastInputFrameOnServer = _receivedInputFrameDeltas.Count;
                //    operation.predictionError = _predictionError;
                //    operation.roomStep = delta.predictedServerFrameNumber;
                //    operation.version = delta.version;
                //    operation.sealedFrameNumber = _sealedFrameNumber;
                //    _operationQueue.AddOperation(operation);
                //    return;
                //}
            }

            {
                _lastPredictedFrameNumber = _frameNumber;
                InputFrameDelta delta = new InputFrameDelta();
                delta.frameNumber = 0; //playerFrameNumber
                _inputFrameDeltas[_frameNumber] = delta;

                _data.Reset();
                _data.Push((byte)0); //length
                SWConsole.Crit($"MockIO: DoTick send EMPTY={delta.frameNumber} roomStep={_frameNumber}");

                MockHandleInputFrameOperaion operation = new MockHandleInputFrameOperaion(_handler, _pingMilliseconds);
                operation.inputFrameData = SWBytes.Clone(_data);
                operation.playerLastInputFrameOnServer = _receivedInputFrameDeltas.Count;
                operation.predictionFrameNumber        = _predictedFrameNumber;
                operation.correctFrameNumber           = _correctFrameNumber;
                operation.roomStep          = _frameNumber;
                operation.sealedFrameNumber = _sealedFrameNumber;
                _operationQueue.AddOperation(operation);
            }
        }