mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-23 17:09:29 +00:00
Added some optimizations (#164)
* uwu * reorder * Change author * Sync upstream * Lithium: equipment tracking * Faster CraftServer#getworlds list creation Co-Authored-By: Kobe ⑧ <102713261+HaHaWTH@users.noreply.github.com>
This commit is contained in:
32
patches/server/0102-Remove-stream-in-GateBehavior.patch
Normal file
32
patches/server/0102-Remove-stream-in-GateBehavior.patch
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Taiyou06 <kaandindar21@gmail.com>
|
||||||
|
Date: Tue, 9 Nov 2077 00:00:00 +0800
|
||||||
|
Subject: [PATCH] Remove stream in GateBehavior
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java b/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java
|
||||||
|
index d4581127366736c54f74e4ef7479236b18fb487d..67aa59deebdf47e53d9f6949b26c9b313de45035 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java
|
||||||
|
@@ -73,9 +73,20 @@ public class GateBehavior<E extends LivingEntity> implements BehaviorControl<E>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Paper end - Perf: Remove streams from hot code
|
||||||
|
- if (this.behaviors.stream().noneMatch(task -> task.getStatus() == Behavior.Status.RUNNING)) {
|
||||||
|
+
|
||||||
|
+ // Leaf start - Remove more streams in GateBehavior
|
||||||
|
+ boolean hasRunningTask = false;
|
||||||
|
+ for (final BehaviorControl<? super E> task : this.behaviors) {
|
||||||
|
+ if (task.getStatus() == Behavior.Status.RUNNING) {
|
||||||
|
+ hasRunningTask = true;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!hasRunningTask) {
|
||||||
|
this.doStop(world, entity, time);
|
||||||
|
}
|
||||||
|
+ // Leaf end - Remove more streams in GateBehavior
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Taiyou06 <kaandindar21@gmail.com>
|
||||||
|
Date: Tue, 9 Nov 2077 00:00:00 +0800
|
||||||
|
Subject: [PATCH] Collect then startEachNonRunningBehavior in Brain
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/entity/ai/Brain.java b/src/main/java/net/minecraft/world/entity/ai/Brain.java
|
||||||
|
index 65bd8c2cccd0a4a68984ea8ff4cd3cf365330630..aeb74b96704e0f187178e2ae106e0a3f6d95717c 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/entity/ai/Brain.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/entity/ai/Brain.java
|
||||||
|
@@ -466,20 +466,30 @@ public class Brain<E extends LivingEntity> {
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startEachNonRunningBehavior(ServerLevel world, E entity) {
|
||||||
|
- long l = world.getGameTime();
|
||||||
|
+ // Leaf start - Collect first then start
|
||||||
|
+ final long gameTime = world.getGameTime();
|
||||||
|
|
||||||
|
- for (Map<Activity, Set<BehaviorControl<? super E>>> map : this.availableBehaviorsByPriority.values()) {
|
||||||
|
- for (Entry<Activity, Set<BehaviorControl<? super E>>> entry : map.entrySet()) {
|
||||||
|
- Activity activity = entry.getKey();
|
||||||
|
- if (this.activeActivities.contains(activity)) {
|
||||||
|
- for (BehaviorControl<? super E> behaviorControl : entry.getValue()) {
|
||||||
|
- if (behaviorControl.getStatus() == Behavior.Status.STOPPED) {
|
||||||
|
- behaviorControl.tryStart(world, entity, l);
|
||||||
|
+ List<BehaviorControl<? super E>> behaviorsToStart = new ObjectArrayList<>();
|
||||||
|
+
|
||||||
|
+ for (Activity activeActivity : this.activeActivities) {
|
||||||
|
+ for (Map<Activity, Set<BehaviorControl<? super E>>> priorityMap : this.availableBehaviorsByPriority.values()) {
|
||||||
|
+ Set<BehaviorControl<? super E>> behaviors = priorityMap.get(activeActivity);
|
||||||
|
+
|
||||||
|
+ if (behaviors != null && !behaviors.isEmpty()) {
|
||||||
|
+ for (BehaviorControl<? super E> behavior : behaviors) {
|
||||||
|
+ if (behavior.getStatus() == Behavior.Status.STOPPED) {
|
||||||
|
+ behaviorsToStart.add(behavior);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ if (!behaviorsToStart.isEmpty()) {
|
||||||
|
+ for (BehaviorControl<? super E> behavior : behaviorsToStart) {
|
||||||
|
+ behavior.tryStart(world, entity, gameTime);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // Leaf end - Collect first then start
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tickEachRunningBehavior(ServerLevel world, E entity) {
|
||||||
741
patches/server/0152-Lithium-equipment-tracking.patch
Normal file
741
patches/server/0152-Lithium-equipment-tracking.patch
Normal file
@@ -0,0 +1,741 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
|
||||||
|
Date: Tue, 9 Nov 2077 00:00:00 +0800
|
||||||
|
Subject: [PATCH] Lithium: equipment tracking
|
||||||
|
|
||||||
|
This patch is based on the following mixins:
|
||||||
|
* "net/caffeinemc/mods/lithium/mixin/util/
|
||||||
|
item_component_and_count_tracking/PatchedDataComponentMapMixin.java"
|
||||||
|
* "net/caffeinemc/mods/lithium/mixin/util/item_component_and_count_tracking/ItemStackMixin.java"
|
||||||
|
* "net/caffeinemc/mods/lithium/mixin/entity/
|
||||||
|
equipment_tracking/equipment_changes/LivingEntityMixin.java"
|
||||||
|
* "net/caffeinemc/mods/lithium/mixin/entity/equipment_tracking/ArmorStandMixin.java"
|
||||||
|
* "net/caffeinemc/mods/lithium/mixin/entity/equipment_tracking/LivingEntityMixin.java"
|
||||||
|
* "net/caffeinemc/mods/lithium/mixin/entity/equipment_tracking/MobMixin.java"
|
||||||
|
* "net/caffeinemc/mods/lithium/mixin/entity/equipment_tracking/
|
||||||
|
enchantment_ticking/LivingEntityMixin.java"
|
||||||
|
* "net/caffeinemc/mods/lithium/common/entity/EquipmentEntity.java"
|
||||||
|
* "net/caffeinemc/mods/lithium/common/util/change_tracking/ChangePublisher.java"
|
||||||
|
* "net/caffeinemc/mods/lithium/common/util/change_tracking/ChangeSubscriber.java"
|
||||||
|
|
||||||
|
As part of: Lithium (https://github.com/CaffeineMC/lithium-fabric)
|
||||||
|
Licensed under: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html)
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/caffeinemc/mods/lithium/common/entity/EquipmentEntity.java b/src/main/java/net/caffeinemc/mods/lithium/common/entity/EquipmentEntity.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..05604b8f149c13454983d29a2c4dfe1e11dec1fb
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/net/caffeinemc/mods/lithium/common/entity/EquipmentEntity.java
|
||||||
|
@@ -0,0 +1,16 @@
|
||||||
|
+package net.caffeinemc.mods.lithium.common.entity;
|
||||||
|
+
|
||||||
|
+import net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber;
|
||||||
|
+import net.minecraft.world.item.ItemStack;
|
||||||
|
+
|
||||||
|
+public interface EquipmentEntity {
|
||||||
|
+ void onEquipmentReplaced(ItemStack oldStack, ItemStack newStack);
|
||||||
|
+
|
||||||
|
+ interface EquipmentTrackingEntity {
|
||||||
|
+ void onEquipmentChanged();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ interface TickableEnchantmentTrackingEntity extends ChangeSubscriber.EnchantmentSubscriber<ItemStack> {
|
||||||
|
+ void updateHasTickableEnchantments(ItemStack oldStack, ItemStack newStack);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
\ No newline at end of file
|
||||||
|
diff --git a/src/main/java/net/caffeinemc/mods/lithium/common/util/change_tracking/ChangePublisher.java b/src/main/java/net/caffeinemc/mods/lithium/common/util/change_tracking/ChangePublisher.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..9a39b58e8aa3a472a9b5a5af1e5ee6d4eaa4d6e4
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/net/caffeinemc/mods/lithium/common/util/change_tracking/ChangePublisher.java
|
||||||
|
@@ -0,0 +1,17 @@
|
||||||
|
+package net.caffeinemc.mods.lithium.common.util.change_tracking;
|
||||||
|
+
|
||||||
|
+import net.minecraft.world.item.ItemStack;
|
||||||
|
+
|
||||||
|
+public interface ChangePublisher<T> {
|
||||||
|
+ void subscribe(ChangeSubscriber<T> subscriber, int subscriberData);
|
||||||
|
+
|
||||||
|
+ int unsubscribe(ChangeSubscriber<T> subscriber);
|
||||||
|
+
|
||||||
|
+ default void unsubscribeWithData(ChangeSubscriber<T> subscriber, int index) {
|
||||||
|
+ throw new UnsupportedOperationException("Only implemented for ItemStacks");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ default boolean isSubscribedWithData(ChangeSubscriber<ItemStack> subscriber, int subscriberData) {
|
||||||
|
+ throw new UnsupportedOperationException("Only implemented for ItemStacks");
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/net/caffeinemc/mods/lithium/common/util/change_tracking/ChangeSubscriber.java b/src/main/java/net/caffeinemc/mods/lithium/common/util/change_tracking/ChangeSubscriber.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..ef206b9ebbd555a786dad37e1ab1bc48e11961cb
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/net/caffeinemc/mods/lithium/common/util/change_tracking/ChangeSubscriber.java
|
||||||
|
@@ -0,0 +1,190 @@
|
||||||
|
+package net.caffeinemc.mods.lithium.common.util.change_tracking;
|
||||||
|
+
|
||||||
|
+import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
|
+import org.jetbrains.annotations.NotNull;
|
||||||
|
+import org.jetbrains.annotations.Nullable;
|
||||||
|
+
|
||||||
|
+import java.util.ArrayList;
|
||||||
|
+import net.minecraft.world.item.ItemStack;
|
||||||
|
+
|
||||||
|
+public interface ChangeSubscriber<T> {
|
||||||
|
+
|
||||||
|
+ static <T> ChangeSubscriber<T> combine(ChangeSubscriber<T> prevSubscriber, int prevSData, @NotNull ChangeSubscriber<T> newSubscriber, int newSData) {
|
||||||
|
+ if (prevSubscriber == null) {
|
||||||
|
+ return newSubscriber;
|
||||||
|
+ } else if (prevSubscriber instanceof Multi) {
|
||||||
|
+ ArrayList<ChangeSubscriber<T>> subscribers = new ArrayList<>(((Multi<T>) prevSubscriber).subscribers);
|
||||||
|
+ IntArrayList subscriberDatas = new IntArrayList(((Multi<T>) prevSubscriber).subscriberDatas);
|
||||||
|
+ subscribers.add(newSubscriber);
|
||||||
|
+ subscriberDatas.add(newSData);
|
||||||
|
+ return new Multi<>(subscribers, subscriberDatas);
|
||||||
|
+ } else {
|
||||||
|
+ ArrayList<ChangeSubscriber<T>> subscribers = new ArrayList<>();
|
||||||
|
+ IntArrayList subscriberDatas = new IntArrayList();
|
||||||
|
+ subscribers.add(prevSubscriber);
|
||||||
|
+ subscriberDatas.add(prevSData);
|
||||||
|
+ subscribers.add(newSubscriber);
|
||||||
|
+ subscriberDatas.add(newSData);
|
||||||
|
+ return new Multi<>(subscribers, subscriberDatas);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ static <T> ChangeSubscriber<T> without(ChangeSubscriber<T> prevSubscriber, ChangeSubscriber<T> removedSubscriber) {
|
||||||
|
+ return without(prevSubscriber, removedSubscriber, 0, false);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ static <T> ChangeSubscriber<T> without(ChangeSubscriber<T> prevSubscriber, ChangeSubscriber<T> removedSubscriber, int removedSubscriberData, boolean matchData) {
|
||||||
|
+ if (prevSubscriber == removedSubscriber) {
|
||||||
|
+ return null;
|
||||||
|
+ } else if (prevSubscriber instanceof Multi<T> multi) {
|
||||||
|
+ int index = multi.indexOf(removedSubscriber, removedSubscriberData, matchData);
|
||||||
|
+ if (index != -1) {
|
||||||
|
+ if (multi.subscribers.size() == 2) {
|
||||||
|
+ return multi.subscribers.get(1 - index);
|
||||||
|
+ } else {
|
||||||
|
+ ArrayList<ChangeSubscriber<T>> subscribers = new ArrayList<>(multi.subscribers);
|
||||||
|
+ IntArrayList subscriberDatas = new IntArrayList(multi.subscriberDatas);
|
||||||
|
+ subscribers.remove(index);
|
||||||
|
+ subscriberDatas.removeInt(index);
|
||||||
|
+
|
||||||
|
+ return new Multi<>(subscribers, subscriberDatas);
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ return prevSubscriber;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ return prevSubscriber;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ static <T> int dataWithout(ChangeSubscriber<T> prevSubscriber, ChangeSubscriber<T> removedSubscriber, int subscriberData) {
|
||||||
|
+ return dataWithout(prevSubscriber, removedSubscriber, subscriberData, 0, false);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ static <T> int dataWithout(ChangeSubscriber<T> prevSubscriber, ChangeSubscriber<T> removedSubscriber, int subscriberData, int removedSubscriberData, boolean matchData) {
|
||||||
|
+ if (prevSubscriber instanceof Multi<T> multi) {
|
||||||
|
+ int index = multi.indexOf(removedSubscriber, removedSubscriberData, matchData);
|
||||||
|
+ if (index != -1) {
|
||||||
|
+ if (multi.subscribers.size() == 2) {
|
||||||
|
+ return multi.subscriberDatas.getInt(1 - index);
|
||||||
|
+ } else {
|
||||||
|
+ return subscriberData;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ return subscriberData;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return prevSubscriber == removedSubscriber ? 0 : subscriberData;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ static int dataOf(ChangeSubscriber<?> subscribers, ChangeSubscriber<?> subscriber, int subscriberData) {
|
||||||
|
+ return subscribers instanceof Multi<?> multi ? multi.subscriberDatas.getInt(multi.subscribers.indexOf(subscriber)) : subscriberData;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ static boolean containsSubscriber(ChangeSubscriber<ItemStack> subscriber, int subscriberData, ChangeSubscriber<ItemStack> subscriber1, int subscriberData1) {
|
||||||
|
+ if (subscriber instanceof Multi<ItemStack> multi) {
|
||||||
|
+ return multi.indexOf(subscriber1, subscriberData1, true) != -1;
|
||||||
|
+ }
|
||||||
|
+ return subscriber == subscriber1 && subscriberData == subscriberData1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Notify the subscriber that the publisher will be changed immediately after this call.
|
||||||
|
+ * @param publisher The publisher that is about to change
|
||||||
|
+ * @param subscriberData The data associated with the subscriber, given when the subscriber was added
|
||||||
|
+ */
|
||||||
|
+ void notify(@Nullable T publisher, int subscriberData);
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Notify the subscriber about being unsubscribed from the publisher. Used when the publisher becomes invalid.
|
||||||
|
+ * The subscriber should not attempt to unsubscribe itself from the publisher in this method.
|
||||||
|
+ *
|
||||||
|
+ * @param publisher The publisher unsubscribed from
|
||||||
|
+ * @param subscriberData The data associated with the subscriber, given when the subscriber was added
|
||||||
|
+ */
|
||||||
|
+ void forceUnsubscribe(T publisher, int subscriberData);
|
||||||
|
+
|
||||||
|
+ interface CountChangeSubscriber<T> extends ChangeSubscriber<T> {
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Notify the subscriber that the publisher's count data will be changed immediately after this call.
|
||||||
|
+ * @param publisher The publisher that is about to change
|
||||||
|
+ * @param subscriberData The data associated with the subscriber, given when the subscriber was added
|
||||||
|
+ * @param newCount The new count of the publisher
|
||||||
|
+ */
|
||||||
|
+ void notifyCount(T publisher, int subscriberData, int newCount);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ interface EnchantmentSubscriber<T> extends ChangeSubscriber<T> {
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Notify the subscriber that the publisher's enchantment data has been changed immediately before this call.
|
||||||
|
+ * @param publisher The publisher that has changed
|
||||||
|
+ * @param subscriberData The data associated with the subscriber, given when the subscriber was added
|
||||||
|
+ */
|
||||||
|
+ void notifyAfterEnchantmentChange(T publisher, int subscriberData);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ class Multi<T> implements CountChangeSubscriber<T>, EnchantmentSubscriber<T> {
|
||||||
|
+ private final ArrayList<ChangeSubscriber<T>> subscribers;
|
||||||
|
+ private final IntArrayList subscriberDatas;
|
||||||
|
+
|
||||||
|
+ public Multi(ArrayList<ChangeSubscriber<T>> subscribers, IntArrayList subscriberDatas) {
|
||||||
|
+ this.subscribers = subscribers;
|
||||||
|
+ this.subscriberDatas = subscriberDatas;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void notify(T publisher, int subscriberData) {
|
||||||
|
+ ArrayList<ChangeSubscriber<T>> changeSubscribers = this.subscribers;
|
||||||
|
+ for (int i = 0; i < changeSubscribers.size(); i++) {
|
||||||
|
+ ChangeSubscriber<T> subscriber = changeSubscribers.get(i);
|
||||||
|
+ subscriber.notify(publisher, this.subscriberDatas.getInt(i));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void forceUnsubscribe(T publisher, int subscriberData) {
|
||||||
|
+ ArrayList<ChangeSubscriber<T>> changeSubscribers = this.subscribers;
|
||||||
|
+ for (int i = 0; i < changeSubscribers.size(); i++) {
|
||||||
|
+ ChangeSubscriber<T> subscriber = changeSubscribers.get(i);
|
||||||
|
+ subscriber.forceUnsubscribe(publisher, this.subscriberDatas.getInt(i));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void notifyCount(T publisher, int subscriberData, int newCount) {
|
||||||
|
+ ArrayList<ChangeSubscriber<T>> changeSubscribers = this.subscribers;
|
||||||
|
+ for (int i = 0; i < changeSubscribers.size(); i++) {
|
||||||
|
+ ChangeSubscriber<T> subscriber = changeSubscribers.get(i);
|
||||||
|
+ if (subscriber instanceof ChangeSubscriber.CountChangeSubscriber<T> countChangeSubscriber) {
|
||||||
|
+ countChangeSubscriber.notifyCount(publisher, this.subscriberDatas.getInt(i), newCount);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ int indexOf(ChangeSubscriber<T> subscriber, int subscriberData, boolean matchData) {
|
||||||
|
+ if (!matchData) {
|
||||||
|
+ return this.subscribers.indexOf(subscriber);
|
||||||
|
+ } else {
|
||||||
|
+ for (int i = 0; i < this.subscribers.size(); i++) {
|
||||||
|
+ if (this.subscribers.get(i) == subscriber && this.subscriberDatas.getInt(i) == subscriberData) {
|
||||||
|
+ return i;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void notifyAfterEnchantmentChange(T publisher, int subscriberData) {
|
||||||
|
+ ArrayList<ChangeSubscriber<T>> changeSubscribers = this.subscribers;
|
||||||
|
+ for (int i = 0; i < changeSubscribers.size(); i++) {
|
||||||
|
+ ChangeSubscriber<T> subscriber = changeSubscribers.get(i);
|
||||||
|
+ if (subscriber instanceof ChangeSubscriber.EnchantmentSubscriber<T> enchantmentSubscriber) {
|
||||||
|
+ enchantmentSubscriber.notifyAfterEnchantmentChange(publisher, this.subscriberDatas.getInt(i));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
\ No newline at end of file
|
||||||
|
diff --git a/src/main/java/net/minecraft/core/component/PatchedDataComponentMap.java b/src/main/java/net/minecraft/core/component/PatchedDataComponentMap.java
|
||||||
|
index 22da75d8197de29a150c9eade7994deecae53a10..aa8a5938984d6860deb67a36f85c83d96057d753 100644
|
||||||
|
--- a/src/main/java/net/minecraft/core/component/PatchedDataComponentMap.java
|
||||||
|
+++ b/src/main/java/net/minecraft/core/component/PatchedDataComponentMap.java
|
||||||
|
@@ -14,10 +14,11 @@ import java.util.Map.Entry;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
-public final class PatchedDataComponentMap implements DataComponentMap {
|
||||||
|
+public final class PatchedDataComponentMap implements DataComponentMap, net.caffeinemc.mods.lithium.common.util.change_tracking.ChangePublisher<PatchedDataComponentMap> { // Leaf - Lithium equipment tracking
|
||||||
|
private final DataComponentMap prototype;
|
||||||
|
private Reference2ObjectMap<DataComponentType<?>, Optional<?>> patch;
|
||||||
|
private boolean copyOnWrite;
|
||||||
|
+ private net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<PatchedDataComponentMap> subscriber; // Leaf - Lithium equipment tracking
|
||||||
|
|
||||||
|
public PatchedDataComponentMap(DataComponentMap baseComponents) {
|
||||||
|
this(baseComponents, Reference2ObjectMaps.emptyMap(), true);
|
||||||
|
@@ -128,6 +129,9 @@ public final class PatchedDataComponentMap implements DataComponentMap {
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureMapOwnership() {
|
||||||
|
+ if (this.subscriber != null) {
|
||||||
|
+ this.subscriber.notify(this, 0);
|
||||||
|
+ }
|
||||||
|
if (this.copyOnWrite) {
|
||||||
|
this.patch = new Reference2ObjectArrayMap<>(this.patch);
|
||||||
|
this.copyOnWrite = false;
|
||||||
|
@@ -210,6 +214,22 @@ public final class PatchedDataComponentMap implements DataComponentMap {
|
||||||
|
return new PatchedDataComponentMap(this.prototype, this.patch, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Leaf start - Lithium equipment tracking
|
||||||
|
+ @Override
|
||||||
|
+ public void subscribe(net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<PatchedDataComponentMap> subscriber, int subscriberData) {
|
||||||
|
+ if (subscriberData != 0) {
|
||||||
|
+ throw new UnsupportedOperationException("ComponentMapImpl does not support subscriber data");
|
||||||
|
+ }
|
||||||
|
+ this.subscriber = net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.combine(this.subscriber, 0, subscriber, 0);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public int unsubscribe(net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<PatchedDataComponentMap> subscriber) {
|
||||||
|
+ this.subscriber = net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.without(this.subscriber, subscriber);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ // Leaf end - Lithium equipment tracking
|
||||||
|
+
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
if (this == object) {
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||||
|
index 9de85972ba32fd2373f70f708aa1bfc6067e6e1c..3ae75230a4250665df7a72aff1d84317b81fc077 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||||
|
@@ -157,7 +157,7 @@ import org.bukkit.event.entity.EntityTeleportEvent;
|
||||||
|
import org.bukkit.event.player.PlayerItemConsumeEvent;
|
||||||
|
// CraftBukkit end
|
||||||
|
|
||||||
|
-public abstract class LivingEntity extends Entity implements Attackable {
|
||||||
|
+public abstract class LivingEntity extends Entity implements Attackable, net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.CountChangeSubscriber<ItemStack>, net.caffeinemc.mods.lithium.common.entity.EquipmentEntity, net.caffeinemc.mods.lithium.common.entity.EquipmentEntity.TickableEnchantmentTrackingEntity, net.caffeinemc.mods.lithium.common.entity.EquipmentEntity.EquipmentTrackingEntity { // Leaf - Lithium equipment tracking
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogUtils.getLogger();
|
||||||
|
private static final String TAG_ACTIVE_EFFECTS = "active_effects";
|
||||||
|
@@ -290,6 +290,10 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||||
|
public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API
|
||||||
|
protected boolean shouldBurnInDay = false; public boolean shouldBurnInDay() { return this.shouldBurnInDay; } public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } // Purpur - API for any mob to burn daylight
|
||||||
|
|
||||||
|
+ // Leaf start - Lithium equipment tracking
|
||||||
|
+ private boolean maybeHasTickableEnchantments = this instanceof net.minecraft.world.entity.player.Player;
|
||||||
|
+ private boolean equipmentChanged = true;
|
||||||
|
+ // Leaf end - Lithium equipment tracking
|
||||||
|
@Override
|
||||||
|
public float getBukkitYaw() {
|
||||||
|
return this.getYHeadRot();
|
||||||
|
@@ -442,7 +446,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||||
|
|
||||||
|
Level world = this.level();
|
||||||
|
|
||||||
|
- if (world instanceof ServerLevel worldserver) {
|
||||||
|
+ if (this.maybeHasTickableEnchantments && world instanceof ServerLevel worldserver) { // Leaf - Lithium equipment tracking
|
||||||
|
EnchantmentHelper.tickEffects(worldserver, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -735,6 +739,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||||
|
boolean flag = itemstack1.isEmpty() && itemstack.isEmpty();
|
||||||
|
|
||||||
|
if (!flag && !ItemStack.isSameItemSameComponents(itemstack, itemstack1) && !this.firstTick) {
|
||||||
|
+ this.onEquipmentReplaced(itemstack, itemstack1); // Leaf - Lithium equipment tracking
|
||||||
|
Equipable equipable = Equipable.get(itemstack1);
|
||||||
|
|
||||||
|
if (!this.level().isClientSide() && !this.isSpectator()) {
|
||||||
|
@@ -3382,6 +3387,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||||
|
Map<EquipmentSlot, ItemStack> map = this.collectEquipmentChanges();
|
||||||
|
|
||||||
|
if (map != null) {
|
||||||
|
+ if (!(this instanceof net.minecraft.world.entity.player.Player)) this.equipmentChanged = false; // Leaf - Lithium equipment tracking
|
||||||
|
this.handleHandSwap(map);
|
||||||
|
if (!map.isEmpty()) {
|
||||||
|
this.handleEquipmentChanges(map);
|
||||||
|
@@ -3392,6 +3398,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Map<EquipmentSlot, ItemStack> collectEquipmentChanges() {
|
||||||
|
+ if (!this.equipmentChanged) return null; // Leaf - Lithium equipment tracking
|
||||||
|
Map<EquipmentSlot, ItemStack> map = null;
|
||||||
|
EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // Gale - JettPack - reduce array allocations
|
||||||
|
int i = aenumitemslot.length;
|
||||||
|
@@ -4848,6 +4855,80 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||||
|
flag = true;
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
+ // Leaf start - Lithium entity equipment tracking
|
||||||
|
+ @Override
|
||||||
|
+ public void updateHasTickableEnchantments(ItemStack oldStack, ItemStack newStack) {
|
||||||
|
+ if (!this.maybeHasTickableEnchantments) {
|
||||||
|
+ this.maybeHasTickableEnchantments = stackHasTickableEnchantment(newStack);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void notifyAfterEnchantmentChange(ItemStack publisher, int subscriberData) {
|
||||||
|
+ if (!this.maybeHasTickableEnchantments) {
|
||||||
|
+ this.maybeHasTickableEnchantments = stackHasTickableEnchantment(publisher);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void onEquipmentChanged() {
|
||||||
|
+ this.equipmentChanged = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private static boolean stackHasTickableEnchantment(ItemStack stack) {
|
||||||
|
+ if (!stack.isEmpty()) {
|
||||||
|
+ net.minecraft.world.item.enchantment.ItemEnchantments enchantments = stack.get(DataComponents.ENCHANTMENTS);
|
||||||
|
+ if (enchantments != null && !enchantments.isEmpty()) {
|
||||||
|
+ for (Holder<Enchantment> enchantmentEntry : enchantments.keySet()) {
|
||||||
|
+ if (!enchantmentEntry.value().getEffects(net.minecraft.world.item.enchantment.EnchantmentEffectComponents.TICK).isEmpty()) {
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ @Override
|
||||||
|
+ public void notify(@Nullable ItemStack publisher, int zero) {
|
||||||
|
+ if (this instanceof EquipmentTrackingEntity equipmentTrackingEntity) {
|
||||||
|
+ equipmentTrackingEntity.onEquipmentChanged();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void notifyCount(ItemStack publisher, int zero, int newCount) {
|
||||||
|
+ if (newCount == 0) {
|
||||||
|
+ //noinspection unchecked
|
||||||
|
+ ((net.caffeinemc.mods.lithium.common.util.change_tracking.ChangePublisher<ItemStack>) (Object) publisher).unsubscribeWithData(this, zero);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ this.onEquipmentReplaced(publisher, ItemStack.EMPTY);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void forceUnsubscribe(ItemStack publisher, int zero) {
|
||||||
|
+ throw new UnsupportedOperationException();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void onEquipmentReplaced(ItemStack oldStack, ItemStack newStack) {
|
||||||
|
+ if (this instanceof TickableEnchantmentTrackingEntity enchantmentTrackingEntity) {
|
||||||
|
+ enchantmentTrackingEntity.updateHasTickableEnchantments(oldStack, newStack);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (this instanceof EquipmentTrackingEntity equipmentTrackingEntity) {
|
||||||
|
+ equipmentTrackingEntity.onEquipmentChanged();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!oldStack.isEmpty()) {
|
||||||
|
+ ((net.caffeinemc.mods.lithium.common.util.change_tracking.ChangePublisher<ItemStack>) oldStack).unsubscribeWithData(this, 0);
|
||||||
|
+ }
|
||||||
|
+ if (!newStack.isEmpty()) {
|
||||||
|
+ ((net.caffeinemc.mods.lithium.common.util.change_tracking.ChangePublisher<ItemStack>) newStack).subscribe(this, 0);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // Leaf end - Lithium entity equipment tracking
|
||||||
|
|
||||||
|
public static record Fallsounds(SoundEvent small, SoundEvent big) {
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||||
|
index 9d196c8a8a0dc49a54264471429b6ff6da8c2b06..2ba607df6ee0500a7ac51cefd076840ae35e4827 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||||
|
@@ -97,7 +97,7 @@ import org.bukkit.event.entity.EntityUnleashEvent;
|
||||||
|
import org.bukkit.event.entity.EntityUnleashEvent.UnleashReason;
|
||||||
|
// CraftBukkit end
|
||||||
|
|
||||||
|
-public abstract class Mob extends LivingEntity implements EquipmentUser, Leashable, Targeting {
|
||||||
|
+public abstract class Mob extends LivingEntity implements EquipmentUser, Leashable, Targeting, net.caffeinemc.mods.lithium.common.entity.EquipmentEntity { // Leaf - Lithium equipment tracking
|
||||||
|
|
||||||
|
private static final EntityDataAccessor<Byte> DATA_MOB_FLAGS_ID = SynchedEntityData.defineId(Mob.class, EntityDataSerializers.BYTE);
|
||||||
|
private static final int MOB_FLAG_NO_AI = 1;
|
||||||
|
@@ -583,6 +583,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readAdditionalSaveData(CompoundTag nbt) {
|
||||||
|
+ ItemStack prevBodyArmor = this.bodyArmorItem; // Leaf - Lithium equipment tracking
|
||||||
|
super.readAdditionalSaveData(nbt);
|
||||||
|
|
||||||
|
// CraftBukkit start - If looting or persistence is false only use it if it was set after we started using it
|
||||||
|
@@ -607,7 +608,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||||
|
|
||||||
|
for (i = 0; i < this.armorItems.size(); ++i) {
|
||||||
|
nbttagcompound1 = nbttaglist.getCompound(i);
|
||||||
|
- this.armorItems.set(i, ItemStack.parseOptional(this.registryAccess(), nbttagcompound1));
|
||||||
|
+ // Leaf start - Lithium equipment tracking
|
||||||
|
+ ItemStack currStack = ItemStack.parseOptional(this.registryAccess(), nbttagcompound1);
|
||||||
|
+ ItemStack prevStack = this.armorItems.set(i, currStack);
|
||||||
|
+ this.trackEquipChange(prevStack, currStack);
|
||||||
|
+ // Leaf end - Lithium equipment tracking
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -624,7 +629,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||||
|
|
||||||
|
for (i = 0; i < this.handItems.size(); ++i) {
|
||||||
|
nbttagcompound1 = nbttaglist.getCompound(i);
|
||||||
|
- this.handItems.set(i, ItemStack.parseOptional(this.registryAccess(), nbttagcompound1));
|
||||||
|
+ // Leaf start - Lithium equipment tracking
|
||||||
|
+ ItemStack currStack = ItemStack.parseOptional(this.registryAccess(), nbttagcompound1);
|
||||||
|
+ ItemStack prevStack = this.handItems.set(i, currStack);
|
||||||
|
+ this.trackEquipChange(prevStack, currStack);
|
||||||
|
+ // Leaf end - Lithium equipment tracking
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -661,6 +670,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||||
|
this.ticksSinceLastInteraction = nbt.getInt("Purpur.ticksSinceLastInteraction");
|
||||||
|
}
|
||||||
|
// Purpur end
|
||||||
|
+ // Leaf start - Lithium equipment tracking
|
||||||
|
+ if (prevBodyArmor != this.bodyArmorItem) {
|
||||||
|
+ this.trackEquipChange(prevBodyArmor, this.bodyArmorItem);
|
||||||
|
+ }
|
||||||
|
+ // Leaf end - Lithium equipment tracking
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@@ -1865,4 +1879,10 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Purpur end
|
||||||
|
+
|
||||||
|
+ // Leaf start - Lithium equipment tracking
|
||||||
|
+ private void trackEquipChange(ItemStack prevStack, ItemStack currStack) {
|
||||||
|
+ this.onEquipmentReplaced(prevStack, currStack);
|
||||||
|
+ }
|
||||||
|
+ // Leaf end - Lithium equipment tracking
|
||||||
|
}
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||||
|
index 3bb46ed871fd56bbbe52cfd2575f9e853e03cd73..6d73ae2a453feeae0aea67bb555c64a0a288c376 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||||
|
@@ -52,7 +52,7 @@ import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.player.PlayerArmorStandManipulateEvent;
|
||||||
|
// CraftBukkit end
|
||||||
|
|
||||||
|
-public class ArmorStand extends LivingEntity {
|
||||||
|
+public class ArmorStand extends LivingEntity implements net.caffeinemc.mods.lithium.common.entity.EquipmentEntity { // Leaf - Lithium equipment tracking
|
||||||
|
|
||||||
|
public static final int WOBBLE_TIME = 5;
|
||||||
|
private static final boolean ENABLE_ARMS = true;
|
||||||
|
@@ -269,7 +269,11 @@ public class ArmorStand extends LivingEntity {
|
||||||
|
|
||||||
|
for (i = 0; i < this.armorItems.size(); ++i) {
|
||||||
|
nbttagcompound1 = nbttaglist.getCompound(i);
|
||||||
|
- this.armorItems.set(i, ItemStack.parseOptional(this.registryAccess(), nbttagcompound1));
|
||||||
|
+ // Leaf start - Lithium equipment tracking
|
||||||
|
+ ItemStack currElement = ItemStack.parseOptional(this.registryAccess(), nbttagcompound1);
|
||||||
|
+ ItemStack prevElement = this.armorItems.set(i, currElement);
|
||||||
|
+ this.trackEquipChange(prevElement, currElement);
|
||||||
|
+ // Leaf end - Lithium equipment tracking
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -278,7 +282,11 @@ public class ArmorStand extends LivingEntity {
|
||||||
|
|
||||||
|
for (i = 0; i < this.handItems.size(); ++i) {
|
||||||
|
nbttagcompound1 = nbttaglist.getCompound(i);
|
||||||
|
- this.handItems.set(i, ItemStack.parseOptional(this.registryAccess(), nbttagcompound1));
|
||||||
|
+ // Leaf start - Lithium equipment tracking
|
||||||
|
+ ItemStack currStack = ItemStack.parseOptional(this.registryAccess(), nbttagcompound1);
|
||||||
|
+ ItemStack prevStack = this.handItems.set(i, currStack);
|
||||||
|
+ this.trackEquipChange(prevStack, currStack);
|
||||||
|
+ // Leaf end - Lithium equipment tracking
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -640,7 +648,11 @@ public class ArmorStand extends LivingEntity {
|
||||||
|
itemstack = (ItemStack) this.handItems.get(i);
|
||||||
|
if (!itemstack.isEmpty()) {
|
||||||
|
this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
|
||||||
|
- this.handItems.set(i, ItemStack.EMPTY);
|
||||||
|
+ // Leaf start - Lithium equipment tracking
|
||||||
|
+ ItemStack emptyStack = ItemStack.EMPTY;
|
||||||
|
+ ItemStack prevStack = this.handItems.set(i, emptyStack);
|
||||||
|
+ this.trackEquipChange(prevStack, emptyStack);
|
||||||
|
+ // Leaf end - Lithium equipment tracking
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -648,7 +660,11 @@ public class ArmorStand extends LivingEntity {
|
||||||
|
itemstack = (ItemStack) this.armorItems.get(i);
|
||||||
|
if (!itemstack.isEmpty()) {
|
||||||
|
this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
|
||||||
|
- this.armorItems.set(i, ItemStack.EMPTY);
|
||||||
|
+ // Leaf start - Lithium equipment tracking
|
||||||
|
+ ItemStack emptyStack = ItemStack.EMPTY;
|
||||||
|
+ ItemStack prevStack = this.armorItems.set(i, ItemStack.EMPTY);
|
||||||
|
+ this.trackEquipChange(prevStack, emptyStack);
|
||||||
|
+ // Leaf end - Lithium equipment tracking
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.dropAllDeathLoot(world, damageSource); // CraftBukkit - moved from above // Paper
|
||||||
|
@@ -1034,4 +1050,10 @@ public class ArmorStand extends LivingEntity {
|
||||||
|
if (this.canMovementTick && this.canMove) super.aiStep();
|
||||||
|
}
|
||||||
|
// Purpur end
|
||||||
|
+
|
||||||
|
+ // Leaf start - Lithium equipment tracking
|
||||||
|
+ private void trackEquipChange(ItemStack prevStack, ItemStack currStack) {
|
||||||
|
+ this.onEquipmentReplaced(prevStack, currStack);
|
||||||
|
+ }
|
||||||
|
+ // Leaf end - Lithium equipment tracking
|
||||||
|
}
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||||
|
index 933b7519da5330ea8acd05c337201f52cab12c3c..b4fc8fcfb7994705a4307d9b0731bcd55f81d1fd 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||||
|
@@ -120,7 +120,7 @@ import org.bukkit.event.player.PlayerItemDamageEvent;
|
||||||
|
import org.bukkit.event.world.StructureGrowEvent;
|
||||||
|
// CraftBukkit end
|
||||||
|
|
||||||
|
-public final class ItemStack implements DataComponentHolder {
|
||||||
|
+public final class ItemStack implements DataComponentHolder, net.caffeinemc.mods.lithium.common.util.change_tracking.ChangePublisher<ItemStack>, net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<PatchedDataComponentMap> { // Leaf - Lithium equipment tracking
|
||||||
|
|
||||||
|
public static final Codec<Holder<Item>> ITEM_NON_AIR_CODEC = BuiltInRegistries.ITEM.holderByNameCodec().validate((holder) -> {
|
||||||
|
return holder.is((Holder) Items.AIR.builtInRegistryHolder()) ? DataResult.error(() -> {
|
||||||
|
@@ -228,6 +228,11 @@ public final class ItemStack implements DataComponentHolder {
|
||||||
|
private PatchedDataComponentMap components;
|
||||||
|
@Nullable
|
||||||
|
private Entity entityRepresentation;
|
||||||
|
+ // Leaf start - Lithium equipment tracking
|
||||||
|
+ @Nullable
|
||||||
|
+ private net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<ItemStack> subscriber;
|
||||||
|
+ private int subscriberData;
|
||||||
|
+ // Leaf end - Lithium equipment tracking
|
||||||
|
|
||||||
|
private static DataResult<ItemStack> validateStrict(ItemStack stack) {
|
||||||
|
DataResult<Unit> dataresult = ItemStack.validateComponents(stack.getComponents());
|
||||||
|
@@ -1368,6 +1373,23 @@ public final class ItemStack implements DataComponentHolder {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCount(int count) {
|
||||||
|
+ // Leaf start - Lithium equipment tracking
|
||||||
|
+ if (count != this.count) {
|
||||||
|
+ if (this.subscriber instanceof net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.CountChangeSubscriber<ItemStack> countChangeSubscriber) {
|
||||||
|
+ countChangeSubscriber.notifyCount(this, this.subscriberData, count);
|
||||||
|
+ }
|
||||||
|
+ if (count == 0) {
|
||||||
|
+ //Safe because ComponentMapImplMixin implements the interface
|
||||||
|
+ //noinspection unchecked
|
||||||
|
+ ((net.caffeinemc.mods.lithium.common.util.change_tracking.ChangePublisher<PatchedDataComponentMap>) (Object) this.components).unsubscribe(this);
|
||||||
|
+ if (this.subscriber != null) {
|
||||||
|
+ this.subscriber.forceUnsubscribe(this, this.subscriberData);
|
||||||
|
+ this.subscriber = null;
|
||||||
|
+ this.subscriberData = 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // Leaf end - Lithium equipment tracking
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1423,4 +1445,91 @@ public final class ItemStack implements DataComponentHolder {
|
||||||
|
public boolean canBeHurtBy(DamageSource source) {
|
||||||
|
return !this.has(DataComponents.FIRE_RESISTANT) || !source.is(DamageTypeTags.IS_FIRE);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Leaf start - Lithium equipment tracking
|
||||||
|
+ @Override
|
||||||
|
+ public void subscribe(net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<ItemStack> subscriber, int subscriberData) {
|
||||||
|
+ if (this.isEmpty()) {
|
||||||
|
+ throw new IllegalStateException("Cannot subscribe to an empty ItemStack!");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (this.subscriber == null) {
|
||||||
|
+ this.startTrackingChanges();
|
||||||
|
+ }
|
||||||
|
+ this.subscriber = net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.combine(this.subscriber, this.subscriberData, subscriber, subscriberData);
|
||||||
|
+ if (this.subscriber instanceof net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.Multi<?>) {
|
||||||
|
+ this.subscriberData = 0;
|
||||||
|
+ } else {
|
||||||
|
+ this.subscriberData = subscriberData;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public int unsubscribe(net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<ItemStack> subscriber) {
|
||||||
|
+ if (this.isEmpty()) {
|
||||||
|
+ throw new IllegalStateException("Cannot unsubscribe from an empty ItemStack!");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ int retval = net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.dataOf(this.subscriber, subscriber, this.subscriberData);
|
||||||
|
+ this.subscriberData = net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.dataWithout(this.subscriber, subscriber, this.subscriberData);
|
||||||
|
+ this.subscriber = net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.without(this.subscriber, subscriber);
|
||||||
|
+
|
||||||
|
+ if (this.subscriber == null) {
|
||||||
|
+ //noinspection unchecked
|
||||||
|
+ ((net.caffeinemc.mods.lithium.common.util.change_tracking.ChangePublisher<PatchedDataComponentMap>) (Object) this.components).unsubscribe(this);
|
||||||
|
+ }
|
||||||
|
+ return retval;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void unsubscribeWithData(net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<ItemStack> subscriber, int subscriberData) {
|
||||||
|
+ if (this.isEmpty()) {
|
||||||
|
+ throw new IllegalStateException("Cannot unsubscribe from an empty ItemStack!");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ this.subscriberData = net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.dataWithout(this.subscriber, subscriber, this.subscriberData, subscriberData, true);
|
||||||
|
+ this.subscriber = net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.without(this.subscriber, subscriber, subscriberData, true);
|
||||||
|
+
|
||||||
|
+ if (this.subscriber == null) {
|
||||||
|
+ //noinspection unchecked
|
||||||
|
+ ((net.caffeinemc.mods.lithium.common.util.change_tracking.ChangePublisher<PatchedDataComponentMap>) (Object) this.components).unsubscribe(this);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public boolean isSubscribedWithData(net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<ItemStack> subscriber, int subscriberData) {
|
||||||
|
+ if (this.isEmpty()) {
|
||||||
|
+ throw new IllegalStateException("Cannot be subscribed to an empty ItemStack!");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.containsSubscriber(this.subscriber, this.subscriberData, subscriber, subscriberData);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void forceUnsubscribe(PatchedDataComponentMap publisher, int subscriberData) {
|
||||||
|
+ if (publisher != this.components) {
|
||||||
|
+ throw new IllegalStateException("Invalid publisher, expected " + this.components + " but got " + publisher);
|
||||||
|
+ }
|
||||||
|
+ this.subscriber.forceUnsubscribe(this, this.subscriberData);
|
||||||
|
+ this.subscriber = null;
|
||||||
|
+ this.subscriberData = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void notify(PatchedDataComponentMap publisher, int subscriberData) {
|
||||||
|
+ if (publisher != this.components) {
|
||||||
|
+ throw new IllegalStateException("Invalid publisher, expected " + this.components + " but got " + publisher);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (this.subscriber != null) {
|
||||||
|
+ this.subscriber.notify(this, this.subscriberData);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private void startTrackingChanges() {
|
||||||
|
+ //Safe because ComponentMapImplMixin
|
||||||
|
+ //noinspection unchecked
|
||||||
|
+ ((net.caffeinemc.mods.lithium.common.util.change_tracking.ChangePublisher<PatchedDataComponentMap>) (Object) this.components).subscribe(this, 0);
|
||||||
|
+ }
|
||||||
|
+ // Leaf end - Lithium equipment tracking
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
|
||||||
|
Date: Tue, 9 Nov 2077 00:00:00 +0800
|
||||||
|
Subject: [PATCH] Faster CraftServer#getworlds list creation
|
||||||
|
|
||||||
|
CraftServer#getWorlds/Bukkit#getWorlds is frequently used in plugins,
|
||||||
|
replacing ArrayList with Fastutil ObjectArrayList
|
||||||
|
brings about 40% performance improvement in benchmark.
|
||||||
|
|
||||||
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||||
|
index 5f4e5b386047258948a0c8772d93bfa8be734ffc..c7d806f7e2ddef2226be1efbe794f0da4c331615 100644
|
||||||
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||||
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||||
|
@@ -976,7 +976,7 @@ public final class CraftServer implements Server {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<World> getWorlds() {
|
||||||
|
- return new ArrayList<World>(this.worlds.values());
|
||||||
|
+ return new it.unimi.dsi.fastutil.objects.ObjectArrayList<World>(this.worlds.values()); // Leaf - Faster CraftServer#getWorlds list creation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
Reference in New Issue
Block a user