//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}"); } } }
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); } } }
internal void ApplyPrediction(FrameSyncInput input, InputFrame i1, InputFrame i2) { //copy i1 to i2 SWBytes.CopyFull(i1.bytes, i2.bytes); //let input reset //important to reset triggers input.InputJustCopied(i2.bytes); byte inputSize = input.Size; if (bytes.DataLength > 0) { byte playerCount = bytes.PopByte(); for (int i = 0; i < playerCount; i++) { byte playerID = bytes.PopByte(); FrameSyncPlayer player = input.GetPlayer(playerID); byte offset = player.InputOffset; SWBytes.Copy(bytes, i2.bytes, bytes.ReadIndex, offset, inputSize); bytes.SkipRead(inputSize); } } //reset read index bytes.SetReadIndex(0); //prepare bitarray input.InputDeltaJustApplied(i2.bytes); }
internal int ExportData(SWBytes buffer) { _byteBuffer.Reset(); foreach (IFrameSyncData frameSyncData in _frameSyncDatas) { frameSyncData.Export(_byteBuffer); } int dataSize = 0; if (largeDataContainer) { UInt16 size = (UInt16)_byteBuffer.DataLength; buffer.Push(size); dataSize = 2 + size; } else { byte size = (byte)_byteBuffer.DataLength; buffer.Push(size); dataSize += 1 + size; } buffer.PushAll(_byteBuffer); return(dataSize); }
internal void Apply(FrameSyncInput input, InputFrame i1, InputFrame i2) { //copy i1 to i2 SWBytes.CopyFull(i1.bytes, i2.bytes); //let input reset //important to reset triggers input.InputJustCopied(i2.bytes); //apply delta for each player byte inputSize = input.Size; SWConsole.Crit($"ApplyDelta delta frameNumber={frameNumber} {bytes.FullString()}"); while (bytes.DataLength > 0) { byte playerID = bytes.PopByte(); FrameSyncPlayer player = input.GetPlayer(playerID); if (player == null) { SWConsole.Error($"InputFrameDelta Apply: player not found {playerID}"); } byte offset = player.InputOffset; SWBytes.Copy(bytes, i2.bytes, bytes.ReadIndex, offset, inputSize); bytes.SkipRead(inputSize); } //reset read index bytes.SetReadIndex(0); //prepare bitarray input.InputDeltaJustApplied(i2.bytes); }
public void DebugExport(SWBytes bytes) { foreach (SWFrameSyncSystem system in _systems) { system.Export(bytes); } }
void ReloadSystemDataSnapshot(SWBytes buffer) { foreach (SWFrameSyncSystem system in _systems) { system.Import(buffer); } }
public override int Export(SWBytes buffer) { int size = 0; buffer.Push(_nextDynamicBehaviourIndex); size += 2; UInt16 behaviourCount = (UInt16)_behaviours.Count; buffer.Push(behaviourCount); size += 2; foreach (var pair in _behaviours) { UInt16 id = pair.Key; DynamicFrameSyncBehaviour behaviour = pair.Value; buffer.Push(id); size += 2; buffer.Push(behaviour.prefabID); size += 2; size += behaviour.ExportData(buffer); } return(0); }
public void InputDeltaJustApplied(SWBytes bytes) { foreach (KeyValuePair <byte, FrameSyncPlayer> pair in _playerDictionary) { pair.Value.InputDeltaJustApplied(bytes); } }
void TakeSystemDataSnapshot(SWBytes buffer) { foreach (SWFrameSyncSystem system in _systems) { system.Export(buffer); } }
//EXPORT INPUT internal void ExportInput(SWBytes data) { data.Push(PlayerID); foreach (FrameSyncInputDataController controller in _inputDataControllers) { controller.Export(_exportBitArray); } _exportBitArray.CopyTo(_exportByteArray, 0); data.Push(_exportByteArray); }
//for trigger to reset value internal void InputJustCopied(SWBytes nextFrameBytes) { nextFrameBytes.ReadByteArray(_inputOffset, _byteArray); _bitArray = new BitArray(_byteArray); foreach (FrameSyncInputDataController controller in _inputDataControllers) { controller.InputJustCopied(_bitArray); } _bitArray.CopyTo(_byteArray, 0); nextFrameBytes.WriteByteArray(_inputOffset, _byteArray); }
// predition internal void ApplyPredictionModifier(SWBytes bytes) { foreach (KeyValuePair <byte, FrameSyncPlayer> pair in _playerDictionary) { FrameSyncPlayer player = pair.Value; if (player.Type == FrameSyncPlayerType.Local || player.Type == FrameSyncPlayerType.LocalBot) { // only apply modifier to remote player's input continue; } player.ApplyPredictionModifier(bytes); } }
void initialize(IFrameSyncData[] frameSyncDatas, IFrameSyncUpdate[] frameSyncUpdates) { _frameSyncDatas = frameSyncDatas; _frameSyncUpdates = frameSyncUpdates; if (largeDataContainer) { _byteBuffer = new SWBytes(FrameSyncConstant.FRAMESYNC_BEHAVIOUR_BUFFER_SIZE_LARGE); } else { _byteBuffer = new SWBytes(FrameSyncConstant.FRAMESYNC_BEHAVIOUR_BUFFER_SIZE); } }
// for user prediction modifier internal void ApplyPredictionModifier(SWBytes nextFrameBytes) { nextFrameBytes.ReadByteArray(_inputOffset, _byteArray); _bitArray = new BitArray(_byteArray); foreach (FrameSyncInputDataController controller in _inputDataControllers) { controller.ApplyPredictionModifier(_bitArray); } _bitArray.CopyTo(_byteArray, 0); nextFrameBytes.WriteByteArray(_inputOffset, _byteArray); }
public void ExportInput(SWBytes bytes) { byte playerCount = 0; foreach (KeyValuePair <byte, FrameSyncPlayer> pair in _playerDictionary) { FrameSyncPlayer player = pair.Value; if (player.Type == FrameSyncPlayerType.Local || player.Type == FrameSyncPlayerType.LocalBot) { playerCount++; pair.Value.ExportInput(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); } }
void SaveInput(SWBytes data, int start, int end) { SWConsole.Info($"SaveItems start={start}, end={end}"); if (end > _lastEndIndex) { _lastEndIndex = end; } return; string partialName = _game.replayFileName + start.ToString("D6") + end.ToString("D6"); SaveReplayoperation operation = new SaveReplayoperation(data.Data(), partialName); operationQueue.AddOperation(operation); }
public void DebugStep(SWBytes bytes, int frameNumber) { _debugInputFrame = bytes; FrameSyncUpdateType updateType = FrameSyncUpdateType.Normal; foreach (SWFrameSyncSystem system in _systems) { system.WillUpdate(); } foreach (SWFrameSyncSystem system in _systems) { system.Update(_game, _input, updateType); } _debugInputFrame = null; }
internal void ImportData(SWBytes buffer) { _byteBuffer.Reset(); if (largeDataContainer) { UInt16 size = _byteBuffer.PopUInt16(); buffer.PopByteBuffer(_byteBuffer, 0, size); } else { byte size = buffer.PopByte(); buffer.PopByteBuffer(_byteBuffer, 0, size); } foreach (IFrameSyncData frameSyncData in _frameSyncDatas) { frameSyncData.Import(_byteBuffer); } }
public override int Export(SWBytes buffer) { int size = 0; UInt16 behaviourCount = (UInt16)_behaviours.Count; buffer.Push(behaviourCount); size += 2; foreach (var pair in _behaviours) { UInt16 id = pair.Key; StaticFrameSyncBehaviour behaviour = pair.Value; buffer.Push(id); size += 2; size += behaviour.ExportData(buffer); } return(size); }
public override void Import(SWBytes buffer) { UInt16 behaviourCount = buffer.PopUInt16(); if (behaviourCount != _behaviours.Count) { throw new Exception($"StaticFrameSyncBehaviourManager: Import importBehaviourCount={behaviourCount} behaviourCount={ _behaviours.Count}"); } foreach (var pair in _behaviours) { UInt16 id = pair.Key; StaticFrameSyncBehaviour behaviour = pair.Value; UInt16 importId = buffer.PopUInt16(); if (importId != id) { throw new Exception($"StaticFrameSyncBehaviourManager: Import importID={importId} id={id}"); } behaviour.ImportData(buffer); } }
public void SetSystemData(SWBytes buffer) { ReloadSystemDataSnapshot(buffer); }
public void Import(SWBytes buffer) { UInt16 dataLength = buffer.PopUInt16(); buffer.PopByteBuffer(bytes, 0, (int)dataLength); }
public void Export(SWBytes buffer) { buffer.PushFront((UInt16)bytes.DataLength); buffer.PushAll(bytes); }
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++; } } } }
public abstract void Import(SWBytes buffer);
public abstract int Export(SWBytes buffer);
public SWSystemDataFrame() { bytes = new SWBytes(FrameSyncConstant.DATA_FRAME_SIZE); FrameNumber = 0; }
internal SWSystemDataFrame(int frameNumber) { bytes = new SWBytes(FrameSyncConstant.DATA_FRAME_SIZE); FrameNumber = frameNumber; }