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); } } }
//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}"); } } }
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); }
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(); }
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); }
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); } }
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); }
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(); }
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); } }
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); } } }
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++; } } } }
internal bool IsSameInput(InputFrameDelta other) { return(Util.ByteArrayCompare(bytes.RawData(), other.bytes.RawData())); }
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); } }