Пример #1
0
        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);
        }
Пример #2
0
        public float GetTotalDuration(List <uint> predictedSnapshotIds,
                                      PredictedSnapshotsStorage predictedSnapshotsStorage)
        {
            float duration = predictedSnapshotIds
                             .Sum(id => predictedSnapshotsStorage.GetByInputId(id).physicsSimulationDuration);

            return(duration);
        }
Пример #3
0
        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}");
        }