9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-19 15:09:15 +00:00

拦截容器物品

This commit is contained in:
XiaoMoMi
2025-05-27 04:18:49 +08:00
parent f08544f82e
commit d9960da796
10 changed files with 110 additions and 61 deletions

View File

@@ -129,11 +129,10 @@ The code you contribute will be open-sourced under the GPLv3 license. If you pre
3. Once done, submit a **pull request** for review. We appreciate your contributions! 3. Once done, submit a **pull request** for review. We appreciate your contributions!
## Differences Between Versions ## Differences Between Versions
| Version | Official Support | Max Players | Online Mode Required | Commercial Use | | Version | Official Support | Max Players | Dev Builds |
|-------------------|------------------|-------------|----------------------|----------------| |-------------------|------------------|-------------|------------|
| Community Edition | ❌ No | 20 | ✔️ Yes | ✔️ Allowed | | Community Edition | ❌ No | 20 | ❌ No |
| GitHub Edition | ❌ No | Unlimited | ❌ No | ✔️ Allowed | | Premium Edition | ✔️ Yes | Unlimited | ✔️ Yes |
| Premium Edition | ✔️ Yes | Unlimited | ❌ No | ✔️ Allowed |
### 💖 Support the Developer ### 💖 Support the Developer
Help sustain CraftEngine's development by going Premium! Help sustain CraftEngine's development by going Premium!

View File

@@ -60,56 +60,6 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
this.debugStickListener = new DebugStickListener(plugin); this.debugStickListener = new DebugStickListener(plugin);
this.armorEventListener = new ArmorEventListener(); this.armorEventListener = new ArmorEventListener();
this.registerAllVanillaItems(); this.registerAllVanillaItems();
if (plugin.hasMod()) {
Class<?> clazz$CustomStreamCodec = ReflectionUtils.getClazz("net.momirealms.craftengine.mod.item.CustomStreamCodec");
if (clazz$CustomStreamCodec != null) {
Field s2cProcessor = ReflectionUtils.getDeclaredField(clazz$CustomStreamCodec, Function.class, 0);
Field c2sProcessor = ReflectionUtils.getDeclaredField(clazz$CustomStreamCodec, Function.class, 1);
Function<Object, Object> s2c = (raw) -> {
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(raw);
Item<ItemStack> wrapped = this.wrap(itemStack.clone());
Optional<CustomItem<ItemStack>> customItem = wrapped.getCustomItem();
if (customItem.isEmpty()) {
return raw;
}
CustomItem<ItemStack> custom = customItem.get();
if (!custom.hasClientBoundDataModifier()) {
return raw;
}
for (NetworkItemDataProcessor<ItemStack> processor : custom.networkItemDataProcessors()) {
processor.toClient(wrapped, ItemBuildContext.EMPTY);
}
wrapped.load();
return wrapped.getLiteralObject();
};
Function<Object, Object> c2s = (raw) -> {
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(raw);
Item<ItemStack> wrapped = this.wrap(itemStack);
Optional<CustomItem<ItemStack>> customItem = wrapped.getCustomItem();
if (customItem.isEmpty()) {
return raw;
}
CustomItem<ItemStack> custom = customItem.get();
if (!custom.hasClientBoundDataModifier()) {
return raw;
}
for (NetworkItemDataProcessor<ItemStack> processor : custom.networkItemDataProcessors()) {
processor.toServer(wrapped, ItemBuildContext.EMPTY);
}
wrapped.load();
return wrapped.getLiteralObject();
};
try {
assert s2cProcessor != null;
s2cProcessor.set(null, s2c);
assert c2sProcessor != null;
c2sProcessor.set(null, c2s);
} catch (ReflectiveOperationException e) {
plugin.logger().warn("Failed to load custom stream codec", e);
}
}
}
} }
@Override @Override
@@ -123,6 +73,34 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
return instance; return instance;
} }
@SuppressWarnings("DuplicatedCode")
public Optional<ItemStack> s2c(ItemStack itemStack, ItemBuildContext context) {
Item<ItemStack> wrapped = this.wrap(itemStack.clone());
if (wrapped == null) return Optional.empty();
Optional<CustomItem<ItemStack>> customItem = wrapped.getCustomItem();
if (customItem.isEmpty()) return Optional.empty();
CustomItem<ItemStack> custom = customItem.get();
if (!custom.hasClientBoundDataModifier()) return Optional.empty();
for (NetworkItemDataProcessor<ItemStack> processor : custom.networkItemDataProcessors()) {
processor.toClient(wrapped, context);
}
return Optional.of(wrapped.load());
}
@SuppressWarnings("DuplicatedCode")
public Optional<ItemStack> c2s(ItemStack itemStack, ItemBuildContext context) {
Item<ItemStack> wrapped = this.wrap(itemStack);
if (wrapped == null) return Optional.empty();
Optional<CustomItem<ItemStack>> customItem = wrapped.getCustomItem();
if (customItem.isEmpty()) return Optional.empty();
CustomItem<ItemStack> custom = customItem.get();
if (!custom.hasClientBoundDataModifier()) return Optional.empty();
for (NetworkItemDataProcessor<ItemStack> processor : custom.networkItemDataProcessors()) {
processor.toServer(wrapped, context);
}
return Optional.of(wrapped.load());
}
@Override @Override
public Optional<BuildableItem<ItemStack>> getVanillaItem(Key key) { public Optional<BuildableItem<ItemStack>> getVanillaItem(Key key) {
Material material = Registry.MATERIAL.get(KeyUtils.toNamespacedKey(key)); Material material = Registry.MATERIAL.get(KeyUtils.toNamespacedKey(key));

View File

@@ -174,6 +174,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
registerByteBufPacketConsumer(PacketConsumers.ADD_ENTITY_BYTEBUFFER, this.packetIds.clientboundAddEntityPacket()); registerByteBufPacketConsumer(PacketConsumers.ADD_ENTITY_BYTEBUFFER, this.packetIds.clientboundAddEntityPacket());
registerByteBufPacketConsumer(PacketConsumers.SOUND, this.packetIds.clientboundSoundPacket()); registerByteBufPacketConsumer(PacketConsumers.SOUND, this.packetIds.clientboundSoundPacket());
registerByteBufPacketConsumer(PacketConsumers.SET_ENTITY_DATA, this.packetIds.clientboundSetEntityDataPacket()); registerByteBufPacketConsumer(PacketConsumers.SET_ENTITY_DATA, this.packetIds.clientboundSetEntityDataPacket());
registerByteBufPacketConsumer(PacketConsumers.CONTAINER_SET_CONTENT, this.packetIds.clientboundContainerSetContentPacket());
} }
public static BukkitNetworkManager instance() { public static BukkitNetworkManager instance() {

View File

@@ -13,6 +13,7 @@ import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture; import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture;
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager;
import net.momirealms.craftengine.bukkit.entity.projectile.BukkitProjectileManager; import net.momirealms.craftengine.bukkit.entity.projectile.BukkitProjectileManager;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.item.behavior.FurnitureItemBehavior; import net.momirealms.craftengine.bukkit.item.behavior.FurnitureItemBehavior;
import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.pack.BukkitPackManager; import net.momirealms.craftengine.bukkit.pack.BukkitPackManager;
@@ -27,6 +28,7 @@ import net.momirealms.craftengine.core.font.FontManager;
import net.momirealms.craftengine.core.font.IllegalCharacterProcessResult; import net.momirealms.craftengine.core.font.IllegalCharacterProcessResult;
import net.momirealms.craftengine.core.item.CustomItem; import net.momirealms.craftengine.core.item.CustomItem;
import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.ItemBuildContext;
import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
import net.momirealms.craftengine.core.item.context.UseOnContext; import net.momirealms.craftengine.core.item.context.UseOnContext;
import net.momirealms.craftengine.core.pack.host.ResourcePackDownloadData; import net.momirealms.craftengine.core.pack.host.ResourcePackDownloadData;
@@ -2147,6 +2149,50 @@ public class PacketConsumers {
} }
}; };
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> CONTAINER_SET_CONTENT = (user, event) -> {
try {
FriendlyByteBuf buf = event.getBuffer();
int containerId = buf.readContainerId();
int stateId = buf.readVarInt();
int listSize = buf.readVarInt();
ItemBuildContext context = ItemBuildContext.of((BukkitServerPlayer) user);
List<ItemStack> items = new ArrayList<>(listSize);
boolean changed = false;
Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
for (int i = 0; i < listSize; i++) {
ItemStack itemStack = FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf);
Optional<ItemStack> optional = BukkitItemManager.instance().s2c(itemStack, context);
if (optional.isPresent()) {
items.add(optional.get());
changed = true;
} else {
items.add(itemStack);
}
}
ItemStack carriedItem = FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf);
ItemStack newCarriedItem = carriedItem;
Optional<ItemStack> optional = BukkitItemManager.instance().s2c(carriedItem, context);
if (optional.isPresent()) {
changed = true;
newCarriedItem = optional.get();
}
if (!changed) return;
event.setChanged(true);
buf.clear();
buf.writeVarInt(event.packetID());
buf.writeContainerId(containerId);
buf.writeVarInt(stateId);
buf.writeVarInt(listSize);
Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf);
for (ItemStack itemStack : items) {
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, itemStack);
}
FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, newCarriedItem);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundContainerSetContentPacket", e);
}
};
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> RESOURCE_PACK_PUSH = (user, event, packet) -> { public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> RESOURCE_PACK_PUSH = (user, event, packet) -> {
try { try {
if (!VersionHelper.isOrAbove1_20_2()) return; if (!VersionHelper.isOrAbove1_20_2()) return;

View File

@@ -41,4 +41,6 @@ public interface PacketIds {
int clientboundPlayerInfoUpdatePacket(); int clientboundPlayerInfoUpdatePacket();
int clientboundSetScorePacket(); int clientboundSetScorePacket();
int clientboundContainerSetContentPacket();
} }

View File

@@ -104,4 +104,9 @@ public class PacketIds1_20 implements PacketIds {
public int clientboundSetScorePacket() { public int clientboundSetScorePacket() {
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundSetScorePacket); return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundSetScorePacket);
} }
@Override
public int clientboundContainerSetContentPacket() {
return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundContainerSetContentPacket);
}
} }

View File

@@ -103,4 +103,9 @@ public class PacketIds1_20_5 implements PacketIds {
public int clientboundSetScorePacket() { public int clientboundSetScorePacket() {
return PacketIdFinder.clientboundByName("minecraft:set_score"); return PacketIdFinder.clientboundByName("minecraft:set_score");
} }
@Override
public int clientboundContainerSetContentPacket() {
return PacketIdFinder.clientboundByName("minecraft:container_set_content");
}
} }

View File

@@ -6822,9 +6822,10 @@ public class Reflections {
.orElse(ReflectionUtils.getMethod(clazz$BlockBehaviour, void.class, clazz$BlockState, clazz$Level, clazz$BlockPos, clazz$Block, clazz$BlockPos, boolean.class)) .orElse(ReflectionUtils.getMethod(clazz$BlockBehaviour, void.class, clazz$BlockState, clazz$Level, clazz$BlockPos, clazz$Block, clazz$BlockPos, boolean.class))
); );
// public static final Method method$BlockBehaviour$getEntityInsideCollisionShape = requireNonNull( public static final Class<?> clazz$ClientboundContainerSetContentPacket = requireNonNull(
// ReflectionUtils.getDeclaredMethod( BukkitReflectionUtils.findReobfOrMojmapClass(
// clazz$BlockBehaviour, clazz$VoxelShape, clazz$BlockState, clazz$BlockGetter, clazz$BlockPos, clazz$Entity "network.protocol.game.PacketPlayOutWindowItems",
// ) "network.protocol.game.ClientboundContainerSetContentPacket"
// ); )
);
} }

View File

@@ -48,6 +48,18 @@ public class FriendlyByteBuf extends ByteBuf {
return BlockPos.of(buf.readLong()); return BlockPos.of(buf.readLong());
} }
public int readContainerId() {
return VersionHelper.isOrAbove1_21_2() ? this.readVarInt() : this.readUnsignedByte();
}
public void writeContainerId(int id) {
if (VersionHelper.isOrAbove1_21_2()) {
this.writeVarInt(id);
} else {
this.writeByte(id);
}
}
public List<String> readStringList() { public List<String> readStringList() {
int i = this.readVarInt(); int i = this.readVarInt();
List<String> list = new ArrayList<>(i); List<String> list = new ArrayList<>(i);

View File

@@ -50,7 +50,7 @@ byte_buddy_version=1.17.5
ahocorasick_version=0.6.3 ahocorasick_version=0.6.3
snake_yaml_version=2.4 snake_yaml_version=2.4
anti_grief_version=0.17 anti_grief_version=0.17
nms_helper_version=0.65.33 nms_helper_version=0.66
evalex_version=3.5.0 evalex_version=3.5.0
reactive_streams_version=1.0.4 reactive_streams_version=1.0.4
amazon_awssdk_version=2.31.23 amazon_awssdk_version=2.31.23