9
0
mirror of https://github.com/LeavesMC/Leaves.git synced 2025-12-19 14:59:32 +00:00

Fix jade protocol inv

This commit is contained in:
violetc
2024-11-15 23:37:30 +08:00
parent fd9bd9bf9a
commit 21c276fcdc

View File

@@ -124,7 +124,7 @@ index 30d0133a42ce990352f5c492fcf9beb105364848..1ab2eab686b3a89d406f127a6036c0e2
protected CompositeLootItemCondition(List<LootItemCondition> terms, Predicate<LootContext> predicate) { protected CompositeLootItemCondition(List<LootItemCondition> terms, Predicate<LootContext> predicate) {
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..eb26708fafa054ba32c5deed43c8496d5496f6a9 index 0000000000000000000000000000000000000000..438dfee78f7114e7c8d3d57c5dcc90e1fcc75a4c
--- /dev/null --- /dev/null
+++ b/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java +++ b/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java
@@ -0,0 +1,311 @@ @@ -0,0 +1,311 @@
@@ -196,7 +196,7 @@ index 0000000000000000000000000000000000000000..eb26708fafa054ba32c5deed43c8496d
+import org.leavesmc.leaves.protocol.jade.provider.block.CommandBlockProvider; +import org.leavesmc.leaves.protocol.jade.provider.block.CommandBlockProvider;
+import org.leavesmc.leaves.protocol.jade.provider.block.FurnaceProvider; +import org.leavesmc.leaves.protocol.jade.provider.block.FurnaceProvider;
+import org.leavesmc.leaves.protocol.jade.provider.block.HopperLockProvider; +import org.leavesmc.leaves.protocol.jade.provider.block.HopperLockProvider;
+import org.leavesmc.leaves.protocol.jade.provider.block.ItemStorageProvider; +import org.leavesmc.leaves.protocol.jade.provider.ItemStorageProvider;
+import org.leavesmc.leaves.protocol.jade.provider.block.JukeboxProvider; +import org.leavesmc.leaves.protocol.jade.provider.block.JukeboxProvider;
+import org.leavesmc.leaves.protocol.jade.provider.block.LecternProvider; +import org.leavesmc.leaves.protocol.jade.provider.block.LecternProvider;
+import org.leavesmc.leaves.protocol.jade.provider.block.MobSpawnerCooldownProvider; +import org.leavesmc.leaves.protocol.jade.provider.block.MobSpawnerCooldownProvider;
@@ -442,20 +442,18 @@ index 0000000000000000000000000000000000000000..eb26708fafa054ba32c5deed43c8496d
\ No newline at end of file \ No newline at end of file
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/Accessor.java b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/Accessor.java diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/Accessor.java b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/Accessor.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..9c9b469f805196dd97e02d93a11232d043f5e854 index 0000000000000000000000000000000000000000..1a637045d9375ae357ca1e592ec0dc7b45fa47fa
--- /dev/null --- /dev/null
+++ b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/Accessor.java +++ b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/Accessor.java
@@ -0,0 +1,37 @@ @@ -0,0 +1,32 @@
+package org.leavesmc.leaves.protocol.jade.accessor; +package org.leavesmc.leaves.protocol.jade.accessor;
+ +
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.nbt.Tag; +import net.minecraft.nbt.Tag;
+import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf;
+import net.minecraft.network.codec.StreamEncoder; +import net.minecraft.network.codec.StreamEncoder;
+import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.level.Level; +import net.minecraft.world.level.Level;
+import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.HitResult;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Nullable;
+ +
+public interface Accessor<T extends HitResult> { +public interface Accessor<T extends HitResult> {
@@ -464,9 +462,6 @@ index 0000000000000000000000000000000000000000..9c9b469f805196dd97e02d93a11232d0
+ +
+ Player getPlayer(); + Player getPlayer();
+ +
+ @NotNull
+ CompoundTag getServerData();
+
+ <D> Tag encodeAsNbt(StreamEncoder<RegistryFriendlyByteBuf, D> codec, D value); + <D> Tag encodeAsNbt(StreamEncoder<RegistryFriendlyByteBuf, D> codec, D value);
+ +
+ T getHitResult(); + T getHitResult();
@@ -485,20 +480,18 @@ index 0000000000000000000000000000000000000000..9c9b469f805196dd97e02d93a11232d0
+} +}
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/AccessorImpl.java b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/AccessorImpl.java diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/AccessorImpl.java b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/AccessorImpl.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..38d6b146d9135fb7c985f1f4e8a804bb490ff0df index 0000000000000000000000000000000000000000..a04fbb45b466d8999b40717d8d48f650b81fe82a
--- /dev/null --- /dev/null
+++ b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/AccessorImpl.java +++ b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/AccessorImpl.java
@@ -0,0 +1,92 @@ @@ -0,0 +1,83 @@
+package org.leavesmc.leaves.protocol.jade.accessor; +package org.leavesmc.leaves.protocol.jade.accessor;
+ +
+import java.util.function.Supplier; +import java.util.function.Supplier;
+ +
+import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.ArrayUtils;
+import org.jetbrains.annotations.NotNull;
+ +
+import io.netty.buffer.Unpooled; +import io.netty.buffer.Unpooled;
+import net.minecraft.nbt.ByteArrayTag; +import net.minecraft.nbt.ByteArrayTag;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.nbt.Tag; +import net.minecraft.nbt.Tag;
+import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf;
+import net.minecraft.network.codec.StreamEncoder; +import net.minecraft.network.codec.StreamEncoder;
@@ -510,20 +503,18 @@ index 0000000000000000000000000000000000000000..38d6b146d9135fb7c985f1f4e8a804bb
+ +
+ private final Level level; + private final Level level;
+ private final Player player; + private final Player player;
+ private final CompoundTag serverData;
+ private final Supplier<T> hit; + private final Supplier<T> hit;
+ private final boolean serverConnected; + private final boolean serverConnected;
+ private final boolean showDetails; + private final boolean showDetails;
+ protected boolean verify; + protected boolean verify;
+ private RegistryFriendlyByteBuf buffer; + private RegistryFriendlyByteBuf buffer;
+ +
+ public AccessorImpl(Level level, Player player, CompoundTag serverData, Supplier<T> hit, boolean serverConnected, boolean showDetails) { + public AccessorImpl(Level level, Player player, Supplier<T> hit, boolean serverConnected, boolean showDetails) {
+ this.level = level; + this.level = level;
+ this.player = player; + this.player = player;
+ this.hit = hit; + this.hit = hit;
+ this.serverConnected = serverConnected; + this.serverConnected = serverConnected;
+ this.showDetails = showDetails; + this.showDetails = showDetails;
+ this.serverData = serverData == null ? new CompoundTag() : serverData.copy();
+ } + }
+ +
+ @Override + @Override
@@ -536,11 +527,6 @@ index 0000000000000000000000000000000000000000..38d6b146d9135fb7c985f1f4e8a804bb
+ return player; + return player;
+ } + }
+ +
+ @Override
+ public final @NotNull CompoundTag getServerData() {
+ return serverData;
+ }
+
+ private RegistryFriendlyByteBuf buffer() { + private RegistryFriendlyByteBuf buffer() {
+ if (buffer == null) { + if (buffer == null) {
+ buffer = new RegistryFriendlyByteBuf(Unpooled.buffer(), level.registryAccess()); + buffer = new RegistryFriendlyByteBuf(Unpooled.buffer(), level.registryAccess());
@@ -639,10 +625,10 @@ index 0000000000000000000000000000000000000000..12d689ca80887dcd5dbf68ea2c38a8ad
+} +}
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/BlockAccessorImpl.java b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/BlockAccessorImpl.java diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/BlockAccessorImpl.java b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/BlockAccessorImpl.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..4a2cd64c7911b756f737ed34f245f7366668f417 index 0000000000000000000000000000000000000000..9e4a321b91a8afc480ef506487608255db2b9c89
--- /dev/null --- /dev/null
+++ b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/BlockAccessorImpl.java +++ b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/BlockAccessorImpl.java
@@ -0,0 +1,166 @@ @@ -0,0 +1,163 @@
+package org.leavesmc.leaves.protocol.jade.accessor; +package org.leavesmc.leaves.protocol.jade.accessor;
+ +
+import java.util.function.Supplier; +import java.util.function.Supplier;
@@ -653,7 +639,6 @@ index 0000000000000000000000000000000000000000..4a2cd64c7911b756f737ed34f245f736
+ +
+import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos;
+import net.minecraft.core.Direction; +import net.minecraft.core.Direction;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.FriendlyByteBuf;
+import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf;
+import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.ByteBufCodecs;
@@ -678,7 +663,7 @@ index 0000000000000000000000000000000000000000..4a2cd64c7911b756f737ed34f245f736
+ private final Supplier<BlockEntity> blockEntity; + private final Supplier<BlockEntity> blockEntity;
+ +
+ private BlockAccessorImpl(Builder builder) { + private BlockAccessorImpl(Builder builder) {
+ super(builder.level, builder.player, builder.serverData, Suppliers.ofInstance(builder.hit), builder.connected, builder.showDetails); + super(builder.level, builder.player, Suppliers.ofInstance(builder.hit), builder.connected, builder.showDetails);
+ blockState = builder.blockState; + blockState = builder.blockState;
+ blockEntity = builder.blockEntity; + blockEntity = builder.blockEntity;
+ } + }
@@ -718,7 +703,6 @@ index 0000000000000000000000000000000000000000..4a2cd64c7911b756f737ed34f245f736
+ +
+ private Level level; + private Level level;
+ private Player player; + private Player player;
+ private CompoundTag serverData;
+ private boolean connected; + private boolean connected;
+ private boolean showDetails; + private boolean showDetails;
+ private BlockHitResult hit; + private BlockHitResult hit;
@@ -765,7 +749,6 @@ index 0000000000000000000000000000000000000000..4a2cd64c7911b756f737ed34f245f736
+ public Builder from(BlockAccessor accessor) { + public Builder from(BlockAccessor accessor) {
+ level = accessor.getLevel(); + level = accessor.getLevel();
+ player = accessor.getPlayer(); + player = accessor.getPlayer();
+ serverData = accessor.getServerData();
+ connected = accessor.isServerConnected(); + connected = accessor.isServerConnected();
+ showDetails = accessor.showDetails(); + showDetails = accessor.showDetails();
+ hit = accessor.getHitResult(); + hit = accessor.getHitResult();
@@ -862,14 +845,13 @@ index 0000000000000000000000000000000000000000..454360d5e5c01cad3c197b078d536a9f
\ No newline at end of file \ No newline at end of file
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/EntityAccessorImpl.java b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/EntityAccessorImpl.java diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/EntityAccessorImpl.java b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/EntityAccessorImpl.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..f670ac9b7ee72bbf3fa4f509cc2cdaeee238ccff index 0000000000000000000000000000000000000000..65d16c0024372ede4cec230b7aad54de28de15f2
--- /dev/null --- /dev/null
+++ b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/EntityAccessorImpl.java +++ b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/EntityAccessorImpl.java
@@ -0,0 +1,126 @@ @@ -0,0 +1,123 @@
+package org.leavesmc.leaves.protocol.jade.accessor; +package org.leavesmc.leaves.protocol.jade.accessor;
+ +
+import com.google.common.base.Suppliers; +import com.google.common.base.Suppliers;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf;
+import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.ByteBufCodecs;
+import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.codec.StreamCodec;
@@ -889,7 +871,7 @@ index 0000000000000000000000000000000000000000..f670ac9b7ee72bbf3fa4f509cc2cdaee
+ private final Supplier<Entity> entity; + private final Supplier<Entity> entity;
+ +
+ public EntityAccessorImpl(Builder builder) { + public EntityAccessorImpl(Builder builder) {
+ super(builder.level, builder.player, builder.serverData, builder.hit, builder.connected, builder.showDetails); + super(builder.level, builder.player, builder.hit, builder.connected, builder.showDetails);
+ entity = builder.entity; + entity = builder.entity;
+ } + }
+ +
@@ -914,7 +896,6 @@ index 0000000000000000000000000000000000000000..f670ac9b7ee72bbf3fa4f509cc2cdaee
+ public boolean showDetails; + public boolean showDetails;
+ private Level level; + private Level level;
+ private Player player; + private Player player;
+ private CompoundTag serverData;
+ private boolean connected; + private boolean connected;
+ private Supplier<EntityHitResult> hit; + private Supplier<EntityHitResult> hit;
+ private Supplier<Entity> entity; + private Supplier<Entity> entity;
@@ -953,7 +934,6 @@ index 0000000000000000000000000000000000000000..f670ac9b7ee72bbf3fa4f509cc2cdaee
+ public Builder from(EntityAccessor accessor) { + public Builder from(EntityAccessor accessor) {
+ level = accessor.getLevel(); + level = accessor.getLevel();
+ player = accessor.getPlayer(); + player = accessor.getPlayer();
+ serverData = accessor.getServerData();
+ connected = accessor.isServerConnected(); + connected = accessor.isServerConnected();
+ showDetails = accessor.showDetails(); + showDetails = accessor.showDetails();
+ hit = accessor::getHitResult; + hit = accessor::getHitResult;
@@ -1251,10 +1231,10 @@ index 0000000000000000000000000000000000000000..6e32eed15f028020223e2500849b4db3
\ No newline at end of file \ No newline at end of file
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java b/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java b/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..7680ff97d99e15a9b3475ef83f7cfe348c895b14 index 0000000000000000000000000000000000000000..797558f3804a1a8143eafafd5dc46cc72ea19a42
--- /dev/null --- /dev/null
+++ b/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java +++ b/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java
@@ -0,0 +1,142 @@ @@ -0,0 +1,138 @@
+package org.leavesmc.leaves.protocol.jade.provider; +package org.leavesmc.leaves.protocol.jade.provider;
+ +
+import com.google.common.cache.Cache; +import com.google.common.cache.Cache;
@@ -1263,7 +1243,6 @@ index 0000000000000000000000000000000000000000..7680ff97d99e15a9b3475ef83f7cfe34
+import net.minecraft.world.Container; +import net.minecraft.world.Container;
+import net.minecraft.world.LockCode; +import net.minecraft.world.LockCode;
+import net.minecraft.world.RandomizableContainer; +import net.minecraft.world.RandomizableContainer;
+import net.minecraft.world.WorldlyContainer;
+import net.minecraft.world.WorldlyContainerHolder; +import net.minecraft.world.WorldlyContainerHolder;
+import net.minecraft.world.entity.animal.horse.AbstractHorse; +import net.minecraft.world.entity.animal.horse.AbstractHorse;
+import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.player.Player;
@@ -1274,6 +1253,8 @@ index 0000000000000000000000000000000000000000..7680ff97d99e15a9b3475ef83f7cfe34
+import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; +import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
+import net.minecraft.world.level.block.entity.ChestBlockEntity; +import net.minecraft.world.level.block.entity.ChestBlockEntity;
+import net.minecraft.world.level.block.entity.EnderChestBlockEntity; +import net.minecraft.world.level.block.entity.EnderChestBlockEntity;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.leavesmc.leaves.LeavesLogger; +import org.leavesmc.leaves.LeavesLogger;
+import org.leavesmc.leaves.protocol.jade.JadeProtocol; +import org.leavesmc.leaves.protocol.jade.JadeProtocol;
+import org.leavesmc.leaves.protocol.jade.accessor.Accessor; +import org.leavesmc.leaves.protocol.jade.accessor.Accessor;
@@ -1290,21 +1271,16 @@ index 0000000000000000000000000000000000000000..7680ff97d99e15a9b3475ef83f7cfe34
+ INSTANCE; + INSTANCE;
+ +
+ public static final Cache<Object, ItemCollector<?>> targetCache = CacheBuilder.newBuilder().weakKeys().expireAfterAccess(60, TimeUnit.SECONDS).build(); + public static final Cache<Object, ItemCollector<?>> targetCache = CacheBuilder.newBuilder().weakKeys().expireAfterAccess(60, TimeUnit.SECONDS).build();
+ public static final Cache<Object, ItemCollector<?>> containerCache = CacheBuilder.newBuilder().weakKeys().expireAfterAccess(120, TimeUnit.SECONDS).build();
+ +
+ private static final ResourceLocation UNIVERSAL_ITEM_STORAGE = JadeProtocol.mc_id("item_storage.default"); + private static final ResourceLocation UNIVERSAL_ITEM_STORAGE = JadeProtocol.mc_id("item_storage.default");
+ +
+ @Override + @Override
+ public List<ViewGroup<ItemStack>> getGroups(Accessor<?> request) { + public List<ViewGroup<ItemStack>> getGroups(Accessor<?> request) {
+ Object target = request.getTarget(); + Object target = request.getTarget();
+ if (target == null && request instanceof BlockAccessor blockAccessor && blockAccessor.getBlock() instanceof WorldlyContainerHolder holder) {
+ WorldlyContainer container = holder.getContainer(blockAccessor.getBlockState(), request.getLevel(), blockAccessor.getPosition());
+ return containerGroup(container, request);
+ }
+ +
+ switch (target) { + switch (target) {
+ case null -> { + case null -> {
+ return List.of(); + return createItemCollector(request).update(request);
+ } + }
+ case RandomizableContainer te when te.getLootTable() != null -> { + case RandomizableContainer te when te.getLootTable() != null -> {
+ return List.of(); + return List.of();
@@ -1325,22 +1301,18 @@ index 0000000000000000000000000000000000000000..7680ff97d99e15a9b3475ef83f7cfe34
+ +
+ if (target instanceof EnderChestBlockEntity) { + if (target instanceof EnderChestBlockEntity) {
+ PlayerEnderChestContainer inventory = player.getEnderChestInventory(); + PlayerEnderChestContainer inventory = player.getEnderChestInventory();
+ return new ItemCollector<>(new ItemIterator.ContainerItemIterator(0)).update(inventory, request.getLevel().getGameTime()); + return new ItemCollector<>(new ItemIterator.ContainerItemIterator(x -> inventory, 0)).update(request);
+ } + }
+ +
+ ItemCollector<?> itemCollector; + ItemCollector<?> itemCollector;
+ try { + try {
+ itemCollector = targetCache.get(target, () -> createItemCollector(target)); + itemCollector = targetCache.get(target, () -> createItemCollector(request));
+ } catch (ExecutionException e) { + } catch (ExecutionException e) {
+ LeavesLogger.LOGGER.severe("Failed to get item collector for " + target); + LeavesLogger.LOGGER.severe("Failed to get item collector for " + target);
+ return null; + return null;
+ } + }
+ +
+ if (itemCollector == ItemCollector.EMPTY) { + return itemCollector.update(request);
+ return null;
+ }
+
+ return itemCollector.update(target, request.getLevel().getGameTime());
+ } + }
+ +
+ @Override + @Override
@@ -1348,16 +1320,8 @@ index 0000000000000000000000000000000000000000..7680ff97d99e15a9b3475ef83f7cfe34
+ return UNIVERSAL_ITEM_STORAGE; + return UNIVERSAL_ITEM_STORAGE;
+ } + }
+ +
+ public static List<ViewGroup<ItemStack>> containerGroup(Container container, Accessor<?> accessor) { + public static ItemCollector<?> createItemCollector(Accessor<?> request) {
+ try { + if (request.getTarget() instanceof AbstractHorse) {
+ return containerCache.get(container, () -> new ItemCollector<>(new ItemIterator.ContainerItemIterator(0))).update(container, accessor.getLevel().getGameTime());
+ } catch (ExecutionException e) {
+ return null;
+ }
+ }
+
+ public static ItemCollector<?> createItemCollector(Object target) {
+ if (target instanceof AbstractHorse) {
+ return new ItemCollector<>(new ItemIterator.ContainerItemIterator(o -> { + return new ItemCollector<>(new ItemIterator.ContainerItemIterator(o -> {
+ if (o instanceof AbstractHorse horse) { + if (o instanceof AbstractHorse horse) {
+ return horse.inventory; + return horse.inventory;
@@ -1368,8 +1332,9 @@ index 0000000000000000000000000000000000000000..7680ff97d99e15a9b3475ef83f7cfe34
+ +
+ // TODO BlockEntity like fabric's ItemStorage + // TODO BlockEntity like fabric's ItemStorage
+ +
+ if (target instanceof Container) { + final Container container = findContainer(request);
+ if (target instanceof ChestBlockEntity) { + if (container != null) {
+ if (container instanceof ChestBlockEntity) {
+ return new ItemCollector<>(new ItemIterator.ContainerItemIterator(o -> { + return new ItemCollector<>(new ItemIterator.ContainerItemIterator(o -> {
+ if (o instanceof ChestBlockEntity blockEntity) { + if (o instanceof ChestBlockEntity blockEntity) {
+ if (blockEntity.getBlockState().getBlock() instanceof ChestBlock chestBlock) { + if (blockEntity.getBlockState().getBlock() instanceof ChestBlock chestBlock) {
@@ -1392,11 +1357,117 @@ index 0000000000000000000000000000000000000000..7680ff97d99e15a9b3475ef83f7cfe34
+ return ItemCollector.EMPTY; + return ItemCollector.EMPTY;
+ } + }
+ +
+ public static @Nullable Container findContainer(@NotNull Accessor<?> accessor) {
+ Object target = accessor.getTarget();
+ if (target == null && accessor instanceof BlockAccessor blockAccessor &&
+ blockAccessor.getBlock() instanceof WorldlyContainerHolder holder) {
+ return holder.getContainer(blockAccessor.getBlockState(), accessor.getLevel(), blockAccessor.getPosition());
+ } else if (target instanceof Container container) {
+ return container;
+ }
+ return null;
+ }
+
+ @Override + @Override
+ public int getDefaultPriority() { + public int getDefaultPriority() {
+ return IServerExtensionProvider.super.getDefaultPriority() + 1000; + return IServerExtensionProvider.super.getDefaultPriority() + 1000;
+ } + }
+} +}
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageProvider.java b/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..8289b5c48213348a7346dfdbb30ee1b8787d2a2d
--- /dev/null
+++ b/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageProvider.java
@@ -0,0 +1,88 @@
+package org.leavesmc.leaves.protocol.jade.provider;
+
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.network.RegistryFriendlyByteBuf;
+import net.minecraft.network.codec.StreamCodec;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.LockCode;
+import net.minecraft.world.RandomizableContainer;
+import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
+import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
+import org.jetbrains.annotations.NotNull;
+import org.leavesmc.leaves.protocol.jade.JadeProtocol;
+import org.leavesmc.leaves.protocol.jade.accessor.Accessor;
+import org.leavesmc.leaves.protocol.jade.accessor.BlockAccessor;
+import org.leavesmc.leaves.protocol.jade.accessor.EntityAccessor;
+import org.leavesmc.leaves.protocol.jade.util.CommonUtil;
+import org.leavesmc.leaves.protocol.jade.util.ItemCollector;
+import org.leavesmc.leaves.protocol.jade.util.ViewGroup;
+
+import java.util.List;
+import java.util.Map;
+
+public abstract class ItemStorageProvider<T extends Accessor<?>> implements IServerDataProvider<T> {
+
+ private static final StreamCodec<RegistryFriendlyByteBuf, Map.Entry<ResourceLocation, List<ViewGroup<ItemStack>>>> STREAM_CODEC = ViewGroup.listCodec(
+ ItemStack.OPTIONAL_STREAM_CODEC);
+
+ private static final ResourceLocation UNIVERSAL_ITEM_STORAGE = JadeProtocol.mc_id("item_storage");
+
+ public static ForBlock getBlock() {
+ return ForBlock.INSTANCE;
+ }
+
+ public static ForEntity getEntity() {
+ return ForEntity.INSTANCE;
+ }
+
+ public static class ForBlock extends ItemStorageProvider<BlockAccessor> {
+ private static final ForBlock INSTANCE = new ForBlock();
+ }
+
+ public static class ForEntity extends ItemStorageProvider<EntityAccessor> {
+ private static final ForEntity INSTANCE = new ForEntity();
+ }
+
+ public static void putData(CompoundTag tag, @NotNull Accessor<?> accessor) {
+ Object target = accessor.getTarget();
+ Player player = accessor.getPlayer();
+ Map.Entry<ResourceLocation, List<ViewGroup<ItemStack>>> entry = CommonUtil.getServerExtensionData(accessor, JadeProtocol.itemStorageProviders);
+ if (entry != null) {
+ List<ViewGroup<ItemStack>> groups = entry.getValue();
+ for (ViewGroup<ItemStack> group : groups) {
+ if (group.views.size() > ItemCollector.MAX_SIZE) {
+ group.views = group.views.subList(0, ItemCollector.MAX_SIZE);
+ }
+ }
+ tag.put(UNIVERSAL_ITEM_STORAGE.toString(), accessor.encodeAsNbt(STREAM_CODEC, entry));
+ return;
+ }
+ if (target instanceof RandomizableContainer containerEntity && containerEntity.getLootTable() != null) {
+ tag.putBoolean("Loot", true);
+ } else if (!player.isCreative() && !player.isSpectator() && target instanceof BaseContainerBlockEntity te) {
+ if (te.lockKey != LockCode.NO_LOCK) {
+ tag.putBoolean("Locked", true);
+ }
+ }
+ }
+
+ @Override
+ public ResourceLocation getUid() {
+ return UNIVERSAL_ITEM_STORAGE;
+ }
+
+ @Override
+ public void appendServerData(CompoundTag tag, @NotNull T accessor) {
+ if (accessor.getTarget() instanceof AbstractFurnaceBlockEntity) {
+ return;
+ }
+ putData(tag, accessor);
+ }
+
+ @Override
+ public int getDefaultPriority() {
+ return 9999;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/provider/StreamServerDataProvider.java b/src/main/java/org/leavesmc/leaves/protocol/jade/provider/StreamServerDataProvider.java diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/provider/StreamServerDataProvider.java b/src/main/java/org/leavesmc/leaves/protocol/jade/provider/StreamServerDataProvider.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..52887edb3359c5eb1900cd1eec912e52afef2c9f index 0000000000000000000000000000000000000000..52887edb3359c5eb1900cd1eec912e52afef2c9f
@@ -1776,105 +1847,6 @@ index 0000000000000000000000000000000000000000..a3937081bd923d3b6f2ee966dc95aa23
+ } + }
+} +}
\ No newline at end of file \ No newline at end of file
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/provider/block/ItemStorageProvider.java b/src/main/java/org/leavesmc/leaves/protocol/jade/provider/block/ItemStorageProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..f4eb38d4b5d98a286964cdb68581bb9a2d836def
--- /dev/null
+++ b/src/main/java/org/leavesmc/leaves/protocol/jade/provider/block/ItemStorageProvider.java
@@ -0,0 +1,92 @@
+package org.leavesmc.leaves.protocol.jade.provider.block;
+
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.network.RegistryFriendlyByteBuf;
+import net.minecraft.network.codec.StreamCodec;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.LockCode;
+import net.minecraft.world.RandomizableContainer;
+import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
+import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
+import org.jetbrains.annotations.NotNull;
+import org.leavesmc.leaves.protocol.jade.JadeProtocol;
+import org.leavesmc.leaves.protocol.jade.accessor.Accessor;
+import org.leavesmc.leaves.protocol.jade.accessor.BlockAccessor;
+import org.leavesmc.leaves.protocol.jade.accessor.EntityAccessor;
+import org.leavesmc.leaves.protocol.jade.provider.IServerDataProvider;
+import org.leavesmc.leaves.protocol.jade.util.CommonUtil;
+import org.leavesmc.leaves.protocol.jade.util.ItemCollector;
+import org.leavesmc.leaves.protocol.jade.util.ViewGroup;
+
+import java.util.List;
+import java.util.Map;
+
+public abstract class ItemStorageProvider<T extends Accessor<?>> implements IServerDataProvider<T> {
+
+ private static final StreamCodec<RegistryFriendlyByteBuf, Map.Entry<ResourceLocation, List<ViewGroup<ItemStack>>>> STREAM_CODEC = ViewGroup.listCodec(
+ ItemStack.OPTIONAL_STREAM_CODEC);
+
+ private static final ResourceLocation UNIVERSAL_ITEM_STORAGE = JadeProtocol.mc_id("item_storage.default");
+
+ public static ForBlock getBlock() {
+ return ForBlock.INSTANCE;
+ }
+
+ public static ForEntity getEntity() {
+ return ForEntity.INSTANCE;
+ }
+
+ public static class ForBlock extends ItemStorageProvider<BlockAccessor> {
+ private static final ForBlock INSTANCE = new ForBlock();
+ }
+
+ public static class ForEntity extends ItemStorageProvider<EntityAccessor> {
+ private static final ForEntity INSTANCE = new ForEntity();
+ }
+
+ public static void putData(Accessor<?> accessor) {
+ CompoundTag tag = accessor.getServerData();
+ Object target = accessor.getTarget();
+ Player player = accessor.getPlayer();
+ Map.Entry<ResourceLocation, List<ViewGroup<ItemStack>>> entry = CommonUtil.getServerExtensionData(
+ accessor,
+ JadeProtocol.itemStorageProviders);
+ if (entry != null) {
+ List<ViewGroup<ItemStack>> groups = entry.getValue();
+ for (ViewGroup<ItemStack> group : groups) {
+ if (group.views.size() > ItemCollector.MAX_SIZE) {
+ group.views = group.views.subList(0, ItemCollector.MAX_SIZE);
+ }
+ }
+ tag.put(UNIVERSAL_ITEM_STORAGE.toString(), accessor.encodeAsNbt(STREAM_CODEC, entry));
+ return;
+ }
+ if (target instanceof RandomizableContainer containerEntity && containerEntity.getLootTable() != null) {
+ tag.putBoolean("Loot", true);
+ } else if (!player.isCreative() && !player.isSpectator() && target instanceof BaseContainerBlockEntity te) {
+ if (te.lockKey != LockCode.NO_LOCK) {
+ tag.putBoolean("Locked", true);
+ }
+ }
+ }
+
+ @Override
+ public ResourceLocation getUid() {
+ return UNIVERSAL_ITEM_STORAGE;
+ }
+
+ @Override
+ public void appendServerData(CompoundTag tag, @NotNull T accessor) {
+ if (accessor.getTarget() instanceof AbstractFurnaceBlockEntity) {
+ return;
+ }
+ putData(accessor);
+ }
+
+ @Override
+ public int getDefaultPriority() {
+ return 9999;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/provider/block/JukeboxProvider.java b/src/main/java/org/leavesmc/leaves/protocol/jade/provider/block/JukeboxProvider.java diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/provider/block/JukeboxProvider.java b/src/main/java/org/leavesmc/leaves/protocol/jade/provider/block/JukeboxProvider.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..0b6e224ebc8d6acdc29abf51f7d98b667baf0984 index 0000000000000000000000000000000000000000..0b6e224ebc8d6acdc29abf51f7d98b667baf0984
@@ -2830,10 +2802,10 @@ index 0000000000000000000000000000000000000000..137cdf619879390477b4fc8c4b7ecee5
+ +
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/util/ItemCollector.java b/src/main/java/org/leavesmc/leaves/protocol/jade/util/ItemCollector.java diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/util/ItemCollector.java b/src/main/java/org/leavesmc/leaves/protocol/jade/util/ItemCollector.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..769c331035e59408064b63a29d8bf2194b386aa0 index 0000000000000000000000000000000000000000..8f57cb0714dc684bd90325a6d2e84d5b1b303d6e
--- /dev/null --- /dev/null
+++ b/src/main/java/org/leavesmc/leaves/protocol/jade/util/ItemCollector.java +++ b/src/main/java/org/leavesmc/leaves/protocol/jade/util/ItemCollector.java
@@ -0,0 +1,114 @@ @@ -0,0 +1,116 @@
+package org.leavesmc.leaves.protocol.jade.util; +package org.leavesmc.leaves.protocol.jade.util;
+ +
+import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap;
@@ -2843,6 +2815,7 @@ index 0000000000000000000000000000000000000000..769c331035e59408064b63a29d8bf219
+import net.minecraft.world.item.Item; +import net.minecraft.world.item.Item;
+import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.component.CustomData; +import net.minecraft.world.item.component.CustomData;
+import org.leavesmc.leaves.protocol.jade.accessor.Accessor;
+ +
+import java.util.List; +import java.util.List;
+import java.util.Locale; +import java.util.Locale;
@@ -2877,15 +2850,16 @@ index 0000000000000000000000000000000000000000..769c331035e59408064b63a29d8bf219
+ this.iterator = iterator; + this.iterator = iterator;
+ } + }
+ +
+ public List<ViewGroup<ItemStack>> update(Object target, long gameTime) { + public List<ViewGroup<ItemStack>> update(Accessor<?> request) {
+ if (iterator == null) { + if (iterator == null) {
+ return null; + return null;
+ } + }
+ T container = iterator.find(target); + T container = iterator.find(request.getTarget());
+ if (container == null) { + if (container == null) {
+ return null; + return null;
+ } + }
+ long currentVersion = iterator.getVersion(container); + long currentVersion = iterator.getVersion(container);
+ long gameTime = request.getLevel().getGameTime();
+ if (mergedResult != null && iterator.isFinished()) { + if (mergedResult != null && iterator.isFinished()) {
+ if (version == currentVersion) { + if (version == currentVersion) {
+ return mergedResult; // content not changed + return mergedResult; // content not changed