public bool IsPredictionCorrect(SnapshotWithLastInputId correctServerSnapshot, ushort playerEntityId) { PredictedSnapshot predictedSnapshot = predictedSnapshotsStorage .GetByInputId(correctServerSnapshot.lastProcessedInputId); if (predictedSnapshot == null) { string mes = $"Не найдено предсказанное состояние. lastProcessedInputId = {correctServerSnapshot.lastProcessedInputId}"; throw new Exception(mes); } bool timeIsSame = correctServerSnapshot.lastProcessedInputId == predictedSnapshot.lastInputId; if (!timeIsSame) { string message = "Время снимков не совпадает. " + $" inputId тика с сервера = {correctServerSnapshot.lastProcessedInputId} " + $" inputId предсказанного тика = {predictedSnapshot.lastInputId}"; throw new ArgumentException(message); } bool isPredictionCorrect = playerEntityComparer .IsSame(predictedSnapshot, correctServerSnapshot, playerEntityId); return(isPredictionCorrect); }
public float GetTotalDuration(List <uint> predictedSnapshotIds, PredictedSnapshotsStorage predictedSnapshotsStorage) { float duration = predictedSnapshotIds .Sum(id => predictedSnapshotsStorage.GetByInputId(id).physicsSimulationDuration); return(duration); }
private void ResimulateSnapshots(SnapshotWithLastInputId correctServerSnapshot, ushort playerEntityId) { //достать все вводы после заменённого снимка var allInputs = clientInputMessagesHistory .GetAllFromId(correctServerSnapshot.lastProcessedInputId); List <AverageInputMessageModel> averageInputs = averageInputManager.GetAverageInputs(allInputs); log.Debug($"Кол-во вводов {allInputs.Count}. Кол-во тиков физики = {averageInputs.Count}"); DateTime startTime = DateTime.UtcNow; //вызвать перегенерцию положения игрока для каждого ввода foreach (var averageInput in averageInputs) { //todo взять суммарную длительность тиков float physicsSimulationDuration = predictedSnapshotUtil .GetTotalDuration(averageInput.replacedInputsIds, predictedSnapshotsStorage); log.Debug("Длительность симуляции " + physicsSimulationDuration); var baseSnapshot = predictedSnapshotsStorage.GetByInputId(averageInput.inputId - 1) ?? throw new NullReferenceException(); if (baseSnapshot.lastInputId != averageInput.inputId - 1) { throw new Exception("Не совпадает lastInputId"); } log.Debug($"Пересчёт снимка {averageInput.inputId}"); Snapshot snapshot = playerPredictor.Predict(baseSnapshot, playerEntityId, averageInput.inputMessageModel, physicsSimulationDuration); foreach (uint inputId in averageInput.replacedInputsIds) { var wrongPredictedSnapshot = predictedSnapshotsStorage.GetByInputId(inputId) ?? throw new NullReferenceException(); wrongPredictedSnapshot.Clear(); wrongPredictedSnapshot.Modify(snapshot); } } DateTime finishTime = DateTime.UtcNow; int reconcileTime = (finishTime - startTime).Milliseconds; log.Debug($"reconcileTime = {reconcileTime}"); }