void ReconcileFrames(float pDistance, InputFrameHistoryItem pLocalItem, InputFrameHistoryItem pServerItem, IEnumerable <InputFrameHistoryItem> pItemsToReconcile)
    {
        // Here we provide an implementation for the reconciling and replaying of frames if anything went wrong.

        // We replay all our frames starting on the servers position and calculate the marging/distance of error.
        Vector3 serverPosition = new Vector3(pServerItem.xPosition, pServerItem.yPosition, pServerItem.zPosition);

        foreach (var item in pItemsToReconcile)
        {
            serverPosition += MoveDelta(_listener.Speed, item.inputFrame);
            if (!item.inputFrame.HasActions)
            {
                continue;
            }

            for (int i = 0; i < item.inputFrame.actions.Length; i++)
            {
                switch (item.inputFrame.actions[i].actionId)
                {
                case 1:
                    serverPosition += JumpDelta(item.inputFrame.actions[i].data[0]);
                    break;

                default:
                    break;
                }
            }
        }

        _errorMargin = serverPosition - transform.position;
    }
 public virtual void RaiseReconcileFrames(float pDistance, InputFrameHistoryItem pLocalItem, InputFrameHistoryItem pServerItem, IEnumerable <InputFrameHistoryItem> pItemsToReconcile)
 {
     if (OnReconcileFrames != null)
     {
         OnReconcileFrames(pDistance, pLocalItem, pServerItem, pItemsToReconcile);
     }
 }
    public virtual void ReconcileFrames()
    {
        ClearLocalInputHistory(_authorativeFrame);
        while (_authorativeInputHistory.Count > 0)
        {
            InputFrameHistoryItem serverItem = _authorativeInputHistory.Dequeue();
            if (serverItem.inputFrame.frame <= _authorativeFrame)
            {
                continue;
            }

            InputFrameHistoryItem localItem = FindLocalInputHistoryItemOrDefault(serverItem.inputFrame.frame);
            if (localItem.inputFrame.frame == 0)
            {
                continue;
            }

            float distance = GetHistoryDistance(ref serverItem, ref localItem);
            if (distance > _reconcileDistance)
            {
                var itemsToReconcile = _localInputHistory.Where(x => x.inputFrame.frame >= serverItem.inputFrame.frame);
                RaiseReconcileFrames(distance, localItem, serverItem, itemsToReconcile);
            }

            _authorativeFrame = serverItem.inputFrame.frame;
        }
    }
 protected virtual float GetHistoryDistance(ref InputFrameHistoryItem pServerItem, ref InputFrameHistoryItem pLocalItem)
 {
     return(Mathf.Sqrt((pServerItem.xPosition - pLocalItem.xPosition) * (pServerItem.xPosition - pLocalItem.xPosition) + (pServerItem.yPosition - pLocalItem.yPosition) * (pServerItem.yPosition - pLocalItem.yPosition) + (pServerItem.zPosition - pLocalItem.zPosition) * (pServerItem.zPosition - pLocalItem.zPosition)));
 }