Add back more patches
This commit is contained in:
parent
60f3bd8d0c
commit
752f957e12
12 changed files with 73 additions and 49 deletions
|
@ -5024,10 +5024,10 @@ index 0000000000000000000000000000000000000000..755b08dd32e568d341ceef8a8aef8418
|
|||
+}
|
||||
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f85820b959213c9bb566897c173f644fd430d01a
|
||||
index 0000000000000000000000000000000000000000..19672631d7c69ade16a6f966c72a4a9d57b77c55
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
|
||||
@@ -0,0 +1,810 @@
|
||||
@@ -0,0 +1,811 @@
|
||||
+package ca.spottedleaf.moonrise.patches.chunk_system.level.entity;
|
||||
+
|
||||
+import ca.spottedleaf.moonrise.common.list.EntityList;
|
||||
|
@ -5056,6 +5056,7 @@ index 0000000000000000000000000000000000000000..f85820b959213c9bb566897c173f644f
|
|||
+import java.util.Iterator;
|
||||
+import java.util.List;
|
||||
+import java.util.function.Predicate;
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+
|
||||
+public final class ChunkEntitySlices {
|
||||
+
|
||||
|
@ -5176,12 +5177,12 @@ index 0000000000000000000000000000000000000000..f85820b959213c9bb566897c173f644f
|
|||
+ continue;
|
||||
+ }
|
||||
+ if (entity.shouldBeSaved()) {
|
||||
+ entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK);
|
||||
+ entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, EntityRemoveEvent.Cause.UNLOAD);
|
||||
+ if (entity.isVehicle()) {
|
||||
+ // we cannot assume that these entities are contained within this chunk, because entities can
|
||||
+ // desync - so we need to remove them all
|
||||
+ for (final Entity passenger : entity.getIndirectPassengers()) {
|
||||
+ passenger.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK);
|
||||
+ passenger.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, EntityRemoveEvent.Cause.UNLOAD);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
|
|
81
patches/server/1009-Entity-load-save-limit-per-chunk.patch
Normal file
81
patches/server/1009-Entity-load-save-limit-per-chunk.patch
Normal file
|
@ -0,0 +1,81 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Wed, 18 Nov 2020 20:52:25 -0800
|
||||
Subject: [PATCH] Entity load/save limit per chunk
|
||||
|
||||
Adds a config option to limit the number of entities saved and loaded
|
||||
to a chunk. The default values of -1 disable the limit. Although
|
||||
defaults are only included for certain entites, this allows setting
|
||||
limits for any entity type.
|
||||
|
||||
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
|
||||
index 19672631d7c69ade16a6f966c72a4a9d57b77c55..df4aadd40c0033c852af575fd11dce8eb3f2959e 100644
|
||||
--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
|
||||
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
|
||||
@@ -100,7 +100,18 @@ public final class ChunkEntitySlices {
|
||||
}
|
||||
|
||||
final ListTag entitiesTag = new ListTag();
|
||||
+ final java.util.Map<net.minecraft.world.entity.EntityType<?>, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk
|
||||
for (final Entity entity : entities) {
|
||||
+ // Paper start - Entity load/save limit per chunk
|
||||
+ final EntityType<?> entityType = entity.getType();
|
||||
+ final int saveLimit = world.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1);
|
||||
+ if (saveLimit > -1) {
|
||||
+ if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) {
|
||||
+ break;
|
||||
+ }
|
||||
+ savedEntityCounts.merge(entityType, 1, Integer::sum);
|
||||
+ }
|
||||
+ // Paper end - Entity load/save limit per chunk
|
||||
CompoundTag compoundTag = new CompoundTag();
|
||||
if (entity.save(compoundTag)) {
|
||||
entitiesTag.add(compoundTag);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
index 842b0cec0397d7ae5166617627340ffac0e35db1..cb61462d4691a055a4b25f7b953609d8a154fdfe 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
@@ -649,9 +649,20 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
|
||||
final Spliterator<? extends Tag> spliterator = entityNbtList.spliterator();
|
||||
|
||||
return StreamSupport.stream(new Spliterator<Entity>() {
|
||||
+ final java.util.Map<EntityType<?>, Integer> loadedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk
|
||||
public boolean tryAdvance(Consumer<? super Entity> consumer) {
|
||||
return spliterator.tryAdvance((nbtbase) -> {
|
||||
EntityType.loadEntityRecursive((CompoundTag) nbtbase, world, (entity) -> {
|
||||
+ // Paper start - Entity load/save limit per chunk
|
||||
+ final EntityType<?> entityType = entity.getType();
|
||||
+ final int saveLimit = world.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1);
|
||||
+ if (saveLimit > -1) {
|
||||
+ if (this.loadedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ this.loadedEntityCounts.merge(entityType, 1, Integer::sum);
|
||||
+ }
|
||||
+ // Paper end - Entity load/save limit per chunk
|
||||
consumer.accept(entity);
|
||||
return entity;
|
||||
});
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java
|
||||
index 503ac0374e0c9f9993ad37bb8bd8cf1570d3615a..d4a505ef4af9ded02aeb1a817bcbe5b1a912a5b3 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java
|
||||
@@ -92,7 +92,18 @@ public class EntityStorage implements EntityPersistentStorage<Entity> {
|
||||
}
|
||||
} else {
|
||||
ListTag listTag = new ListTag();
|
||||
+ final java.util.Map<net.minecraft.world.entity.EntityType<?>, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk
|
||||
dataList.getEntities().forEach(entity -> {
|
||||
+ // Paper start - Entity load/save limit per chunk
|
||||
+ final EntityType<?> entityType = entity.getType();
|
||||
+ final int saveLimit = this.level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1);
|
||||
+ if (saveLimit > -1) {
|
||||
+ if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) {
|
||||
+ return;
|
||||
+ }
|
||||
+ savedEntityCounts.merge(entityType, 1, Integer::sum);
|
||||
+ }
|
||||
+ // Paper end - Entity load/save limit per chunk
|
||||
CompoundTag compoundTagx = new CompoundTag();
|
||||
if (entity.save(compoundTagx)) {
|
||||
listTag.add(compoundTagx);
|
232
patches/server/1019-Properly-resend-entities.patch
Normal file
232
patches/server/1019-Properly-resend-entities.patch
Normal file
|
@ -0,0 +1,232 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Wed, 7 Dec 2022 17:25:19 -0500
|
||||
Subject: [PATCH] Properly resend entities
|
||||
|
||||
This resolves some issues which caused entities to not be resent correctly.
|
||||
Entities that are interacted with need to be resent to the client, so we resend all the entity
|
||||
data to the player whilst making sure not to clear dirty entries from the tracker. This makes
|
||||
sure that values will be correctly updated to other players.
|
||||
|
||||
This also adds utilities to aid in further preventing entity desyncs.
|
||||
|
||||
This also also fixes the bug causing cancelling PlayerInteractEvent to cause items to continue
|
||||
to be used despite being cancelled on the server.
|
||||
|
||||
For example, items being consumed but never finishing, shields being put up, etc.
|
||||
The underlying issue of this is that the client modifies their synced data values,
|
||||
and so we have to (forcibly) resend them in order for the client to reset their using item state.
|
||||
|
||||
See: https://github.com/PaperMC/Paper/pull/1896
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.server.level.ChunkMap$TrackedEntity serverEntity
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
|
||||
index 02bf2705ca1c99023a83a22d92e1962181102297..0f99733660f91280e4c6262cf75b3c9cae86f65a 100644
|
||||
--- a/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
|
||||
+++ b/src/main/java/net/minecraft/network/syncher/SynchedEntityData.java
|
||||
@@ -50,7 +50,7 @@ public class SynchedEntityData {
|
||||
}
|
||||
}
|
||||
|
||||
- private <T> SynchedEntityData.DataItem<T> getItem(EntityDataAccessor<T> key) {
|
||||
+ public <T> SynchedEntityData.DataItem<T> getItem(EntityDataAccessor<T> key) { // Paper - public
|
||||
return (SynchedEntityData.DataItem<T>) this.itemsById[key.id()]; // CraftBukkit - decompile error
|
||||
}
|
||||
|
||||
@@ -151,6 +151,20 @@ public class SynchedEntityData {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ // We need to pack all as we cannot rely on "non default values" or "dirty" ones.
|
||||
+ // Because these values can possibly be desynced on the client.
|
||||
+ @Nullable
|
||||
+ public List<SynchedEntityData.DataValue<?>> packAll() {
|
||||
+ final List<SynchedEntityData.DataValue<?>> list = new ArrayList<>();
|
||||
+ for (final DataItem<?> dataItem : this.itemsById) {
|
||||
+ list.add(dataItem.value());
|
||||
+ }
|
||||
+
|
||||
+ return list;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public static class DataItem<T> {
|
||||
|
||||
final EntityDataAccessor<T> accessor;
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
index e9dcdb1e09e84a9b451034ff4bdfa6eae2dd1c04..24b1715397ba8e6f5e9841a030d0e3d964356f89 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -561,6 +561,7 @@ public class ServerPlayerGameMode {
|
||||
}
|
||||
// Paper end - extend Player Interact cancellation
|
||||
player.getBukkitEntity().updateInventory(); // SPIGOT-2867
|
||||
+ this.player.resyncUsingItem(this.player); // Paper - Properly cancel usable items
|
||||
return (event.useItemInHand() != Event.Result.ALLOW) ? InteractionResult.SUCCESS : InteractionResult.PASS;
|
||||
} else if (this.gameModeForPlayer == GameType.SPECTATOR) {
|
||||
MenuProvider itileinventory = iblockdata.getMenuProvider(world, blockposition);
|
||||
@@ -612,6 +613,11 @@ public class ServerPlayerGameMode {
|
||||
|
||||
return enuminteractionresult;
|
||||
} else {
|
||||
+ // Paper start - Properly cancel usable items; Cancel only if cancelled + if the interact result is different from default response
|
||||
+ if (this.interactResult && this.interactResult != cancelledItem) {
|
||||
+ this.player.resyncUsingItem(this.player);
|
||||
+ }
|
||||
+ // Paper end - Properly cancel usable items
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index be2e97e4de911ad9570a9b4e9f3c5fafa93f6203..199e2f447ddb319387a15c934da71c27aab6da1e 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -1949,6 +1949,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
}
|
||||
|
||||
if (cancelled) {
|
||||
+ this.player.resyncUsingItem(this.player); // Paper - Properly cancel usable items
|
||||
this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524
|
||||
return;
|
||||
}
|
||||
@@ -2718,7 +2719,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
|
||||
// Entity in bucket - SPIGOT-4048 and SPIGOT-6859a
|
||||
if ((entity instanceof Bucketable && entity instanceof LivingEntity && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null || ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem() != origItem)) {
|
||||
- entity.getBukkitEntity().update(ServerGamePacketListenerImpl.this.player);
|
||||
+ entity.resendPossiblyDesyncedEntityData(ServerGamePacketListenerImpl.this.player); // Paper - The entire mob gets deleted, so resend it
|
||||
ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote();
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 0d0b07c9199be9ca0d5ac3feb1d44f149ba69283..3d30427e75bdfb9cf453fb5cd2a344227da1641a 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -393,7 +393,7 @@ public abstract class PlayerList {
|
||||
((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - Fire PlayerJoinEvent when Player is actually ready; track entity now
|
||||
// CraftBukkit end
|
||||
|
||||
- player.refreshEntityData(player); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn
|
||||
+ //player.refreshEntityData(player); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn // Paper - THIS IS NOT NEEDED ANYMORE
|
||||
|
||||
this.sendLevelInfo(player, worldserver1);
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 14db8510af7465eb663501008ca35f8ec63bfe30..898651b7cfff15fe1afb690c247cdc3936d12fa6 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -664,13 +664,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
|
||||
// CraftBukkit start
|
||||
public void refreshEntityData(ServerPlayer to) {
|
||||
- List<SynchedEntityData.DataValue<?>> list = this.getEntityData().getNonDefaultValues();
|
||||
+ List<SynchedEntityData.DataValue<?>> list = this.entityData.packAll(); // Paper - Update EVERYTHING not just not default
|
||||
|
||||
- if (list != null) {
|
||||
+ if (list != null && to.getBukkitEntity().canSee(this.getBukkitEntity())) { // Paper
|
||||
to.connection.send(new ClientboundSetEntityDataPacket(this.getId(), list));
|
||||
}
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start
|
||||
+ // This method should only be used if the data of an entity could have become desynced
|
||||
+ // due to interactions on the client.
|
||||
+ public void resendPossiblyDesyncedEntityData(net.minecraft.server.level.ServerPlayer player) {
|
||||
+ if (this.tracker == null) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (player.getBukkitEntity().canSee(this.getBukkitEntity())) {
|
||||
+ final net.minecraft.server.level.ServerEntity serverEntity = this.tracker.serverEntity;
|
||||
+ final List<net.minecraft.network.protocol.Packet<? super net.minecraft.network.protocol.game.ClientGamePacketListener>> list = new java.util.ArrayList<>();
|
||||
+ serverEntity.sendPairingData(player, list::add);
|
||||
+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundBundlePacket(list));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // This method allows you to specifically resend certain data accessor keys to the client
|
||||
+ public void resendPossiblyDesyncedDataValues(List<EntityDataAccessor<?>> keys, ServerPlayer to) {
|
||||
+ if (!to.getBukkitEntity().canSee(this.getBukkitEntity())) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ final List<SynchedEntityData.DataValue<?>> values = new java.util.ArrayList<>(keys.size());
|
||||
+ for (final EntityDataAccessor<?> key : keys) {
|
||||
+ final SynchedEntityData.DataItem<?> synchedValue = this.entityData.getItem(key);
|
||||
+ values.add(synchedValue.value());
|
||||
+ }
|
||||
+
|
||||
+ to.connection.send(new ClientboundSetEntityDataPacket(this.id, values));
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
public boolean equals(Object object) {
|
||||
return object instanceof Entity ? ((Entity) object).id == this.id : false;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 25a7dfddb44a11f6e20c459141a61270c0c12d4c..e980c8c356b30d25e2fc5a73b91ad2c6edd4fe05 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3840,6 +3840,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
return ((Byte) this.entityData.get(LivingEntity.DATA_LIVING_ENTITY_FLAGS) & 2) > 0 ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND;
|
||||
}
|
||||
|
||||
+ // Paper start - Properly cancel usable items
|
||||
+ public void resyncUsingItem(ServerPlayer serverPlayer) {
|
||||
+ this.resendPossiblyDesyncedDataValues(java.util.List.of(DATA_LIVING_ENTITY_FLAGS), serverPlayer);
|
||||
+ }
|
||||
+ // Paper end - Properly cancel usable items
|
||||
private void updatingUsingItem() {
|
||||
if (this.isUsingItem()) {
|
||||
if (ItemStack.isSameItem(this.getItemInHand(this.getUsedItemHand()), this.useItem)) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Bucketable.java b/src/main/java/net/minecraft/world/entity/animal/Bucketable.java
|
||||
index b586116d8cca1585f9c9e618ed4d0cb2ef2747be..acf38ef6d8de8b15cf2b09eb7bda390c4e446e9a 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Bucketable.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Bucketable.java
|
||||
@@ -108,8 +108,7 @@ public interface Bucketable {
|
||||
itemstack1 = CraftItemStack.asNMSCopy(playerBucketFishEvent.getEntityBucket());
|
||||
if (playerBucketFishEvent.isCancelled()) {
|
||||
((ServerPlayer) player).containerMenu.sendAllDataToRemote(); // We need to update inventory to resync client's bucket
|
||||
- entity.getBukkitEntity().update((ServerPlayer) player); // We need to play out these packets as the client assumes the fish is gone
|
||||
- entity.refreshEntityData((ServerPlayer) player); // Need to send data such as the display name to client
|
||||
+ entity.resendPossiblyDesyncedEntityData((ServerPlayer) player); // Paper
|
||||
return Optional.of(InteractionResult.FAIL);
|
||||
}
|
||||
entity.playSound(((Bucketable) entity).getPickupSound(), 1.0F, 1.0F);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index b8eb9166e44da8745a056bf68f2f9316ce25d7a7..2cde808bfa797256409879505ba205a71f381981 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -1012,7 +1012,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
return;
|
||||
}
|
||||
|
||||
- entityTracker.broadcast(this.getHandle().getAddEntityPacket(entityTracker.serverEntity));
|
||||
+ // Paper start - resend possibly desynced entity instead of add entity packet
|
||||
+ for (final ServerPlayerConnection connection : entityTracker.seenBy) {
|
||||
+ this.getHandle().resendPossiblyDesyncedEntityData(connection.getPlayer());
|
||||
+ }
|
||||
+ // Paper end - resend possibly desynced entity instead of add entity packet
|
||||
}
|
||||
|
||||
public void update(ServerPlayer player) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java
|
||||
index f3a9b3380246fb2dd4b60a8d1a94c5dfed98d316..350ad61ab3fe66abd528e353b431a4a6dac17506 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java
|
||||
@@ -39,9 +39,11 @@ public class CraftItemFrame extends CraftHanging implements ItemFrame {
|
||||
protected void update() {
|
||||
super.update();
|
||||
|
||||
+ // Paper start, don't mark as dirty as this is handled in super.update()
|
||||
// mark dirty, so that the client gets updated with item and rotation
|
||||
- this.getHandle().getEntityData().markDirty(net.minecraft.world.entity.decoration.ItemFrame.DATA_ITEM);
|
||||
- this.getHandle().getEntityData().markDirty(net.minecraft.world.entity.decoration.ItemFrame.DATA_ROTATION);
|
||||
+ //this.getHandle().getEntityData().markDirty(net.minecraft.world.entity.decoration.ItemFrame.DATA_ITEM);
|
||||
+ //this.getHandle().getEntityData().markDirty(net.minecraft.world.entity.decoration.ItemFrame.DATA_ROTATION);
|
||||
+ // Paper end
|
||||
|
||||
// update redstone
|
||||
if (!this.getHandle().generation) {
|
Loading…
Add table
Add a link
Reference in a new issue