ProtocolLib-related code refactoring

This commit is contained in:
filoghost 2019-09-11 15:14:36 +02:00
parent 70e070ac11
commit 04d8cf0c92
3 changed files with 351 additions and 215 deletions

View File

@ -0,0 +1,177 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.gmail.filoghost.holographicdisplays.bridge.protocollib.current;
import java.util.List;
import java.util.Optional;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject;
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
import com.gmail.filoghost.holographicdisplays.util.NMSVersion;
public class MetadataHelper {
private Serializer itemSerializer;
private Serializer intSerializer;
private Serializer byteSerializer;
private Serializer stringSerializer;
private Serializer booleanSerializer;
private Serializer chatComponentSerializer;
private int itemSlotIndex;
private int entityStatusIndex;
private int airLevelWatcherIndex;
private int customNameIndex;
private int customNameVisibleIndex;
private int noGravityIndex;
private int armorStandStatusIndex;
public MetadataHelper() {
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_14_R1)) {
itemSlotIndex = 7;
} else if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_10_R1)) {
itemSlotIndex = 6;
} else if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_9_R1)) {
itemSlotIndex = 5;
} else {
itemSlotIndex = 10;
}
entityStatusIndex = 0;
airLevelWatcherIndex = 1;
customNameIndex = 2;
customNameVisibleIndex = 3;
noGravityIndex = 5;
armorStandStatusIndex = 11;
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_9_R1)) {
itemSerializer = Registry.get(MinecraftReflection.getItemStackClass());
intSerializer = Registry.get(Integer.class);
byteSerializer = Registry.get(Byte.class);
stringSerializer = Registry.get(String.class);
booleanSerializer = Registry.get(Boolean.class);
}
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_13_R1)) {
chatComponentSerializer = Registry.get(MinecraftReflection.getIChatBaseComponentClass(), true);
}
}
public WrappedWatchableObject getCustomNameWacthableObject(WrappedDataWatcher metadata) {
return metadata.getWatchableObject(customNameIndex);
}
public WrappedWatchableObject getCustomNameWatchableObject(List<WrappedWatchableObject> dataWatcherValues) {
for (int i = 0; i < dataWatcherValues.size(); i++) {
WrappedWatchableObject watchableObject = dataWatcherValues.get(i);
if (watchableObject.getIndex() == customNameIndex) {
return watchableObject;
}
}
return null;
}
public String getSerializedCustomName(WrappedWatchableObject customNameWatchableObject) {
Object customNameWatchableObjectValue = customNameWatchableObject.getValue();
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_13_R1)) {
if (!(customNameWatchableObjectValue instanceof Optional)) {
return null;
}
Optional<?> customNameOptional = (Optional<?>) customNameWatchableObjectValue;
if (!customNameOptional.isPresent()) {
return null;
}
WrappedChatComponent componentWrapper = WrappedChatComponent.fromHandle(customNameOptional.get());
return componentWrapper.getJson();
} else {
if (!(customNameWatchableObjectValue instanceof String)) {
return null;
}
return (String) customNameWatchableObjectValue;
}
}
public void setSerializedCustomName(WrappedWatchableObject customNameWatchableObject, String serializedCustomName) {
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_13_R1)) {
customNameWatchableObject.setValue(Optional.of(WrappedChatComponent.fromJson(serializedCustomName).getHandle()));
} else {
customNameWatchableObject.setValue(serializedCustomName);
}
}
public void setEntityStatus_v1_9(WrappedDataWatcher dataWatcher, byte statusBitmask) {
dataWatcher.setObject(new WrappedDataWatcherObject(entityStatusIndex, byteSerializer), statusBitmask);
}
public void setCustomName_v1_9(WrappedDataWatcher dataWatcher, String customName) {
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_13_R1)) {
dataWatcher.setObject(new WrappedDataWatcherObject(customNameIndex, chatComponentSerializer), Optional.of(WrappedChatComponent.fromText(customName).getHandle()));
} else {
dataWatcher.setObject(new WrappedDataWatcherObject(customNameIndex, stringSerializer), customName);
}
}
public void setCustomNameVisible_v1_9(WrappedDataWatcher dataWatcher, boolean customNameVisible) {
dataWatcher.setObject(new WrappedDataWatcherObject(customNameVisibleIndex, booleanSerializer), customNameVisible);
}
public void setNoGravity_v1_9(WrappedDataWatcher dataWatcher, boolean noGravity) {
dataWatcher.setObject(new WrappedDataWatcherObject(noGravityIndex, booleanSerializer), noGravity);
}
public void setArmorStandStatus_v1_9(WrappedDataWatcher dataWatcher, byte statusBitmask) {
dataWatcher.setObject(new WrappedDataWatcherObject(armorStandStatusIndex, byteSerializer), statusBitmask);
}
public void setItemMetadata(WrappedDataWatcher dataWatcher, Object nmsItemStack) {
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_9_R1)) {
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_11_R1)) {
dataWatcher.setObject(new WrappedDataWatcherObject(itemSlotIndex, itemSerializer), nmsItemStack);
} else {
dataWatcher.setObject(new WrappedDataWatcherObject(itemSlotIndex, itemSerializer), com.google.common.base.Optional.of(nmsItemStack));
}
dataWatcher.setObject(new WrappedDataWatcherObject(airLevelWatcherIndex, intSerializer), 300);
dataWatcher.setObject(new WrappedDataWatcherObject(entityStatusIndex, byteSerializer), (byte) 0);
} else {
dataWatcher.setObject(itemSlotIndex, nmsItemStack);
dataWatcher.setObject(airLevelWatcherIndex, 300);
dataWatcher.setObject(entityStatusIndex, (byte) 0);
}
}
}

View File

@ -0,0 +1,125 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.gmail.filoghost.holographicdisplays.bridge.protocollib.current;
import java.util.List;
import org.bukkit.entity.Player;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.AbstractPacket;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.WrapperPlayServerAttachEntity;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.WrapperPlayServerEntityDestroy;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.WrapperPlayServerEntityMetadata;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.WrapperPlayServerMount;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.WrapperPlayServerSpawnEntity;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.WrapperPlayServerSpawnEntityLiving;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.WrapperPlayServerSpawnEntity.ObjectTypes;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSSlime;
import com.gmail.filoghost.holographicdisplays.util.NMSVersion;
public class PacketHelper {
private MetadataHelper metadataHelper;
public PacketHelper(MetadataHelper metadataHelper) {
this.metadataHelper = metadataHelper;
}
public void sendSpawnArmorStandPacket(Player receiver, NMSArmorStand armorStand) {
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_11_R1)) {
AbstractPacket spawnPacket;
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_14_R1)) {
spawnPacket = new WrapperPlayServerSpawnEntityLiving(armorStand.getBukkitEntityNMS());
} else {
spawnPacket = new WrapperPlayServerSpawnEntity(armorStand.getBukkitEntityNMS(), WrapperPlayServerSpawnEntity.ObjectTypes.ARMOR_STAND, 1);
}
spawnPacket.sendPacket(receiver);
WrapperPlayServerEntityMetadata dataPacket = new WrapperPlayServerEntityMetadata();
WrappedDataWatcher dataWatcher = new WrappedDataWatcher();
metadataHelper.setEntityStatus_v1_9(dataWatcher, (byte) 0x20); // Invisible
String customName = armorStand.getCustomNameNMS();
if (customName != null && !customName.isEmpty()) {
metadataHelper.setCustomName_v1_9(dataWatcher, customName);
metadataHelper.setCustomNameVisible_v1_9(dataWatcher, true);
}
metadataHelper.setNoGravity_v1_9(dataWatcher, true);
metadataHelper.setArmorStandStatus_v1_9(dataWatcher, (byte) (0x01 | 0x08 | 0x10)); // Small, no base plate, marker
dataPacket.setEntityMetadata(dataWatcher.getWatchableObjects());
dataPacket.setEntityID(armorStand.getIdNMS());
dataPacket.sendPacket(receiver);
} else {
WrapperPlayServerSpawnEntityLiving spawnPacket = new WrapperPlayServerSpawnEntityLiving(armorStand.getBukkitEntityNMS());
spawnPacket.sendPacket(receiver);
}
}
public void sendSpawnItemPacket(Player receiver, NMSItem item) {
AbstractPacket packet = new WrapperPlayServerSpawnEntity(item.getBukkitEntityNMS(), ObjectTypes.ITEM_STACK, 1);
packet.sendPacket(receiver);
}
public void sendSpawnSlimePacket(Player receiver, NMSSlime slime) {
AbstractPacket packet = new WrapperPlayServerSpawnEntityLiving(slime.getBukkitEntityNMS());
packet.sendPacket(receiver);
}
public void sendItemMetadataPacket(Player receiver, NMSItem item) {
WrapperPlayServerEntityMetadata packet = new WrapperPlayServerEntityMetadata();
WrappedDataWatcher dataWatcher = new WrappedDataWatcher();
metadataHelper.setItemMetadata(dataWatcher, item.getRawItemStack());
packet.setEntityMetadata(dataWatcher.getWatchableObjects());
packet.setEntityID(item.getIdNMS());
packet.sendPacket(receiver);
}
public void sendVehicleAttachPacket(Player receiver, NMSEntityBase vehicle, NMSEntityBase passenger) {
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_9_R1)) {
WrapperPlayServerMount packet = new WrapperPlayServerMount();
packet.setVehicleId(vehicle.getIdNMS());
packet.setPassengers(new int[] {passenger.getIdNMS()});
packet.sendPacket(receiver);
} else {
WrapperPlayServerAttachEntity packet = new WrapperPlayServerAttachEntity();
packet.setVehicleId(vehicle.getIdNMS());
packet.setEntityId(passenger.getIdNMS());
packet.sendPacket(receiver);
}
}
public void sendDestroyEntitiesPacket(Player player, List<Integer> ids) {
WrapperPlayServerEntityDestroy packet = new WrapperPlayServerEntityDestroy();
packet.setEntities(ids);
packet.sendPacket(player);
}
}

View File

@ -17,8 +17,6 @@ package com.gmail.filoghost.holographicdisplays.bridge.protocollib.current;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
@ -32,28 +30,16 @@ import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketAdapter.AdapterParameteters;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject;
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
import com.gmail.filoghost.holographicdisplays.HolographicDisplays;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.ProtocolLibHook;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.AbstractPacket;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.EntityRelatedPacketWrapper;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.WrapperPlayServerAttachEntity;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.WrapperPlayServerEntityDestroy;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.WrapperPlayServerEntityMetadata;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.WrapperPlayServerMount;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.WrapperPlayServerSpawnEntity;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.WrapperPlayServerSpawnEntity.ObjectTypes;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.WrapperPlayServerSpawnEntityLiving;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.NMSManager;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem;
import com.gmail.filoghost.holographicdisplays.object.CraftHologram;
import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine;
import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine;
@ -61,7 +47,6 @@ import com.gmail.filoghost.holographicdisplays.object.line.CraftTextLine;
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine;
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchableLine;
import com.gmail.filoghost.holographicdisplays.placeholder.RelativePlaceholder;
import com.gmail.filoghost.holographicdisplays.util.NMSVersion;
/**
* This is for the ProtocolLib versions containing the WrappedDataWatcher.WrappedDataWatcherObject class.
@ -69,66 +54,26 @@ import com.gmail.filoghost.holographicdisplays.util.NMSVersion;
public class ProtocolLibHookImpl implements ProtocolLibHook {
private NMSManager nmsManager;
private Serializer
itemSerializer,
intSerializer,
byteSerializer,
stringSerializer,
booleanSerializer,
chatComponentSerializer;
private int itemstackMetadataWatcherIndex;
private int customNameWatcherIndex;
private int customNameVisibleWatcherIndex;
private int noGravityWatcherIndex;
private int armorStandStatusWatcherIndex;
private int entityStatusWatcherIndex;
private int airLevelWatcherIndex;
private PacketHelper packetHelper;
private MetadataHelper metadataHelper;
private boolean useGetEntityWorkaround;
@Override
public boolean hook(Plugin plugin, NMSManager nmsManager) {
public boolean hook(Plugin plugin, NMSManager nmsManager) {
this.nmsManager = nmsManager;
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_14_R1)) {
itemstackMetadataWatcherIndex = 7;
} else if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_10_R1)) {
itemstackMetadataWatcherIndex = 6;
} else if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_9_R1)) {
itemstackMetadataWatcherIndex = 5;
} else {
itemstackMetadataWatcherIndex = 10;
}
entityStatusWatcherIndex = 0;
airLevelWatcherIndex = 1;
customNameWatcherIndex = 2;
customNameVisibleWatcherIndex = 3;
noGravityWatcherIndex = 5;
armorStandStatusWatcherIndex = 11;
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_9_R1)) {
itemSerializer = Registry.get(MinecraftReflection.getItemStackClass());
intSerializer = Registry.get(Integer.class);
byteSerializer = Registry.get(Byte.class);
stringSerializer = Registry.get(String.class);
booleanSerializer = Registry.get(Boolean.class);
}
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_13_R1)) {
chatComponentSerializer = Registry.get(MinecraftReflection.getIChatBaseComponentClass(), true);
}
this.metadataHelper = new MetadataHelper();
this.packetHelper = new PacketHelper(metadataHelper);
AdapterParameteters params = PacketAdapter
.params()
.plugin(plugin)
.types( PacketType.Play.Server.SPAWN_ENTITY_LIVING,
PacketType.Play.Server.SPAWN_ENTITY,
PacketType.Play.Server.ENTITY_METADATA)
.serverSide()
.listenerPriority(ListenerPriority.NORMAL);
.params()
.plugin(plugin)
.types(
PacketType.Play.Server.SPAWN_ENTITY_LIVING,
PacketType.Play.Server.SPAWN_ENTITY,
PacketType.Play.Server.ENTITY_METADATA)
.serverSide()
.listenerPriority(ListenerPriority.NORMAL);
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(params) {
@ -163,7 +108,12 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
}
spawnEntityPacket = new WrapperPlayServerSpawnEntityLiving(packet.deepClone());
WrappedWatchableObject customNameWatchableObject = spawnEntityPacket.getMetadata().getWatchableObject(customNameWatcherIndex);
WrappedWatchableObject customNameWatchableObject = metadataHelper.getCustomNameWacthableObject(spawnEntityPacket.getMetadata());
if (customNameWatchableObject == null) {
return;
}
replaceRelativePlaceholders(customNameWatchableObject, player, hologramLine.getRelativePlaceholders());
event.setPacket(spawnEntityPacket.getHandle());
@ -202,19 +152,15 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
}
entityMetadataPacket = new WrapperPlayServerEntityMetadata(packet.deepClone());
List<WrappedWatchableObject> dataWatcherValues = entityMetadataPacket.getEntityMetadata();
WrappedWatchableObject customNameWatchableObject = metadataHelper.getCustomNameWatchableObject(entityMetadataPacket.getEntityMetadata());
for (int i = 0; i < dataWatcherValues.size(); i++) {
WrappedWatchableObject watchableObject = dataWatcherValues.get(i);
if (watchableObject.getIndex() == customNameWatcherIndex) {
if (replaceRelativePlaceholders(watchableObject, player, hologramLine.getRelativePlaceholders())) {
event.setPacket(entityMetadataPacket.getHandle());
}
// No reason to check further.
return;
}
if (customNameWatchableObject == null) {
return;
}
boolean modified = replaceRelativePlaceholders(customNameWatchableObject, player, hologramLine.getRelativePlaceholders());
if (modified) {
event.setPacket(entityMetadataPacket.getHandle());
}
}
}
@ -243,45 +189,20 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
return true;
}
Object customNameWatchableObjectValue = customNameWatchableObject.getValue();
String customName;
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_13_R1)) {
if (!(customNameWatchableObjectValue instanceof Optional)) {
return false;
}
Optional<?> customNameOptional = (Optional<?>) customNameWatchableObjectValue;
if (!customNameOptional.isPresent()) {
return false;
}
WrappedChatComponent componentWrapper = WrappedChatComponent.fromHandle(customNameOptional.get());
customName = componentWrapper.getJson();
} else {
if (!(customNameWatchableObjectValue instanceof String)) {
return false;
}
customName = (String) customNameWatchableObjectValue;
String customName = metadataHelper.getSerializedCustomName(customNameWatchableObject);
if (customName == null) {
return false;
}
for (RelativePlaceholder relativePlaceholder : relativePlaceholders) {
customName = customName.replace(relativePlaceholder.getTextPlaceholder(), relativePlaceholder.getReplacement(player));
}
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_13_R1)) {
customNameWatchableObject.setValue(Optional.of(WrappedChatComponent.fromJson(customName).getHandle()));
} else {
customNameWatchableObject.setValue(customName);
}
metadataHelper.setSerializedCustomName(customNameWatchableObject, customName);
return true;
}
@Override
public void sendDestroyEntitiesPacket(Player player, CraftHologram hologram) {
List<Integer> ids = new ArrayList<>();
@ -294,9 +215,7 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
}
if (!ids.isEmpty()) {
WrapperPlayServerEntityDestroy packet = new WrapperPlayServerEntityDestroy();
packet.setEntities(ids);
packet.sendPacket(player);
packetHelper.sendDestroyEntitiesPacket(player, ids);
}
}
@ -313,9 +232,7 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
}
if (!ids.isEmpty()) {
WrapperPlayServerEntityDestroy packet = new WrapperPlayServerEntityDestroy();
packet.setEntities(ids);
packet.sendPacket(player);
packetHelper.sendDestroyEntitiesPacket(player, ids);
}
}
@ -334,125 +251,42 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
return;
}
CraftTouchableLine touchableLine;
if (line instanceof CraftTextLine) {
CraftTextLine textLine = (CraftTextLine) line;
touchableLine = textLine;
if (textLine.isSpawned()) {
sendSpawnArmorStandPacket(player, (NMSArmorStand) textLine.getNmsNameable());
packetHelper.sendSpawnArmorStandPacket(player, (NMSArmorStand) textLine.getNmsNameable());
}
} else if (line instanceof CraftItemLine) {
CraftItemLine itemLine = (CraftItemLine) line;
touchableLine = itemLine;
if (itemLine.isSpawned()) {
sendSpawnItemPacket(player, itemLine.getNmsItem());
sendSpawnArmorStandPacket(player, (NMSArmorStand) itemLine.getNmsVehicle());
sendVehicleAttachPacket(player, itemLine.getNmsVehicle().getIdNMS(), itemLine.getNmsItem().getIdNMS());
sendItemMetadataPacket(player, itemLine.getNmsItem());
packetHelper.sendSpawnArmorStandPacket(player, (NMSArmorStand) itemLine.getNmsVehicle());
packetHelper.sendSpawnItemPacket(player, itemLine.getNmsItem());
packetHelper.sendVehicleAttachPacket(player, itemLine.getNmsVehicle(), itemLine.getNmsItem());
packetHelper.sendItemMetadataPacket(player, itemLine.getNmsItem());
}
} else {
throw new IllegalArgumentException("Unexpected hologram line type: " + line.getClass().getName());
}
// Unsafe cast, however both CraftTextLine and CraftItemLine are touchable.
CraftTouchableLine touchableLine = (CraftTouchableLine) line;
if (touchableLine.isSpawned() && touchableLine.getTouchSlime() != null) {
if (touchableLine != null && touchableLine.isSpawned() && touchableLine.getTouchSlime() != null) {
CraftTouchSlimeLine touchSlime = touchableLine.getTouchSlime();
if (touchSlime.isSpawned()) {
sendSpawnArmorStandPacket(player, (NMSArmorStand) touchSlime.getNmsVehicle());
AbstractPacket slimePacket = new WrapperPlayServerSpawnEntityLiving(touchSlime.getNmsSlime().getBukkitEntityNMS());
slimePacket.sendPacket(player);
sendVehicleAttachPacket(player, touchSlime.getNmsVehicle().getIdNMS(), touchSlime.getNmsSlime().getIdNMS());
packetHelper.sendSpawnArmorStandPacket(player, (NMSArmorStand) touchSlime.getNmsVehicle());
packetHelper.sendSpawnSlimePacket(player, touchSlime.getNmsSlime());
packetHelper.sendVehicleAttachPacket(player, touchSlime.getNmsVehicle(), touchSlime.getNmsSlime());
}
}
}
private void sendSpawnArmorStandPacket(Player receiver, NMSArmorStand armorStand) {
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_11_R1)) {
AbstractPacket spawnPacket;
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_14_R1)) {
spawnPacket = new WrapperPlayServerSpawnEntityLiving(armorStand.getBukkitEntityNMS());
} else {
spawnPacket = new WrapperPlayServerSpawnEntity(armorStand.getBukkitEntityNMS(), WrapperPlayServerSpawnEntity.ObjectTypes.ARMOR_STAND, 1);
}
spawnPacket.sendPacket(receiver);
WrapperPlayServerEntityMetadata dataPacket = new WrapperPlayServerEntityMetadata();
WrappedDataWatcher dataWatcher = new WrappedDataWatcher();
dataWatcher.setObject(new WrappedDataWatcherObject(entityStatusWatcherIndex, byteSerializer), (byte) 0x20); // Entity status: invisible
String customName = armorStand.getCustomNameNMS();
if (customName != null && !customName.isEmpty()) {
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_13_R1)) {
dataWatcher.setObject(new WrappedDataWatcherObject(customNameWatcherIndex, chatComponentSerializer), Optional.of(WrappedChatComponent.fromText(customName).getHandle()));
} else {
dataWatcher.setObject(new WrappedDataWatcherObject(customNameWatcherIndex, stringSerializer), customName);
}
dataWatcher.setObject(new WrappedDataWatcherObject(customNameVisibleWatcherIndex, booleanSerializer), true); // Custom name visible
}
dataWatcher.setObject(new WrappedDataWatcherObject(noGravityWatcherIndex, booleanSerializer), true); // No gravity
dataWatcher.setObject(new WrappedDataWatcherObject(armorStandStatusWatcherIndex, byteSerializer), (byte) (0x01 | 0x08 | 0x10)); // Armor stand data: small, no base plate, marker
dataPacket.setEntityMetadata(dataWatcher.getWatchableObjects());
dataPacket.setEntityID(armorStand.getIdNMS());
dataPacket.sendPacket(receiver);
} else {
WrapperPlayServerSpawnEntityLiving spawnPacket = new WrapperPlayServerSpawnEntityLiving(armorStand.getBukkitEntityNMS());
spawnPacket.sendPacket(receiver);
}
}
private void sendSpawnItemPacket(Player receiver, NMSItem item) {
AbstractPacket itemPacket = new WrapperPlayServerSpawnEntity(item.getBukkitEntityNMS(), ObjectTypes.ITEM_STACK, 1);
itemPacket.sendPacket(receiver);
}
private void sendItemMetadataPacket(Player receiver, NMSItem item) {
WrapperPlayServerEntityMetadata itemDataPacket = new WrapperPlayServerEntityMetadata();
WrappedDataWatcher dataWatcher = new WrappedDataWatcher();
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_9_R1)) {
Object itemStackObject = NMSVersion.isGreaterEqualThan(NMSVersion.v1_11_R1) ? item.getRawItemStack() : com.google.common.base.Optional.of(item.getRawItemStack());
dataWatcher.setObject(new WrappedDataWatcherObject(itemstackMetadataWatcherIndex, itemSerializer), itemStackObject);
dataWatcher.setObject(new WrappedDataWatcherObject(airLevelWatcherIndex, intSerializer), 300);
dataWatcher.setObject(new WrappedDataWatcherObject(entityStatusWatcherIndex, byteSerializer), (byte) 0);
} else {
dataWatcher.setObject(itemstackMetadataWatcherIndex, item.getRawItemStack());
dataWatcher.setObject(airLevelWatcherIndex, 300);
dataWatcher.setObject(entityStatusWatcherIndex, (byte) 0);
}
itemDataPacket.setEntityMetadata(dataWatcher.getWatchableObjects());
itemDataPacket.setEntityID(item.getIdNMS());
itemDataPacket.sendPacket(receiver);
}
private void sendVehicleAttachPacket(Player receiver, int vehicleId, int passengerId) {
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_9_R1)) {
WrapperPlayServerMount attachPacket = new WrapperPlayServerMount();
attachPacket.setVehicleId(vehicleId);
attachPacket.setPassengers(new int[] {passengerId});
attachPacket.sendPacket(receiver);
} else {
WrapperPlayServerAttachEntity attachPacket = new WrapperPlayServerAttachEntity();
attachPacket.setVehicleId(vehicleId);
attachPacket.setEntityId(passengerId);
attachPacket.sendPacket(receiver);
}
}
private CraftHologramLine getHologramLine(Entity bukkitEntity) {
if (bukkitEntity != null && isHologramType(bukkitEntity.getType())) {
NMSEntityBase entity = nmsManager.getNMSEntityBase(bukkitEntity);