From 38c296de7151cff42d6d3cd0e2b585eed59b18b8 Mon Sep 17 00:00:00 2001
From: modmuss50 <modmuss50@gmail.com>
Date: Tue, 24 Nov 2020 19:51:28 +0000
Subject: [PATCH] Assign a new ID to client only registry entries when syncing.
 (#1179)

* Assign a new ID to client only registry entries when syncing.

Fixes #1165

* Cleanup + review comments
---
 .../mixin/registry/sync/MixinIdRegistry.java  | 28 ++++++++++---------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/MixinIdRegistry.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/MixinIdRegistry.java
index a39365139..58bdc57d5 100644
--- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/MixinIdRegistry.java
+++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/mixin/registry/sync/MixinIdRegistry.java
@@ -18,10 +18,8 @@ package net.fabricmc.fabric.mixin.registry.sync;
 
 import java.util.ArrayList;
 import java.util.Comparator;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import com.google.common.collect.BiMap;
 import com.google.common.collect.HashBiMap;
@@ -273,25 +271,29 @@ public abstract class MixinIdRegistry<T> extends Registry<T> implements Remappab
 			break;
 		}
 		case REMOTE: {
-			// TODO: Is this what mods really want?
-			Set<Identifier> droppedIds = new HashSet<>();
+			int maxId = -1;
 
 			for (Identifier id : getIds()) {
 				if (!remoteIndexedEntries.containsKey(id)) {
-					T object = get(id);
-					int rid = getRawId(object);
+					if (maxId < 0) {
+						for (int value : remoteIndexedEntries.values()) {
+							if (value > maxId) {
+								maxId = value;
+							}
+						}
+					}
 
-					droppedIds.add(id);
+					if (maxId < 0) {
+						throw new RemapException("Failed to assign new id to client only registry entry");
+					}
 
-					// Emit RemoveObject events for removed objects.
-					fabric_getRemoveObjectEvent().invoker().onEntryRemoved(rid, id, object);
+					maxId++;
+
+					FABRIC_LOGGER.debug("An ID for {} was not sent by the server, assuming client only registry entry and assigning a new id ({}) in {}", id.toString(), maxId, getKey().getValue().toString());
+					remoteIndexedEntries.put(id, maxId);
 				}
 			}
 
-			// note: indexedEntries cannot be safely remove()d from
-			idToEntry.keySet().removeAll(droppedIds);
-			keyToEntry.keySet().removeIf(registryKey -> droppedIds.contains(registryKey.getValue()));
-
 			break;
 		}
 		}