mirror of
https://github.com/filoghost/HolographicDisplays.git
synced 2025-01-04 15:17:50 +01:00
Improve NMS implementation
This commit is contained in:
parent
98f27b73b4
commit
6be5f00f53
@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) filoghost and contributors
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
*/
|
|
||||||
package me.filoghost.holographicdisplays.nms.v1_17_R1;
|
|
||||||
|
|
||||||
class DataWatcherEntry<T> {
|
|
||||||
|
|
||||||
private final DataWatcherKey<T> key;
|
|
||||||
private final T value;
|
|
||||||
|
|
||||||
DataWatcherEntry(DataWatcherKey<T> key, T value) {
|
|
||||||
this.key = key;
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataWatcherKey<T> getKey() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
T getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -26,12 +26,12 @@ class DataWatcherKey<T> {
|
|||||||
static DataWatcherKey<ItemStack> ITEM_STACK = new DataWatcherKey<>(8, ITEM_STACK_SERIALIZER);
|
static DataWatcherKey<ItemStack> ITEM_STACK = new DataWatcherKey<>(8, ITEM_STACK_SERIALIZER);
|
||||||
static DataWatcherKey<Byte> ARMOR_STAND_STATUS = new DataWatcherKey<>(15, BYTE_SERIALIZER);
|
static DataWatcherKey<Byte> ARMOR_STAND_STATUS = new DataWatcherKey<>(15, BYTE_SERIALIZER);
|
||||||
|
|
||||||
private final int keyIndex;
|
private final int index;
|
||||||
private final DataWatcherSerializer<T> serializer;
|
private final DataWatcherSerializer<T> serializer;
|
||||||
private final int serializerTypeID;
|
private final int serializerTypeID;
|
||||||
|
|
||||||
private DataWatcherKey(int keyIndex, DataWatcherSerializer<T> serializer) {
|
private DataWatcherKey(int index, DataWatcherSerializer<T> serializer) {
|
||||||
this.keyIndex = keyIndex;
|
this.index = index;
|
||||||
this.serializer = serializer;
|
this.serializer = serializer;
|
||||||
this.serializerTypeID = DataWatcherRegistry.b(serializer);
|
this.serializerTypeID = DataWatcherRegistry.b(serializer);
|
||||||
if (serializerTypeID < 0) {
|
if (serializerTypeID < 0) {
|
||||||
@ -39,8 +39,8 @@ class DataWatcherKey<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getKeyIndex() {
|
int getIndex() {
|
||||||
return keyIndex;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataWatcherSerializer<T> getSerializer() {
|
DataWatcherSerializer<T> getSerializer() {
|
||||||
|
@ -5,20 +5,22 @@
|
|||||||
*/
|
*/
|
||||||
package me.filoghost.holographicdisplays.nms.v1_17_R1;
|
package me.filoghost.holographicdisplays.nms.v1_17_R1;
|
||||||
|
|
||||||
|
import me.filoghost.fcommons.Strings;
|
||||||
import me.filoghost.holographicdisplays.common.nms.EntityID;
|
import me.filoghost.holographicdisplays.common.nms.EntityID;
|
||||||
|
import net.minecraft.network.chat.IChatBaseComponent;
|
||||||
import net.minecraft.network.protocol.Packet;
|
import net.minecraft.network.protocol.Packet;
|
||||||
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
|
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
|
||||||
|
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.craftbukkit.v1_17_R1.util.CraftChatMessage;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
class EntityMetadataNMSPacket extends VersionNMSPacket {
|
class EntityMetadataNMSPacket extends VersionNMSPacket {
|
||||||
|
|
||||||
private final Packet<?> rawPacket;
|
private final Packet<?> rawPacket;
|
||||||
|
|
||||||
EntityMetadataNMSPacket(EntityID entityID, DataWatcherEntry<?>... dataWatcherEntries) {
|
private EntityMetadataNMSPacket(PacketByteBuffer packetByteBuffer) {
|
||||||
PacketByteBuffer packetByteBuffer = PacketByteBuffer.get();
|
|
||||||
|
|
||||||
packetByteBuffer.writeVarInt(entityID.getNumericID());
|
|
||||||
packetByteBuffer.writeDataWatcherEntries(dataWatcherEntries);
|
|
||||||
|
|
||||||
this.rawPacket = new PacketPlayOutEntityMetadata(packetByteBuffer);
|
this.rawPacket = new PacketPlayOutEntityMetadata(packetByteBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,4 +29,57 @@ class EntityMetadataNMSPacket extends VersionNMSPacket {
|
|||||||
return rawPacket;
|
return rawPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Builder builder(EntityID entityID) {
|
||||||
|
return new Builder(entityID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static class Builder {
|
||||||
|
|
||||||
|
private final PacketByteBuffer packetByteBuffer;
|
||||||
|
|
||||||
|
private Builder(EntityID entityID) {
|
||||||
|
this.packetByteBuffer = PacketByteBuffer.get();
|
||||||
|
|
||||||
|
packetByteBuffer.writeVarInt(entityID.getNumericID());
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder setInvisible() {
|
||||||
|
packetByteBuffer.writeDataWatcherEntry(DataWatcherKey.ENTITY_STATUS, (byte) 0x20); // Invisible
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder setMarkerArmorStand() {
|
||||||
|
setInvisible();
|
||||||
|
packetByteBuffer.writeDataWatcherEntry(DataWatcherKey.ARMOR_STAND_STATUS, (byte) (0x01 | 0x08 | 0x10)); // Small, no base plate, marker
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder setCustomName(String customName) {
|
||||||
|
packetByteBuffer.writeDataWatcherEntry(DataWatcherKey.CUSTOM_NAME, getCustomNameDataWatcherValue(customName));
|
||||||
|
packetByteBuffer.writeDataWatcherEntry(DataWatcherKey.CUSTOM_NAME_VISIBILITY, !Strings.isEmpty(customName));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<IChatBaseComponent> getCustomNameDataWatcherValue(String customName) {
|
||||||
|
customName = Strings.truncate(customName, 300);
|
||||||
|
if (!Strings.isEmpty(customName)) {
|
||||||
|
return Optional.of(CraftChatMessage.fromString(customName, false, true)[0]);
|
||||||
|
} else {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder setItemStack(ItemStack itemStack) {
|
||||||
|
packetByteBuffer.writeDataWatcherEntry(DataWatcherKey.ITEM_STACK, CraftItemStack.asNMSCopy(itemStack));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityMetadataNMSPacket build() {
|
||||||
|
packetByteBuffer.writeDataWatcherEntriesEnd();
|
||||||
|
return new EntityMetadataNMSPacket(packetByteBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,17 +37,14 @@ class PacketByteBuffer extends PacketDataSerializer {
|
|||||||
super.a(array);
|
super.a(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeDataWatcherEntries(DataWatcherEntry<?>... dataWatcherEntries) {
|
<T> void writeDataWatcherEntry(DataWatcherKey<T> key, T value) {
|
||||||
for (DataWatcherEntry<?> dataWatcherItem : dataWatcherEntries) {
|
writeByte(key.getIndex());
|
||||||
writeDataWatcherEntry(dataWatcherItem);
|
writeVarInt(key.getSerializerTypeID());
|
||||||
}
|
key.getSerializer().a(this, value);
|
||||||
writeByte(255); // End of data watcher entries
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> void writeDataWatcherEntry(DataWatcherEntry<T> dataWatcherItem) {
|
void writeDataWatcherEntriesEnd() {
|
||||||
writeByte(dataWatcherItem.getKey().getKeyIndex());
|
writeByte(255);
|
||||||
writeVarInt(dataWatcherItem.getKey().getSerializerTypeID());
|
|
||||||
dataWatcherItem.getKey().getSerializer().a(this, dataWatcherItem.getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ public class VersionNMSManager implements NMSManager {
|
|||||||
this.entityIDGenerator = getEntityIDGenerator(errorCollector);
|
this.entityIDGenerator = getEntityIDGenerator(errorCollector);
|
||||||
|
|
||||||
// Force initialization of class to eventually throw exceptions early
|
// Force initialization of class to eventually throw exceptions early
|
||||||
DataWatcherKey.ENTITY_STATUS.getKeyIndex();
|
DataWatcherKey.ENTITY_STATUS.getIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Supplier<Integer> getEntityIDGenerator(ErrorCollector errorCollector) {
|
private Supplier<Integer> getEntityIDGenerator(ErrorCollector errorCollector) {
|
||||||
|
@ -5,106 +5,90 @@
|
|||||||
*/
|
*/
|
||||||
package me.filoghost.holographicdisplays.nms.v1_17_R1;
|
package me.filoghost.holographicdisplays.nms.v1_17_R1;
|
||||||
|
|
||||||
import me.filoghost.fcommons.Strings;
|
|
||||||
import me.filoghost.fcommons.logging.Log;
|
import me.filoghost.fcommons.logging.Log;
|
||||||
import me.filoghost.holographicdisplays.common.nms.AbstractNMSPacketList;
|
import me.filoghost.holographicdisplays.common.nms.AbstractNMSPacketList;
|
||||||
import me.filoghost.holographicdisplays.common.nms.EntityID;
|
import me.filoghost.holographicdisplays.common.nms.EntityID;
|
||||||
import me.filoghost.holographicdisplays.common.nms.IndividualCustomName;
|
import me.filoghost.holographicdisplays.common.nms.IndividualCustomName;
|
||||||
import me.filoghost.holographicdisplays.common.nms.IndividualNMSPacket;
|
import me.filoghost.holographicdisplays.common.nms.IndividualNMSPacket;
|
||||||
import net.minecraft.network.chat.IChatBaseComponent;
|
|
||||||
import net.minecraft.network.protocol.game.PacketPlayOutEntityDestroy;
|
import net.minecraft.network.protocol.game.PacketPlayOutEntityDestroy;
|
||||||
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.IntList;
|
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.IntList;
|
||||||
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.craftbukkit.v1_17_R1.util.CraftChatMessage;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
class VersionNMSPacketList extends AbstractNMSPacketList {
|
class VersionNMSPacketList extends AbstractNMSPacketList {
|
||||||
|
|
||||||
private static final DataWatcherEntry<Byte> ENTITY_STATUS_INVISIBLE = new DataWatcherEntry<>(DataWatcherKey.ENTITY_STATUS, (byte) 0x20);
|
|
||||||
private static final DataWatcherEntry<Boolean> CUSTOM_NAME_VISIBLE = new DataWatcherEntry<>(DataWatcherKey.CUSTOM_NAME_VISIBILITY, true);
|
|
||||||
private static final DataWatcherEntry<Boolean> CUSTOM_NAME_INVISIBLE = new DataWatcherEntry<>(DataWatcherKey.CUSTOM_NAME_VISIBILITY, false);
|
|
||||||
private static final DataWatcherEntry<Byte> ARMOR_STAND_STATUS_MARKER = new DataWatcherEntry<>(DataWatcherKey.ARMOR_STAND_STATUS, (byte) (0x01 | 0x08 | 0x10)); // Small, no base plate, marker
|
|
||||||
|
|
||||||
private static final boolean USE_ENTITY_LIST_DESTROY_PACKET = useEntityListDestroyPacket();
|
private static final boolean USE_ENTITY_LIST_DESTROY_PACKET = useEntityListDestroyPacket();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addArmorStandSpawnPackets(EntityID entityID, double locationX, double locationY, double locationZ) {
|
public void addArmorStandSpawnPackets(EntityID entityID, double locationX, double locationY, double locationZ) {
|
||||||
add(new EntityLivingSpawnNMSPacket(entityID, EntityTypeID.ARMOR_STAND, locationX, locationY, locationZ));
|
add(new EntityLivingSpawnNMSPacket(entityID, EntityTypeID.ARMOR_STAND, locationX, locationY, locationZ));
|
||||||
add(new EntityMetadataNMSPacket(entityID,
|
add(EntityMetadataNMSPacket.builder(entityID)
|
||||||
ENTITY_STATUS_INVISIBLE,
|
.setMarkerArmorStand()
|
||||||
ARMOR_STAND_STATUS_MARKER
|
.build()
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addArmorStandSpawnPackets(EntityID entityID, double locationX, double locationY, double locationZ, String customName) {
|
public void addArmorStandSpawnPackets(EntityID entityID, double locationX, double locationY, double locationZ, String customName) {
|
||||||
add(new EntityLivingSpawnNMSPacket(entityID, EntityTypeID.ARMOR_STAND, locationX, locationY, locationZ));
|
add(new EntityLivingSpawnNMSPacket(entityID, EntityTypeID.ARMOR_STAND, locationX, locationY, locationZ));
|
||||||
add(createFullArmorStandMetadataPacket(entityID, customName));
|
add(EntityMetadataNMSPacket.builder(entityID)
|
||||||
|
.setMarkerArmorStand()
|
||||||
|
.setCustomName(customName)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addArmorStandSpawnPackets(EntityID entityID, double locationX, double locationY, double locationZ, IndividualCustomName individualCustomName) {
|
public void addArmorStandSpawnPackets(EntityID entityID, double locationX, double locationY, double locationZ, IndividualCustomName individualCustomName) {
|
||||||
add(new EntityLivingSpawnNMSPacket(entityID, EntityTypeID.ARMOR_STAND, locationX, locationY, locationZ));
|
add(new EntityLivingSpawnNMSPacket(entityID, EntityTypeID.ARMOR_STAND, locationX, locationY, locationZ));
|
||||||
add(new IndividualNMSPacket(player -> createFullArmorStandMetadataPacket(entityID, individualCustomName.get(player))));
|
add(new IndividualNMSPacket(player -> EntityMetadataNMSPacket.builder(entityID)
|
||||||
}
|
.setMarkerArmorStand()
|
||||||
|
.setCustomName(individualCustomName.get(player))
|
||||||
private EntityMetadataNMSPacket createFullArmorStandMetadataPacket(EntityID entityID, String customName) {
|
.build()
|
||||||
return new EntityMetadataNMSPacket(entityID,
|
));
|
||||||
ENTITY_STATUS_INVISIBLE,
|
|
||||||
new DataWatcherEntry<>(DataWatcherKey.CUSTOM_NAME, getCustomNameDataWatcherValue(customName)),
|
|
||||||
Strings.isEmpty(customName) ? CUSTOM_NAME_INVISIBLE : CUSTOM_NAME_VISIBLE,
|
|
||||||
ARMOR_STAND_STATUS_MARKER
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addArmorStandNameChangePackets(EntityID entityID, String customName) {
|
public void addArmorStandNameChangePackets(EntityID entityID, String customName) {
|
||||||
add(createPartialArmorStandMetadataPacket(entityID, customName));
|
add(EntityMetadataNMSPacket.builder(entityID)
|
||||||
|
.setCustomName(customName)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addArmorStandNameChangePackets(EntityID entityID, IndividualCustomName individualCustomName) {
|
public void addArmorStandNameChangePackets(EntityID entityID, IndividualCustomName individualCustomName) {
|
||||||
add(new IndividualNMSPacket(player -> createPartialArmorStandMetadataPacket(entityID, individualCustomName.get(player))));
|
add(new IndividualNMSPacket(player -> EntityMetadataNMSPacket.builder(entityID)
|
||||||
}
|
.setCustomName(individualCustomName.get(player))
|
||||||
|
.build()
|
||||||
private EntityMetadataNMSPacket createPartialArmorStandMetadataPacket(EntityID entityID, String customName) {
|
));
|
||||||
return new EntityMetadataNMSPacket(entityID,
|
|
||||||
new DataWatcherEntry<>(DataWatcherKey.CUSTOM_NAME, getCustomNameDataWatcherValue(customName)),
|
|
||||||
Strings.isEmpty(customName) ? CUSTOM_NAME_INVISIBLE : CUSTOM_NAME_VISIBLE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<IChatBaseComponent> getCustomNameDataWatcherValue(String customName) {
|
|
||||||
customName = Strings.truncate(customName, 300);
|
|
||||||
if (!Strings.isEmpty(customName)) {
|
|
||||||
return Optional.of(CraftChatMessage.fromString(customName, false, true)[0]);
|
|
||||||
} else {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addItemSpawnPackets(EntityID entityID, double locationX, double locationY, double locationZ, ItemStack itemStack) {
|
public void addItemSpawnPackets(EntityID entityID, double locationX, double locationY, double locationZ, ItemStack itemStack) {
|
||||||
add(new EntitySpawnNMSPacket(entityID, EntityTypeID.ITEM, locationX, locationY, locationZ));
|
add(new EntitySpawnNMSPacket(entityID, EntityTypeID.ITEM, locationX, locationY, locationZ));
|
||||||
add(new EntityMetadataNMSPacket(entityID,
|
add(EntityMetadataNMSPacket.builder(entityID)
|
||||||
new DataWatcherEntry<>(DataWatcherKey.ITEM_STACK, CraftItemStack.asNMSCopy(itemStack))
|
.setItemStack(itemStack)
|
||||||
));
|
.build()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addItemStackChangePackets(EntityID entityID, ItemStack itemStack) {
|
public void addItemStackChangePackets(EntityID entityID, ItemStack itemStack) {
|
||||||
add(new EntityMetadataNMSPacket(entityID,
|
add(EntityMetadataNMSPacket.builder(entityID)
|
||||||
new DataWatcherEntry<>(DataWatcherKey.ITEM_STACK, CraftItemStack.asNMSCopy(itemStack))
|
.setItemStack(itemStack)
|
||||||
));
|
.build()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addSlimeSpawnPackets(EntityID entityID, double locationX, double locationY, double locationZ) {
|
public void addSlimeSpawnPackets(EntityID entityID, double locationX, double locationY, double locationZ) {
|
||||||
add(new EntityLivingSpawnNMSPacket(entityID, EntityTypeID.SLIME, locationX, locationY, locationZ));
|
add(new EntityLivingSpawnNMSPacket(entityID, EntityTypeID.SLIME, locationX, locationY, locationZ));
|
||||||
add(new EntityMetadataNMSPacket(entityID, ENTITY_STATUS_INVISIBLE));
|
add(EntityMetadataNMSPacket.builder(entityID)
|
||||||
|
.setInvisible()
|
||||||
|
.build()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user