2020-08-06 20:54:26 +02:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
|
From: JellySquid <jellysquid+atwork@protonmail.com>
|
|
|
|
Date: Tue, 4 Aug 2020 21:46:05 +0200
|
|
|
|
Subject: [PATCH] lithium-MixinDataWatcher
|
|
|
|
|
|
|
|
Original code by JellySquid, licensed under GNU Lesser General Public License v3.0
|
2020-08-06 23:02:30 +02:00
|
|
|
you can find the original code on https://github.com/jellysquid3/lithium-fabric/tree/1.16.x/fabric (Yarn mappings)
|
2020-08-06 20:54:26 +02:00
|
|
|
|
|
|
|
Co-authored-by: tr7zw <tr7zw@live.de>
|
|
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/DataWatcher.java b/src/main/java/net/minecraft/server/DataWatcher.java
|
2020-08-13 17:53:32 +02:00
|
|
|
index e69093b411f76ea4090789576f8fb6635bd02ca5..4a14431b198c227eb6f0f68eaac14f5c09fc3036 100644
|
2020-08-06 20:54:26 +02:00
|
|
|
--- a/src/main/java/net/minecraft/server/DataWatcher.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/DataWatcher.java
|
2020-08-13 17:53:32 +02:00
|
|
|
@@ -27,6 +27,77 @@ public class DataWatcher {
|
2020-08-06 20:54:26 +02:00
|
|
|
private boolean f = true;
|
|
|
|
private boolean g;
|
|
|
|
|
|
|
|
+ // Yatopia lithium start
|
|
|
|
+ private static final int DEFAULT_ENTRY_COUNT = 10, GROW_FACTOR = 8;
|
|
|
|
+ /** Mirrors the vanilla backing entries map. Each DataWatcher.Item can be accessed in this array through its ID. **/
|
|
|
|
+ private DataWatcher.Item<?>[] entriesArray = new DataWatcher.Item<?>[DEFAULT_ENTRY_COUNT];
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * We redirect the call to add a tracked data to the internal map so we can add it to our new storage structure. This
|
|
|
|
+ * should only ever occur during entity initialization. Type-erasure is a bit of a pain here since we must redirect
|
|
|
|
+ * a calls to the generic Map interface.
|
|
|
|
+ */
|
2020-08-13 17:53:32 +02:00
|
|
|
+ private Object onAddTrackedDataInsertMap(Int2ObjectOpenHashMap<DataWatcher.Item<?>> map, int keyRaw, DataWatcher.Item<?> valueRaw) {
|
2020-08-06 20:54:26 +02:00
|
|
|
+ int k = keyRaw;
|
|
|
|
+ DataWatcher.Item<?> v = (DataWatcher.Item<?>) valueRaw;
|
|
|
|
+
|
|
|
|
+ DataWatcher.Item<?>[] storage = this.entriesArray;
|
|
|
|
+
|
|
|
|
+ // Check if we need to grow the backing array to accommodate the new key range
|
|
|
|
+ if (storage.length <= k) {
|
|
|
|
+ // Grow the array to accommodate 8 entries after this one, but limit it to never be larger
|
|
|
|
+ // than 256 entries as per the vanilla limit
|
|
|
|
+ int newSize = Math.min(k + GROW_FACTOR, 256);
|
|
|
|
+
|
2020-08-11 20:40:29 +02:00
|
|
|
+ this.entriesArray = storage = java.util.Arrays.copyOf(storage, newSize);
|
2020-08-06 20:54:26 +02:00
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Update the storage
|
|
|
|
+ storage[k] = v;
|
|
|
|
+
|
|
|
|
+ // Ensure that the vanilla backing storage is still updated appropriately
|
|
|
|
+ return this.entries.put(k, v);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * @reason Avoid integer boxing/unboxing and use our array-based storage
|
|
|
|
+ * @author JellySquid
|
|
|
|
+ */
|
|
|
|
+ private <T> DataWatcher.Item<T> getEntry(DataWatcherObject<T> data) {
|
|
|
|
+ try {
|
|
|
|
+ DataWatcher.Item<?>[] array = this.entriesArray;
|
|
|
|
+
|
|
|
|
+ int id = data.a();
|
|
|
|
+
|
|
|
|
+ // The vanilla implementation will simply return null if the tracker doesn't contain the specified entry. However,
|
|
|
|
+ // accessing an array with an invalid pointer will throw a OOB exception, where-as a HashMap would simply
|
|
|
|
+ // return null. We check this case (which should be free, even if so insignificant, as the subsequent bounds
|
|
|
|
+ // check will hopefully be eliminated)
|
|
|
|
+ if (id < 0 || id >= array.length) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // This cast can fail if trying to access a entry which doesn't belong to this tracker, as the ID could
|
|
|
|
+ // instead point to an entry of a different type. However, that is also vanilla behaviour.
|
|
|
|
+ // noinspection unchecked
|
|
|
|
+ return (DataWatcher.Item<T>) array[id];
|
|
|
|
+ } catch (Throwable cause) {
|
|
|
|
+ // Move to another method so this function can be in-lined better
|
|
|
|
+ throw onGetException(cause, data);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static <T> ReportedException onGetException(Throwable cause, DataWatcherObject<T> data) {
|
|
|
|
+ CrashReport report = CrashReport.a(cause, "Getting synced entity data");
|
|
|
|
+
|
|
|
|
+ CrashReportSystemDetails section = report.a("Synced entity data");
|
|
|
|
+ section.a("Data ID", data);
|
|
|
|
+
|
|
|
|
+ return new ReportedException(report);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Yatopia lithium end
|
|
|
|
+
|
|
|
|
public DataWatcher(Entity entity) {
|
|
|
|
this.entity = entity;
|
|
|
|
}
|
2020-08-13 17:53:32 +02:00
|
|
|
@@ -91,7 +162,8 @@ public class DataWatcher {
|
2020-08-06 20:54:26 +02:00
|
|
|
DataWatcher.Item<T> datawatcher_item = new DataWatcher.Item<>(datawatcherobject, t0);
|
|
|
|
|
|
|
|
// this.lock.writeLock().lock(); // Spigot - not required
|
|
|
|
- this.entries.put(datawatcherobject.a(), datawatcher_item);
|
|
|
|
+ //this.entries.put(datawatcherobject.a(), datawatcher_item);
|
|
|
|
+ this.onAddTrackedDataInsertMap(this.entries, datawatcherobject.a(), datawatcher_item); // Yatopia lithium
|
|
|
|
this.f = false;
|
|
|
|
// this.lock.writeLock().unlock(); // Spigot - not required
|
|
|
|
}
|
2020-08-13 17:53:32 +02:00
|
|
|
@@ -122,7 +194,8 @@ public class DataWatcher {
|
2020-08-06 20:54:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public <T> T get(DataWatcherObject<T> datawatcherobject) {
|
|
|
|
- return this.b(datawatcherobject).b();
|
2020-08-11 20:40:29 +02:00
|
|
|
+ return getEntry(datawatcherobject).b(); // Yatopia
|
2020-08-06 20:54:26 +02:00
|
|
|
+ //return this.b(datawatcherobject).b();
|
|
|
|
}
|
|
|
|
|
|
|
|
public <T> void set(DataWatcherObject<T> datawatcherobject, T t0) {
|