9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-31 21:06:31 +00:00

重构发包物品系统

This commit is contained in:
XiaoMoMi
2025-05-28 00:29:31 +08:00
parent fb40b49549
commit e491b28722
22 changed files with 364 additions and 372 deletions

View File

@@ -15,6 +15,7 @@ import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.*;
import net.momirealms.craftengine.core.item.modifier.IdModifier;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
@@ -57,7 +58,7 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
this.itemEventListener = new ItemEventListener(plugin);
this.debugStickListener = new DebugStickListener(plugin);
this.armorEventListener = new ArmorEventListener();
this.networkItemHandler = new LegacyNetworkItemHandler(this);
this.networkItemHandler = new ModernNetworkItemHandler(this);
this.registerAllVanillaItems();
}
@@ -73,11 +74,25 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
}
public Optional<ItemStack> s2c(ItemStack itemStack, ItemBuildContext context) {
return this.networkItemHandler.s2c(itemStack, context);
try {
return this.networkItemHandler.s2c(itemStack, context);
} catch (Throwable e) {
if (Config.debug()) {
this.plugin.logger().warn("Failed to handle s2c items.", e);
}
return Optional.empty();
}
}
public Optional<ItemStack> c2s(ItemStack itemStack, ItemBuildContext context) {
return this.networkItemHandler.c2s(itemStack, context);
try {
return this.networkItemHandler.c2s(itemStack, context);
} catch (Throwable e) {
if (Config.debug()) {
this.plugin.logger().warn("Failed to handle c2s items.", e);
}
return Optional.empty();
}
}
@Override

View File

@@ -108,6 +108,7 @@ public class ComponentItemWrapper implements ItemWrapper<ItemStack> {
@SuppressWarnings({"rawtypes", "unchecked"})
private void setComponentInternal(Object type, DynamicOps ops, Object value) {
if (value == null) return;
Object componentType = ensureDataComponentType(type);
Codec codec = FastNMS.INSTANCE.method$DataComponentType$codec(componentType);
try {

View File

@@ -1,63 +0,0 @@
package net.momirealms.craftengine.bukkit.item;
import net.momirealms.craftengine.core.item.CustomItem;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.ItemBuildContext;
import net.momirealms.craftengine.core.plugin.config.Config;
import org.bukkit.inventory.ItemStack;
import java.util.Optional;
public class LegacyNetworkItemHandler implements NetworkItemHandler {
private final BukkitItemManager itemManager;
public LegacyNetworkItemHandler(BukkitItemManager itemManager) {
this.itemManager = itemManager;
}
@Override
public Optional<ItemStack> c2s(ItemStack itemStack, ItemBuildContext context) {
Item<ItemStack> wrapped = this.itemManager.wrap(itemStack);
if (wrapped == null) return Optional.empty();
return Optional.empty();
}
@Override
public Optional<ItemStack> s2c(ItemStack itemStack, ItemBuildContext context) {
Item<ItemStack> wrapped = this.itemManager.wrap(itemStack);
if (wrapped == null) return Optional.empty();
Optional<CustomItem<ItemStack>> optionalCustomItem = wrapped.getCustomItem();
if (optionalCustomItem.isEmpty()) {
return s2cOtherItems(wrapped, context);
} else {
return Optional.empty();
}
}
private Optional<ItemStack> s2cOtherItems(Item<ItemStack> item, ItemBuildContext context) {
if (!Config.interceptItem()) return Optional.empty();
// Optional<List<String>> optionalLore = item.lore();
// if (optionalLore.isPresent()) {
// boolean changed = false;
// List<String> lore = optionalLore.get();
// List<String> newLore = new ArrayList<>(lore.size());
// for (String line : lore) {
// Map<String, Component> tokens = CraftEngine.instance().fontManager().matchTags(line);
// if (tokens.isEmpty()) {
// newLore.add(line);
// } else {
// newLore.add(AdventureHelper.componentToJson(AdventureHelper.replaceText(AdventureHelper.jsonToComponent(line), tokens)));
// changed = true;
// }
// }
// if (changed) {
// item.lore(newLore);
// }
// }
//
return Optional.empty();
}
}

View File

@@ -0,0 +1,150 @@
package net.momirealms.craftengine.bukkit.item;
import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.core.item.ComponentKeys;
import net.momirealms.craftengine.core.item.CustomItem;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.ItemBuildContext;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.util.AdventureHelper;
import net.momirealms.craftengine.core.util.VersionHelper;
import net.momirealms.sparrow.nbt.CompoundTag;
import net.momirealms.sparrow.nbt.ListTag;
import net.momirealms.sparrow.nbt.StringTag;
import net.momirealms.sparrow.nbt.Tag;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public class ModernNetworkItemHandler implements NetworkItemHandler {
private final BukkitItemManager itemManager;
public ModernNetworkItemHandler(BukkitItemManager itemManager) {
this.itemManager = itemManager;
}
@Override
public Optional<ItemStack> c2s(ItemStack itemStack, ItemBuildContext context) {
Item<ItemStack> wrapped = this.itemManager.wrap(itemStack);
if (wrapped == null) return Optional.empty();
Tag customData = wrapped.getNBTComponent(ComponentTypes.CUSTOM_DATA);
if (!(customData instanceof CompoundTag compoundTag)) return Optional.empty();
CompoundTag networkData = compoundTag.getCompound(NETWORK_ITEM_TAG);
if (networkData == null) return Optional.empty();
compoundTag.remove(NETWORK_ITEM_TAG);
for (Map.Entry<String, Tag> entry : networkData.entrySet()) {
if (entry.getValue() instanceof CompoundTag tag) {
NetworkItemHandler.apply(entry.getKey(), tag, wrapped);
}
}
if (compoundTag.isEmpty()) {
wrapped.resetComponent(ComponentTypes.CUSTOM_DATA);
} else {
wrapped.setNBTComponent(ComponentTypes.CUSTOM_DATA, compoundTag);
}
return Optional.of(wrapped.load());
}
@Override
public Optional<ItemStack> s2c(ItemStack itemStack, ItemBuildContext context) {
Item<ItemStack> wrapped = this.itemManager.wrap(itemStack);
if (wrapped == null) return Optional.empty();
Optional<CustomItem<ItemStack>> optionalCustomItem = wrapped.getCustomItem();
if (optionalCustomItem.isEmpty()) {
if (!Config.interceptItem()) return Optional.empty();
return new OtherItem(wrapped).process();
} else {
return Optional.empty();
}
}
static class OtherItem {
private final Item<ItemStack> item;
private boolean globalChanged = false;
private CompoundTag tag;
public OtherItem(Item<ItemStack> item) {
this.item = item;
}
public Optional<ItemStack> process() {
if (VersionHelper.isOrAbove1_21_5()) {
processModernLore();
} else {
processLore();
}
if (this.globalChanged) {
CompoundTag customData = Optional.ofNullable(this.item.getNBTComponent(ComponentTypes.CUSTOM_DATA)).map(CompoundTag.class::cast).orElse(new CompoundTag());
customData.put(NETWORK_ITEM_TAG, getOrCreateTag());
this.item.setNBTComponent(ComponentKeys.CUSTOM_DATA, customData);
return Optional.of(this.item.load());
} else {
return Optional.empty();
}
}
private void processLore() {
Optional<List<String>> optionalLore = this.item.loreJson();
if (optionalLore.isPresent()) {
boolean changed = false;
List<String> lore = optionalLore.get();
List<String> newLore = new ArrayList<>(lore.size());
for (String line : lore) {
Map<String, Component> tokens = CraftEngine.instance().fontManager().matchTags(line);
if (tokens.isEmpty()) {
newLore.add(line);
} else {
newLore.add(AdventureHelper.componentToJson(AdventureHelper.replaceText(AdventureHelper.jsonToComponent(line), tokens)));
changed = true;
}
}
if (changed) {
this.globalChanged = true;
this.item.loreJson(newLore);
ListTag listTag = new ListTag();
for (String line : lore) {
listTag.add(new StringTag(line));
}
getOrCreateTag().put(ComponentKeys.LORE.asString(), NetworkItemHandler.pack(Operation.ADD, listTag));
}
}
}
private void processModernLore() {
Tag loreTag = this.item.getNBTComponent(ComponentTypes.LORE);
if (loreTag == null) return;
boolean changed = false;
if (!(loreTag instanceof ListTag listTag)) {
return;
}
ListTag newLore = new ListTag();
for (Tag tag : listTag) {
String tagStr = tag.getAsString();
Map<String, Component> tokens = CraftEngine.instance().fontManager().matchTags(tagStr);
if (tokens.isEmpty()) {
newLore.add(tag);
} else {
newLore.add(AdventureHelper.componentToNbt(AdventureHelper.replaceText(AdventureHelper.nbtToComponent(tag), tokens)));
changed = true;
}
}
if (changed) {
this.globalChanged = true;
this.item.setNBTComponent(ComponentKeys.LORE, newLore);
getOrCreateTag().put(ComponentKeys.LORE.asString(), NetworkItemHandler.pack(Operation.ADD, listTag));
}
}
private CompoundTag getOrCreateTag() {
if (this.tag == null) {
this.tag = new CompoundTag();
}
return this.tag;
}
}
}

View File

@@ -1,13 +1,57 @@
package net.momirealms.craftengine.bukkit.item;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.ItemBuildContext;
import net.momirealms.craftengine.core.util.TriConsumer;
import net.momirealms.sparrow.nbt.ByteTag;
import net.momirealms.sparrow.nbt.CompoundTag;
import net.momirealms.sparrow.nbt.Tag;
import org.bukkit.inventory.ItemStack;
import java.util.Map;
import java.util.Optional;
public interface NetworkItemHandler {
Operation[] BY_INDEX = new Operation[] {Operation.ADD, Operation.REMOVE, Operation.RESET};
String NETWORK_ITEM_TAG = "craftengine:network";
String NETWORK_OPERATION = "type";
String NETWORK_VALUE = "value";
Optional<ItemStack> s2c(ItemStack itemStack, ItemBuildContext context);
Optional<ItemStack> c2s(ItemStack itemStack, ItemBuildContext context);
static CompoundTag pack(Operation operation, Tag value) {
return new CompoundTag(Map.of(NETWORK_OPERATION, operation.tag(), NETWORK_VALUE, value));
}
static void apply(String componentType, CompoundTag networkData, Item<ItemStack> item) {
byte index = networkData.getByte(NETWORK_OPERATION);
Operation operation = BY_INDEX[index];
operation.consumer.accept(item, componentType, operation == Operation.ADD ? networkData.get(NETWORK_VALUE) : null);
}
enum Operation {
ADD(0, Item::setNBTComponent),
REMOVE(1, (i, s, t) -> i.removeComponent(s)),
RESET(2, (i, s, t) -> i.resetComponent(s));
private final int id;
private final ByteTag tag;
private final TriConsumer<Item<ItemStack>, String, Tag> consumer;
Operation(int id, TriConsumer<Item<ItemStack>, String, Tag> consumer) {
this.id = id;
this.tag = new ByteTag((byte) id);
this.consumer = consumer;
}
public int id() {
return this.id;
}
public ByteTag tag() {
return tag;
}
}
}

View File

@@ -1,6 +1,8 @@
package net.momirealms.craftengine.bukkit.item.factory;
import com.google.gson.JsonElement;
import com.saicone.rtag.item.ItemTagStream;
import net.momirealms.craftengine.bukkit.item.LegacyItemWrapper;
import net.momirealms.craftengine.bukkit.util.ItemTags;
import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.core.item.EquipmentData;
@@ -9,6 +11,7 @@ import net.momirealms.craftengine.core.item.ItemWrapper;
import net.momirealms.craftengine.core.item.JukeboxPlayable;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.sparrow.nbt.Tag;
import org.bukkit.inventory.ItemStack;
import java.util.Objects;
@@ -87,6 +90,36 @@ public abstract class BukkitItemFactory<W extends ItemWrapper<ItemStack>> extend
}
}
@Override
protected void setJavaComponent(W item, Object type, Object value) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected void setJsonComponent(W item, Object type, JsonElement value) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected void setNBTComponent(W item, Object type, Tag value) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected Object getJavaComponent(W item, Object type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected JsonElement getJsonComponent(W item, Object type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected Tag getNBTComponent(W item, Object type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected void resetComponent(W item, Object type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");

View File

@@ -73,6 +73,21 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
item.setComponent(type, value);
}
@Override
protected void setJavaComponent(ComponentItemWrapper item, Object type, Object value) {
item.setJavaComponent(type, value);
}
@Override
protected void setJsonComponent(ComponentItemWrapper item, Object type, JsonElement value) {
item.setJsonComponent(type, value);
}
@Override
protected void setNBTComponent(ComponentItemWrapper item, Object type, Tag value) {
item.setSparrowNBTComponent(type, value);
}
@Override
protected void resetComponent(ComponentItemWrapper item, Object type) {
item.resetComponent(type);

View File

@@ -1,6 +1,5 @@
package net.momirealms.craftengine.bukkit.item.factory;
import com.google.gson.JsonElement;
import com.saicone.rtag.RtagItem;
import com.saicone.rtag.item.ItemObject;
import com.saicone.rtag.tag.TagBase;
@@ -13,7 +12,6 @@ import net.momirealms.craftengine.core.item.modifier.IdModifier;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.SkullUtils;
import net.momirealms.sparrow.nbt.Tag;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.inventory.ItemFlag;
@@ -33,21 +31,6 @@ public class UniversalItemFactory extends BukkitItemFactory<LegacyItemWrapper> {
return new LegacyItemWrapper(new RtagItem(item), item.getAmount());
}
@Override
protected Object getJavaComponent(LegacyItemWrapper item, Object type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected JsonElement getJsonComponent(LegacyItemWrapper item, Object type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected Tag getNBTComponent(LegacyItemWrapper item, Object type) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
@Override
protected void setTag(LegacyItemWrapper item, Object value, Object... path) {
item.set(value, path);

View File

@@ -40,16 +40,22 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
private static BukkitNetworkManager instance;
private static final Map<Class<?>, TriConsumer<NetWorkUser, NMSPacketEvent, Object>> NMS_PACKET_HANDLERS = new HashMap<>();
// only for game stage for the moment
private static final Map<Integer, BiConsumer<NetWorkUser, ByteBufPacketEvent>> BYTE_BUFFER_PACKET_HANDLERS = new HashMap<>();
private static final Map<Integer, BiConsumer<NetWorkUser, ByteBufPacketEvent>> S2C_BYTE_BUFFER_PACKET_HANDLERS = new HashMap<>();
private static final Map<Integer, BiConsumer<NetWorkUser, ByteBufPacketEvent>> C2S_BYTE_BUFFER_PACKET_HANDLERS = new HashMap<>();
private static void registerNMSPacketConsumer(final TriConsumer<NetWorkUser, NMSPacketEvent, Object> function, @Nullable Class<?> packet) {
if (packet == null) return;
NMS_PACKET_HANDLERS.put(packet, function);
}
private static void registerByteBufPacketConsumer(final BiConsumer<NetWorkUser, ByteBufPacketEvent> function, int id) {
private static void registerS2CByteBufPacketConsumer(final BiConsumer<NetWorkUser, ByteBufPacketEvent> function, int id) {
if (id == -1) return;
BYTE_BUFFER_PACKET_HANDLERS.put(id, function);
S2C_BYTE_BUFFER_PACKET_HANDLERS.put(id, function);
}
private static void registerC2SByteBufPacketConsumer(final BiConsumer<NetWorkUser, ByteBufPacketEvent> function, int id) {
if (id == -1) return;
C2S_BYTE_BUFFER_PACKET_HANDLERS.put(id, function);
}
private final BiConsumer<Object, List<Object>> packetsConsumer;
@@ -155,32 +161,32 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
registerNMSPacketConsumer(PacketConsumers.RESOURCE_PACK_RESPONSE, Reflections.clazz$ServerboundResourcePackPacket);
registerNMSPacketConsumer(PacketConsumers.ENTITY_EVENT, Reflections.clazz$ClientboundEntityEventPacket);
registerNMSPacketConsumer(PacketConsumers.MOVE_POS_AND_ROTATE_ENTITY, Reflections.clazz$ClientboundMoveEntityPacket$PosRot);
registerByteBufPacketConsumer(PacketConsumers.LEVEL_CHUNK_WITH_LIGHT, this.packetIds.clientboundLevelChunkWithLightPacket());
registerByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket());
registerByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket());
registerByteBufPacketConsumer(VersionHelper.isOrAbove1_21_4() ? PacketConsumers.LEVEL_PARTICLE_1_21_4 : (VersionHelper.isOrAbove1_20_5() ? PacketConsumers.LEVEL_PARTICLE_1_20_5 : PacketConsumers.LEVEL_PARTICLE_1_20), this.packetIds.clientboundLevelParticlesPacket());
registerByteBufPacketConsumer(PacketConsumers.LEVEL_EVENT, this.packetIds.clientboundLevelEventPacket());
registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.OPEN_SCREEN_1_20_3 : PacketConsumers.OPEN_SCREEN_1_20, this.packetIds.clientboundOpenScreenPacket());
registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SET_TITLE_TEXT_1_20_3 : PacketConsumers.SET_TITLE_TEXT_1_20, this.packetIds.clientboundSetTitleTextPacket());
registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SET_SUBTITLE_TEXT_1_20_3 : PacketConsumers.SET_SUBTITLE_TEXT_1_20, this.packetIds.clientboundSetSubtitleTextPacket());
registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SET_ACTIONBAR_TEXT_1_20_3 : PacketConsumers.SET_ACTIONBAR_TEXT_1_20, this.packetIds.clientboundSetActionBarTextPacket());
registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.BOSS_EVENT_1_20_3 : PacketConsumers.BOSS_EVENT_1_20, this.packetIds.clientboundBossEventPacket());
registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SYSTEM_CHAT_1_20_3 : PacketConsumers.SYSTEM_CHAT_1_20, this.packetIds.clientboundSystemChatPacket());
registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.TAB_LIST_1_20_3 : PacketConsumers.TAB_LIST_1_20, this.packetIds.clientboundTabListPacket());
registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.TEAM_1_20_3 : PacketConsumers.TEAM_1_20, this.packetIds.clientboundSetPlayerTeamPacket());
registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SET_OBJECTIVE_1_20_3 : PacketConsumers.SET_OBJECTIVE_1_20, this.packetIds.clientboundSetObjectivePacket());
registerByteBufPacketConsumer(PacketConsumers.SET_SCORE_1_20_3, VersionHelper.isOrAbove1_20_3() ? this.packetIds.clientboundSetScorePacket() : -1);
registerByteBufPacketConsumer(PacketConsumers.REMOVE_ENTITY, this.packetIds.clientboundRemoveEntitiesPacket());
registerByteBufPacketConsumer(PacketConsumers.ADD_ENTITY_BYTEBUFFER, this.packetIds.clientboundAddEntityPacket());
registerByteBufPacketConsumer(PacketConsumers.SOUND, this.packetIds.clientboundSoundPacket());
registerByteBufPacketConsumer(PacketConsumers.SET_ENTITY_DATA, this.packetIds.clientboundSetEntityDataPacket());
registerByteBufPacketConsumer(PacketConsumers.CONTAINER_SET_CONTENT, this.packetIds.clientboundContainerSetContentPacket());
registerByteBufPacketConsumer(PacketConsumers.CONTAINER_SET_SLOT, this.packetIds.clientboundContainerSetSlotPacket());
registerByteBufPacketConsumer(PacketConsumers.SET_CURSOR_ITEM, this.packetIds.clientboundSetCursorItemPacket());
registerByteBufPacketConsumer(PacketConsumers.SET_EQUIPMENT, this.packetIds.clientboundSetEquipmentPacket());
registerByteBufPacketConsumer(PacketConsumers.SET_PLAYER_INVENTORY_1_21_2, this.packetIds.clientboundSetPlayerInventoryPacket());
registerByteBufPacketConsumer(PacketConsumers.SET_CREATIVE_MODE_SLOT, this.packetIds.serverboundSetCreativeModeSlotPacket());
registerByteBufPacketConsumer(PacketConsumers.CONTAINER_CLICK_1_20, this.packetIds.serverboundContainerClickPacket());
registerS2CByteBufPacketConsumer(PacketConsumers.LEVEL_CHUNK_WITH_LIGHT, this.packetIds.clientboundLevelChunkWithLightPacket());
registerS2CByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket());
registerS2CByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket());
registerS2CByteBufPacketConsumer(VersionHelper.isOrAbove1_21_4() ? PacketConsumers.LEVEL_PARTICLE_1_21_4 : (VersionHelper.isOrAbove1_20_5() ? PacketConsumers.LEVEL_PARTICLE_1_20_5 : PacketConsumers.LEVEL_PARTICLE_1_20), this.packetIds.clientboundLevelParticlesPacket());
registerS2CByteBufPacketConsumer(PacketConsumers.LEVEL_EVENT, this.packetIds.clientboundLevelEventPacket());
registerS2CByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.OPEN_SCREEN_1_20_3 : PacketConsumers.OPEN_SCREEN_1_20, this.packetIds.clientboundOpenScreenPacket());
registerS2CByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SET_TITLE_TEXT_1_20_3 : PacketConsumers.SET_TITLE_TEXT_1_20, this.packetIds.clientboundSetTitleTextPacket());
registerS2CByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SET_SUBTITLE_TEXT_1_20_3 : PacketConsumers.SET_SUBTITLE_TEXT_1_20, this.packetIds.clientboundSetSubtitleTextPacket());
registerS2CByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SET_ACTIONBAR_TEXT_1_20_3 : PacketConsumers.SET_ACTIONBAR_TEXT_1_20, this.packetIds.clientboundSetActionBarTextPacket());
registerS2CByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.BOSS_EVENT_1_20_3 : PacketConsumers.BOSS_EVENT_1_20, this.packetIds.clientboundBossEventPacket());
registerS2CByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SYSTEM_CHAT_1_20_3 : PacketConsumers.SYSTEM_CHAT_1_20, this.packetIds.clientboundSystemChatPacket());
registerS2CByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.TAB_LIST_1_20_3 : PacketConsumers.TAB_LIST_1_20, this.packetIds.clientboundTabListPacket());
registerS2CByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.TEAM_1_20_3 : PacketConsumers.TEAM_1_20, this.packetIds.clientboundSetPlayerTeamPacket());
registerS2CByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SET_OBJECTIVE_1_20_3 : PacketConsumers.SET_OBJECTIVE_1_20, this.packetIds.clientboundSetObjectivePacket());
registerS2CByteBufPacketConsumer(PacketConsumers.SET_SCORE_1_20_3, VersionHelper.isOrAbove1_20_3() ? this.packetIds.clientboundSetScorePacket() : -1);
registerS2CByteBufPacketConsumer(PacketConsumers.REMOVE_ENTITY, this.packetIds.clientboundRemoveEntitiesPacket());
registerS2CByteBufPacketConsumer(PacketConsumers.ADD_ENTITY_BYTEBUFFER, this.packetIds.clientboundAddEntityPacket());
registerS2CByteBufPacketConsumer(PacketConsumers.SOUND, this.packetIds.clientboundSoundPacket());
registerS2CByteBufPacketConsumer(PacketConsumers.SET_ENTITY_DATA, this.packetIds.clientboundSetEntityDataPacket());
registerS2CByteBufPacketConsumer(PacketConsumers.CONTAINER_SET_CONTENT, this.packetIds.clientboundContainerSetContentPacket());
registerS2CByteBufPacketConsumer(PacketConsumers.CONTAINER_SET_SLOT, this.packetIds.clientboundContainerSetSlotPacket());
registerS2CByteBufPacketConsumer(PacketConsumers.SET_CURSOR_ITEM, this.packetIds.clientboundSetCursorItemPacket());
registerS2CByteBufPacketConsumer(PacketConsumers.SET_EQUIPMENT, this.packetIds.clientboundSetEquipmentPacket());
registerS2CByteBufPacketConsumer(PacketConsumers.SET_PLAYER_INVENTORY_1_21_2, this.packetIds.clientboundSetPlayerInventoryPacket());
registerC2SByteBufPacketConsumer(PacketConsumers.SET_CREATIVE_MODE_SLOT, this.packetIds.serverboundSetCreativeModeSlotPacket());
registerC2SByteBufPacketConsumer(PacketConsumers.CONTAINER_CLICK_1_20, this.packetIds.serverboundContainerClickPacket());
}
public static BukkitNetworkManager instance() {
@@ -573,7 +579,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
int packetId = buf.readVarInt();
int preIndex = buf.readerIndex();
ByteBufPacketEvent event = new ByteBufPacketEvent(packetId, buf, preIndex);
BukkitNetworkManager.this.handleByteBufPacket(this.player, event);
BukkitNetworkManager.this.handleS2CByteBufPacket(this.player, event);
if (event.isCancelled()) {
buf.clear();
} else if (!event.changed()) {
@@ -583,7 +589,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
}
}
public static class PluginChannelDecoder extends MessageToMessageDecoder<ByteBuf> {
public class PluginChannelDecoder extends MessageToMessageDecoder<ByteBuf> {
private final NetWorkUser player;
public PluginChannelDecoder(NetWorkUser player) {
@@ -592,10 +598,30 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
@Override
protected void decode(ChannelHandlerContext context, ByteBuf byteBuf, List<Object> list) {
this.onByteBufReceive(byteBuf);
if (byteBuf.isReadable()) {
list.add(byteBuf.retain());
}
}
private void onByteBufReceive(ByteBuf buffer) {
// I don't care packets before PLAY for the moment
if (player.decoderState() != ConnectionState.PLAY) return;
int size = buffer.readableBytes();
if (size != 0) {
FriendlyByteBuf buf = new FriendlyByteBuf(buffer);
int preProcessIndex = buf.readerIndex();
int packetId = buf.readVarInt();
int preIndex = buf.readerIndex();
ByteBufPacketEvent event = new ByteBufPacketEvent(packetId, buf, preIndex);
BukkitNetworkManager.this.handleC2SByteBufPacket(this.player, event);
if (event.isCancelled()) {
buf.clear();
} else if (!event.changed()) {
buf.readerIndex(preProcessIndex);
}
}
}
}
private void onNMSPacketReceive(NetWorkUser user, NMSPacketEvent event, Object packet) {
@@ -618,9 +644,15 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
.ifPresent(function -> function.accept(user, event, packet));
}
protected void handleByteBufPacket(NetWorkUser user, ByteBufPacketEvent event) {
protected void handleS2CByteBufPacket(NetWorkUser user, ByteBufPacketEvent event) {
int packetID = event.packetID();
Optional.ofNullable(BYTE_BUFFER_PACKET_HANDLERS.get(packetID))
Optional.ofNullable(S2C_BYTE_BUFFER_PACKET_HANDLERS.get(packetID))
.ifPresent(function -> function.accept(user, event));
}
protected void handleC2SByteBufPacket(NetWorkUser user, ByteBufPacketEvent event) {
int packetID = event.packetID();
Optional.ofNullable(C2S_BYTE_BUFFER_PACKET_HANDLERS.get(packetID))
.ifPresent(function -> function.accept(user, event));
}