/// <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(); }); }