Пример #1
0
        /// <summary>
        /// Creates a patch from the PatchMessage sent by the client.
        /// Then applies the patch to the ShadowCopy followed by applying the patch to the live server copy.
        /// Then creates new diffs from the live server text and the shadow (which contains the exact copy of latest client message).
        /// These diffs will then be send to the client so that the client now has the latest updates.
        /// </summary>
        /// <param name="message"></param>
        private void HandlePatchMessage(PatchMessage message)
        {
            _edits.Clear();
            Edit edit = message.Edits.Pop();

            Task.Factory.StartNew(() =>
            {
                if (edit.ClientVersion > User.Document.ShadowCopy.ClientVersion || edit.ClientVersion == 0)
                {
                    // Update Server Shadow
                    bool success;
                    List <Patch> patches;
                    try
                    {
                        patches = _dmp.patch_make(User.Document.ShadowCopy.ShadowText, edit.Diffs);
                        User.Document.ShadowCopy.ShadowText =
                            _dmp.patch_apply(patches, User.Document.ShadowCopy.ShadowText)[0].ToString();
                        //User.Document.ShadowCopy.ClientVersion++;
                        User.Document.BackupShadowCopy.BackupText = User.Document.ShadowCopy.ShadowText;
                        success = true;
                    }
                    catch (ArgumentOutOfRangeException e)
                    {
                        Console.WriteLine(e);
                        success = false;
                        Session.BroadCastOutOfSyncResponse(Session.Document.CurrentText);
                    }

                    if (success)
                    {
                        // Update Server Current
                        patches = _dmp.patch_make(Session.Document.CurrentText, edit.Diffs);
                        Session.Document.CurrentText =
                            _dmp.patch_apply(patches, Session.Document.CurrentText)[0].ToString();
                        Console.WriteLine(
                            $"Updated client: {User.Username}, With test: {Session.Document.CurrentText}");
                    }
                }
            }).ContinueWith((result) =>
            {
                List <Diff> diffs = _dmp.diff_main(User.Document.ShadowCopy.ShadowText, Session.Document.CurrentText,
                                                   false);
                _dmp.diff_cleanupEfficiency(diffs);
                _edits.Push(new Edit(diffs, User.Document.ShadowCopy.ClientVersion,
                                     User.Document.ShadowCopy.ServerVersion));
                SendMessage(new PatchMessage("Server", _edits));
                User.Document.ShadowCopy.ShadowText = Session.Document.CurrentText;
                _edits.Clear();
            });
        }