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); }
//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}"); } } }
void CombineSavedInputFiles() { return; string fileName = _game.replayFileName; string[] savedFiles = SWLocalStorage.GetFilesWithPartialName(FrameSyncConstant.DEFAULT_DIRECTORY, fileName); if (savedFiles.Length == 0) { return; } SortedList <int, string> orderedFiles = new SortedList <int, string>(); List <int> sortedIndexes = new List <int>(); foreach (string saveFile in savedFiles) { Debug.Log($"saveFile={saveFile}"); string frameNumber = saveFile.Substring(saveFile.LastIndexOf(fileName) + fileName.Length); Debug.Log($"frameNumber={frameNumber}"); long frameNumberLong = 0; bool good = long.TryParse(frameNumber, out frameNumberLong); if (!good) { continue; } int low = (int)(frameNumberLong / 1000000); int high = (int)(frameNumberLong % 100000); int size = high - low; Debug.Log($"low={low} high={high} size={size}"); orderedFiles[low] = saveFile; sortedIndexes.Add(low); sortedIndexes.Add(high); } sortedIndexes.Sort(); int count = sortedIndexes.Count; bool verified = true; for (int i = 0; i < count; i++) { if (i == count - 1) { break; } if (i % 2 == 1) { bool match = sortedIndexes[i] == sortedIndexes[i + 1]; if (!match) { verified = false; break; } } } if (!verified) { Debug.Log("Corrupted files"); } int startFrameNumber = sortedIndexes[0]; int endFrameNumber = sortedIndexes[sortedIndexes.Count - 1]; Debug.Log($"start={startFrameNumber} end={endFrameNumber}"); int estimatedSize = (endFrameNumber - startFrameNumber) * InputFrameDelta.DataSize + 100; byte[] dataToSave = new byte[estimatedSize]; SWBytes combinedBuffer = new SWBytes(dataToSave); PersistentArrayMetaData metaData = new PersistentArrayMetaData(); metaData.itemCount = endFrameNumber - startFrameNumber; combinedBuffer.SetWriteIndex(PersistentArrayMetaData.DataSize); foreach (var orderedFile in orderedFiles) { byte[] data; int length = SWLocalStorage.LoadFromFile(orderedFile.Value, out data); SWBytes dataBuffer = new SWBytes(data); //Debug.Log($"Combined add={dataBuffer.FullString()}"); combinedBuffer.PushAll(dataBuffer); Debug.Log($"Remove {orderedFile.Value}"); SWLocalStorage.RemoveFile(orderedFile.Value); } combinedBuffer.SetReadIndex(PersistentArrayMetaData.DataSize); metaData.checksum = combinedBuffer.Crc32(); int end = combinedBuffer.GetWriteIndex(); combinedBuffer.SetWriteIndex(0); //Debug.Log($"Combined before meta={combinedBuffer.FullString()}"); metaData.Export(combinedBuffer); //Debug.Log($"Combined after meta={combinedBuffer.FullString()}"); combinedBuffer.SetWriteIndex(end); combinedBuffer.SetReadIndex(0); //Debug.Log($"Combined combinedBuffer={combinedBuffer.FullString()}"); SaveReplayoperation operation = new SaveReplayoperation(combinedBuffer.Data(), fileName + ".play"); operationQueue.AddOperation(operation); }