diff --git a/Assets/Mirror/Core/SyncDictionary.cs b/Assets/Mirror/Core/SyncDictionary.cs index 4de1994a9..34be71a59 100644 --- a/Assets/Mirror/Core/SyncDictionary.cs +++ b/Assets/Mirror/Core/SyncDictionary.cs @@ -65,12 +65,10 @@ public SyncIDictionary(IDictionary objects) this.objects = objects; } - void AddOperation(Operation op, TKey key, TValue item, bool checkAccess) + void AddOperation(Operation op, TKey key, TValue item, TValue oldItem, bool checkAccess) { if (checkAccess && IsReadOnly) - { - throw new System.InvalidOperationException("SyncDictionaries can only be modified by the owner."); - } + throw new InvalidOperationException("SyncDictionaries can only be modified by the owner."); Change change = new Change { @@ -179,15 +177,15 @@ public override void OnDeserializeDelta(NetworkReader reader) // ClientToServer needs to set dirty in server OnDeserialize. // no access check: server OnDeserialize can always // write, even for ClientToServer (for broadcasting). - if (ContainsKey(key)) + if (objects.TryGetValue(key, out TValue oldItem)) { - objects[key] = item; // assign after ContainsKey check - AddOperation(Operation.OP_SET, key, item, false); + objects[key] = item; // assign after TryGetValue + AddOperation(Operation.OP_SET, key, item, oldItem, false); } else { - objects[key] = item; // assign after ContainsKey check - AddOperation(Operation.OP_ADD, key, item, false); + objects[key] = item; // assign after TryGetValue + AddOperation(Operation.OP_ADD, key, item, default, false); } } break; @@ -199,7 +197,7 @@ public override void OnDeserializeDelta(NetworkReader reader) // ClientToServer needs to set dirty in server OnDeserialize. // no access check: server OnDeserialize can always // write, even for ClientToServer (for broadcasting). - AddOperation(Operation.OP_CLEAR, default, default, false); + AddOperation(Operation.OP_CLEAR, default, default, default, false); // clear after invoking the callback so users can iterate the dictionary // and take appropriate action on the items before they are wiped. objects.Clear(); @@ -210,14 +208,14 @@ public override void OnDeserializeDelta(NetworkReader reader) key = reader.Read(); if (apply) { - if (objects.TryGetValue(key, out item)) + if (objects.TryGetValue(key, out TValue oldItem)) { // add dirty + changes. // ClientToServer needs to set dirty in server OnDeserialize. // no access check: server OnDeserialize can always // write, even for ClientToServer (for broadcasting). objects.Remove(key); - AddOperation(Operation.OP_REMOVE, key, item, false); + AddOperation(Operation.OP_REMOVE, key, oldItem, oldItem, false); } } break; @@ -233,7 +231,7 @@ public override void OnDeserializeDelta(NetworkReader reader) public void Clear() { - AddOperation(Operation.OP_CLEAR, default, default, true); + AddOperation(Operation.OP_CLEAR, default, default, default, true); // clear after invoking the callback so users can iterate the dictionary // and take appropriate action on the items before they are wiped. objects.Clear(); @@ -243,9 +241,9 @@ public void Clear() public bool Remove(TKey key) { - if (objects.TryGetValue(key, out TValue item) && objects.Remove(key)) + if (objects.TryGetValue(key, out TValue oldItem) && objects.Remove(key)) { - AddOperation(Operation.OP_REMOVE, key, item, true); + AddOperation(Operation.OP_REMOVE, key, oldItem, oldItem, true); return true; } return false; @@ -258,13 +256,14 @@ public TValue this[TKey i] { if (ContainsKey(i)) { + TValue oldItem = objects[i]; objects[i] = value; - AddOperation(Operation.OP_SET, i, value, true); + AddOperation(Operation.OP_SET, i, value, oldItem, true); } else { objects[i] = value; - AddOperation(Operation.OP_ADD, i, value, true); + AddOperation(Operation.OP_ADD, i, value, default, true); } } } @@ -274,7 +273,7 @@ public TValue this[TKey i] public void Add(TKey key, TValue value) { objects.Add(key, value); - AddOperation(Operation.OP_ADD, key, value, true); + AddOperation(Operation.OP_ADD, key, value, default, true); } public void Add(KeyValuePair item) => Add(item.Key, item.Value); @@ -301,7 +300,7 @@ public bool Remove(KeyValuePair item) { bool result = objects.Remove(item.Key); if (result) - AddOperation(Operation.OP_REMOVE, item.Key, item.Value, true); + AddOperation(Operation.OP_REMOVE, item.Key, item.Value, item.Value, true); return result; }