Add NMS hologram line implementations

This commit is contained in:
Eric 2020-03-19 13:24:29 +01:00
parent 2d832e587a
commit 30de267f1e
23 changed files with 2081 additions and 21 deletions

View File

@ -12,7 +12,7 @@
<modules>
<module>interfaces</module>
<module>v8r1</module>
<!-- <module>v8r2</module>
<module>v8r2</module>
<module>v8r3</module>
<module>v9r1</module>
<module>v9r2</module>
@ -21,7 +21,7 @@
<module>v12r1</module>
<module>v13r1</module>
<module>v13r2</module>
<module>v14r1</module> -->
<module>v14r1</module>
<module>v15r1</module>
</modules>

34
nms/v10r1/pom.xml Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-v10r1</artifactId>
<version>1.13-SNAPSHOT</version>
<name>ShopChest NMS v1.10-R1</name>
<parent>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms</artifactId>
<version>1.13-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-interfaces</artifactId>
<version>1.13-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.10-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,182 @@
package de.epiceric.shopchest.shop.hologram;
import java.io.IOException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Optional;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import io.netty.buffer.Unpooled;
import net.minecraft.server.v1_10_R1.DataWatcher;
import net.minecraft.server.v1_10_R1.DataWatcherObject;
import net.minecraft.server.v1_10_R1.Entity;
import net.minecraft.server.v1_10_R1.EntityArmorStand;
import net.minecraft.server.v1_10_R1.IChatBaseComponent;
import net.minecraft.server.v1_10_R1.Packet;
import net.minecraft.server.v1_10_R1.PacketDataSerializer;
import net.minecraft.server.v1_10_R1.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_10_R1.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_10_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_10_R1.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_10_R1.PlayerConnection;
public class HologramLine implements IHologramLine {
private PacketPlayOutSpawnEntity spawnPacket;
private DataWatcher dataWatcher;
private DataWatcherObject<Boolean> nameVisible;
private DataWatcherObject<Optional<IChatBaseComponent>> customName;
private int id;
private Location location;
private String text;
public HologramLine(Location location, String text) {
this.id = 5;
this.location = location.clone();
this.text = text;
this.spawnPacket = new PacketPlayOutSpawnEntity();
this.dataWatcher = createDataWatcher();
updatePacket();
}
@Override
public void setLocation(Location location) {
this.location = location.clone();
updatePacket();
PacketPlayOutEntityTeleport packet = createTeleportPacket();
location.getWorld().getPlayers().forEach(player -> sendPackets(player, packet));
}
@Override
public void setText(String text) {
this.text = text;
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, text);
Packet<?> metadataPacket = new PacketPlayOutEntityMetadata(id, dataWatcher, true);
location.getWorld().getPlayers().forEach(player -> sendPackets(player, metadataPacket));
}
@Override
public void showPlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, spawnPacket, new PacketPlayOutEntityMetadata(id, dataWatcher, true));
}
@Override
public void hidePlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, new PacketPlayOutEntityDestroy(id));
}
@Override
public void destroy() {
location.getWorld().getPlayers().forEach(player -> hidePlayer(player));
}
private void sendPackets(Player player, Packet<?>... packets) {
PlayerConnection con = ((CraftPlayer) player).getHandle().playerConnection;
Arrays.stream(packets).forEach(packet -> con.sendPacket(packet));
}
private PacketPlayOutEntityTeleport createTeleportPacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY() + 1.975); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // yaw
s.writeByte(0); // pitch
s.writeBoolean(true); // on ground
try {
PacketPlayOutEntityTeleport packet = new PacketPlayOutEntityTeleport();
packet.a(s);
return packet;
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
return null;
}
private void updatePacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.a(UUID.randomUUID()); // uuid
s.writeByte(78); // type
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY() + 1.975); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // pitch
s.writeByte(0); // yaw
s.writeInt(0); // ?
s.writeShort(0); // mot x
s.writeShort(0); // mot y
s.writeShort(0); // mot z
try {
spawnPacket.a(s);
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
}
@SuppressWarnings("unchecked")
private DataWatcher createDataWatcher() {
try {
Field fEntityFlags = Entity.class.getDeclaredField("aa");
Field fAirTicks = Entity.class.getDeclaredField("az");
Field fNameVisible = Entity.class.getDeclaredField("aB");
Field fCustomName = Entity.class.getDeclaredField("aA");
Field fNoGravity = Entity.class.getDeclaredField("aD");
setAccessible(fEntityFlags, fAirTicks, fNameVisible, fCustomName, fNoGravity);
nameVisible = (DataWatcherObject<Boolean>) fNameVisible.get(null);
customName = (DataWatcherObject<Optional<IChatBaseComponent>>) fCustomName.get(null);
DataWatcherObject<Byte> entityFlags = (DataWatcherObject<Byte>) fEntityFlags.get(null);
DataWatcherObject<Integer> airTicks = (DataWatcherObject<Integer>) fAirTicks.get(null);
DataWatcherObject<Boolean> noGravity = (DataWatcherObject<Boolean>) fNoGravity.get(null);
DataWatcherObject<Byte> armorStandFlags = EntityArmorStand.a;
DataWatcher dataWatcher = new DataWatcher(null);
dataWatcher.register(entityFlags, (byte) 0b100000);
dataWatcher.register(airTicks, 300);
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, text);
dataWatcher.register(noGravity, true);
dataWatcher.register(armorStandFlags, (byte) 0b10000);
return dataWatcher;
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
return null;
}
private void setAccessible(AccessibleObject... args) {
Arrays.stream(args).forEach(arg -> arg.setAccessible(true));
}
}

34
nms/v11r1/pom.xml Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-v11r1</artifactId>
<version>1.13-SNAPSHOT</version>
<name>ShopChest NMS v1.11-R1</name>
<parent>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms</artifactId>
<version>1.13-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-interfaces</artifactId>
<version>1.13-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.11.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,182 @@
package de.epiceric.shopchest.shop.hologram;
import java.io.IOException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Optional;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import io.netty.buffer.Unpooled;
import net.minecraft.server.v1_11_R1.DataWatcher;
import net.minecraft.server.v1_11_R1.DataWatcherObject;
import net.minecraft.server.v1_11_R1.Entity;
import net.minecraft.server.v1_11_R1.EntityArmorStand;
import net.minecraft.server.v1_11_R1.IChatBaseComponent;
import net.minecraft.server.v1_11_R1.Packet;
import net.minecraft.server.v1_11_R1.PacketDataSerializer;
import net.minecraft.server.v1_11_R1.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_11_R1.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_11_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_11_R1.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_11_R1.PlayerConnection;
public class HologramLine implements IHologramLine {
private PacketPlayOutSpawnEntity spawnPacket;
private DataWatcher dataWatcher;
private DataWatcherObject<Boolean> nameVisible;
private DataWatcherObject<Optional<IChatBaseComponent>> customName;
private int id;
private Location location;
private String text;
public HologramLine(Location location, String text) {
this.id = 5;
this.location = location.clone();
this.text = text;
this.spawnPacket = new PacketPlayOutSpawnEntity();
this.dataWatcher = createDataWatcher();
updatePacket();
}
@Override
public void setLocation(Location location) {
this.location = location.clone();
updatePacket();
PacketPlayOutEntityTeleport packet = createTeleportPacket();
location.getWorld().getPlayers().forEach(player -> sendPackets(player, packet));
}
@Override
public void setText(String text) {
this.text = text;
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, text);
Packet<?> metadataPacket = new PacketPlayOutEntityMetadata(id, dataWatcher, true);
location.getWorld().getPlayers().forEach(player -> sendPackets(player, metadataPacket));
}
@Override
public void showPlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, spawnPacket, new PacketPlayOutEntityMetadata(id, dataWatcher, true));
}
@Override
public void hidePlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, new PacketPlayOutEntityDestroy(id));
}
@Override
public void destroy() {
location.getWorld().getPlayers().forEach(player -> hidePlayer(player));
}
private void sendPackets(Player player, Packet<?>... packets) {
PlayerConnection con = ((CraftPlayer) player).getHandle().playerConnection;
Arrays.stream(packets).forEach(packet -> con.sendPacket(packet));
}
private PacketPlayOutEntityTeleport createTeleportPacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY() + 1.975); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // yaw
s.writeByte(0); // pitch
s.writeBoolean(true); // on ground
try {
PacketPlayOutEntityTeleport packet = new PacketPlayOutEntityTeleport();
packet.a(s);
return packet;
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
return null;
}
private void updatePacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.a(UUID.randomUUID()); // uuid
s.writeByte(78); // type
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY() + 1.975); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // pitch
s.writeByte(0); // yaw
s.writeInt(0); // ?
s.writeShort(0); // mot x
s.writeShort(0); // mot y
s.writeShort(0); // mot z
try {
spawnPacket.a(s);
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
}
@SuppressWarnings("unchecked")
private DataWatcher createDataWatcher() {
try {
Field fEntityFlags = Entity.class.getDeclaredField("Z");
Field fAirTicks = Entity.class.getDeclaredField("az");
Field fNameVisible = Entity.class.getDeclaredField("aB");
Field fCustomName = Entity.class.getDeclaredField("aA");
Field fNoGravity = Entity.class.getDeclaredField("aD");
setAccessible(fEntityFlags, fAirTicks, fNameVisible, fCustomName, fNoGravity);
nameVisible = (DataWatcherObject<Boolean>) fNameVisible.get(null);
customName = (DataWatcherObject<Optional<IChatBaseComponent>>) fCustomName.get(null);
DataWatcherObject<Byte> entityFlags = (DataWatcherObject<Byte>) fEntityFlags.get(null);
DataWatcherObject<Integer> airTicks = (DataWatcherObject<Integer>) fAirTicks.get(null);
DataWatcherObject<Boolean> noGravity = (DataWatcherObject<Boolean>) fNoGravity.get(null);
DataWatcherObject<Byte> armorStandFlags = EntityArmorStand.a;
DataWatcher dataWatcher = new DataWatcher(null);
dataWatcher.register(entityFlags, (byte) 0b100000);
dataWatcher.register(airTicks, 300);
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, text);
dataWatcher.register(noGravity, true);
dataWatcher.register(armorStandFlags, (byte) 0b10000);
return dataWatcher;
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
return null;
}
private void setAccessible(AccessibleObject... args) {
Arrays.stream(args).forEach(arg -> arg.setAccessible(true));
}
}

34
nms/v12r1/pom.xml Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-v12r1</artifactId>
<version>1.13-SNAPSHOT</version>
<name>ShopChest NMS v1.12-R1</name>
<parent>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms</artifactId>
<version>1.13-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-interfaces</artifactId>
<version>1.13-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,182 @@
package de.epiceric.shopchest.shop.hologram;
import java.io.IOException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Optional;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import io.netty.buffer.Unpooled;
import net.minecraft.server.v1_12_R1.DataWatcher;
import net.minecraft.server.v1_12_R1.DataWatcherObject;
import net.minecraft.server.v1_12_R1.Entity;
import net.minecraft.server.v1_12_R1.EntityArmorStand;
import net.minecraft.server.v1_12_R1.IChatBaseComponent;
import net.minecraft.server.v1_12_R1.Packet;
import net.minecraft.server.v1_12_R1.PacketDataSerializer;
import net.minecraft.server.v1_12_R1.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_12_R1.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_12_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_12_R1.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_12_R1.PlayerConnection;
public class HologramLine implements IHologramLine {
private PacketPlayOutSpawnEntity spawnPacket;
private DataWatcher dataWatcher;
private DataWatcherObject<Boolean> nameVisible;
private DataWatcherObject<Optional<IChatBaseComponent>> customName;
private int id;
private Location location;
private String text;
public HologramLine(Location location, String text) {
this.id = 5;
this.location = location.clone();
this.text = text;
this.spawnPacket = new PacketPlayOutSpawnEntity();
this.dataWatcher = createDataWatcher();
updatePacket();
}
@Override
public void setLocation(Location location) {
this.location = location.clone();
updatePacket();
PacketPlayOutEntityTeleport packet = createTeleportPacket();
location.getWorld().getPlayers().forEach(player -> sendPackets(player, packet));
}
@Override
public void setText(String text) {
this.text = text;
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, text);
Packet<?> metadataPacket = new PacketPlayOutEntityMetadata(id, dataWatcher, true);
location.getWorld().getPlayers().forEach(player -> sendPackets(player, metadataPacket));
}
@Override
public void showPlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, spawnPacket, new PacketPlayOutEntityMetadata(id, dataWatcher, true));
}
@Override
public void hidePlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, new PacketPlayOutEntityDestroy(id));
}
@Override
public void destroy() {
location.getWorld().getPlayers().forEach(player -> hidePlayer(player));
}
private void sendPackets(Player player, Packet<?>... packets) {
PlayerConnection con = ((CraftPlayer) player).getHandle().playerConnection;
Arrays.stream(packets).forEach(packet -> con.sendPacket(packet));
}
private PacketPlayOutEntityTeleport createTeleportPacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY() + 1.975); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // yaw
s.writeByte(0); // pitch
s.writeBoolean(true); // on ground
try {
PacketPlayOutEntityTeleport packet = new PacketPlayOutEntityTeleport();
packet.a(s);
return packet;
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
return null;
}
private void updatePacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.a(UUID.randomUUID()); // uuid
s.writeByte(78); // type
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY() + 1.975); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // pitch
s.writeByte(0); // yaw
s.writeInt(0); // ?
s.writeShort(0); // mot x
s.writeShort(0); // mot y
s.writeShort(0); // mot z
try {
spawnPacket.a(s);
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
}
@SuppressWarnings("unchecked")
private DataWatcher createDataWatcher() {
try {
Field fEntityFlags = Entity.class.getDeclaredField("Z");
Field fAirTicks = Entity.class.getDeclaredField("aA");
Field fNameVisible = Entity.class.getDeclaredField("aC");
Field fCustomName = Entity.class.getDeclaredField("aB");
Field fNoGravity = Entity.class.getDeclaredField("aE");
setAccessible(fEntityFlags, fAirTicks, fNameVisible, fCustomName, fNoGravity);
nameVisible = (DataWatcherObject<Boolean>) fNameVisible.get(null);
customName = (DataWatcherObject<Optional<IChatBaseComponent>>) fCustomName.get(null);
DataWatcherObject<Byte> entityFlags = (DataWatcherObject<Byte>) fEntityFlags.get(null);
DataWatcherObject<Integer> airTicks = (DataWatcherObject<Integer>) fAirTicks.get(null);
DataWatcherObject<Boolean> noGravity = (DataWatcherObject<Boolean>) fNoGravity.get(null);
DataWatcherObject<Byte> armorStandFlags = EntityArmorStand.a;
DataWatcher dataWatcher = new DataWatcher(null);
dataWatcher.register(entityFlags, (byte) 0b100000);
dataWatcher.register(airTicks, 300);
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, text);
dataWatcher.register(noGravity, true);
dataWatcher.register(armorStandFlags, (byte) 0b10000);
return dataWatcher;
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
return null;
}
private void setAccessible(AccessibleObject... args) {
Arrays.stream(args).forEach(arg -> arg.setAccessible(true));
}
}

34
nms/v13r1/pom.xml Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-v13r1</artifactId>
<version>1.13-SNAPSHOT</version>
<name>ShopChest NMS v1.13-R1</name>
<parent>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms</artifactId>
<version>1.13-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-interfaces</artifactId>
<version>1.13-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.13-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,183 @@
package de.epiceric.shopchest.shop.hologram;
import java.io.IOException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Optional;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_13_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import io.netty.buffer.Unpooled;
import net.minecraft.server.v1_13_R1.DataWatcher;
import net.minecraft.server.v1_13_R1.DataWatcherObject;
import net.minecraft.server.v1_13_R1.Entity;
import net.minecraft.server.v1_13_R1.EntityArmorStand;
import net.minecraft.server.v1_13_R1.IChatBaseComponent;
import net.minecraft.server.v1_13_R1.Packet;
import net.minecraft.server.v1_13_R1.PacketDataSerializer;
import net.minecraft.server.v1_13_R1.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_13_R1.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_13_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_13_R1.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_13_R1.PlayerConnection;
import net.minecraft.server.v1_13_R1.IChatBaseComponent.ChatSerializer;
public class HologramLine implements IHologramLine {
private PacketPlayOutSpawnEntity spawnPacket;
private DataWatcher dataWatcher;
private DataWatcherObject<Boolean> nameVisible;
private DataWatcherObject<Optional<IChatBaseComponent>> customName;
private int id;
private Location location;
private String text;
public HologramLine(Location location, String text) {
this.id = 5;
this.location = location.clone();
this.text = text;
this.spawnPacket = new PacketPlayOutSpawnEntity();
this.dataWatcher = createDataWatcher();
updatePacket();
}
@Override
public void setLocation(Location location) {
this.location = location.clone();
updatePacket();
PacketPlayOutEntityTeleport packet = createTeleportPacket();
location.getWorld().getPlayers().forEach(player -> sendPackets(player, packet));
}
@Override
public void setText(String text) {
this.text = text;
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, Optional.ofNullable(ChatSerializer.b(text)));
Packet<?> metadataPacket = new PacketPlayOutEntityMetadata(id, dataWatcher, true);
location.getWorld().getPlayers().forEach(player -> sendPackets(player, metadataPacket));
}
@Override
public void showPlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, spawnPacket, new PacketPlayOutEntityMetadata(id, dataWatcher, true));
}
@Override
public void hidePlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, new PacketPlayOutEntityDestroy(id));
}
@Override
public void destroy() {
location.getWorld().getPlayers().forEach(player -> hidePlayer(player));
}
private void sendPackets(Player player, Packet<?>... packets) {
PlayerConnection con = ((CraftPlayer) player).getHandle().playerConnection;
Arrays.stream(packets).forEach(packet -> con.sendPacket(packet));
}
private PacketPlayOutEntityTeleport createTeleportPacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY() + 1.975); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // yaw
s.writeByte(0); // pitch
s.writeBoolean(true); // on ground
try {
PacketPlayOutEntityTeleport packet = new PacketPlayOutEntityTeleport();
packet.a(s);
return packet;
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
return null;
}
private void updatePacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.a(UUID.randomUUID()); // uuid
s.writeByte(78); // type
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY() + 1.975); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // pitch
s.writeByte(0); // yaw
s.writeInt(0); // ?
s.writeShort(0); // mot x
s.writeShort(0); // mot y
s.writeShort(0); // mot z
try {
spawnPacket.a(s);
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
}
@SuppressWarnings("unchecked")
private DataWatcher createDataWatcher() {
try {
Field fEntityFlags = Entity.class.getDeclaredField("ac");
Field fAirTicks = Entity.class.getDeclaredField("aD");
Field fNameVisible = Entity.class.getDeclaredField("aF");
Field fCustomName = Entity.class.getDeclaredField("aE");
Field fNoGravity = Entity.class.getDeclaredField("aH");
setAccessible(fEntityFlags, fAirTicks, fNameVisible, fCustomName, fNoGravity);
nameVisible = (DataWatcherObject<Boolean>) fNameVisible.get(null);
customName = (DataWatcherObject<Optional<IChatBaseComponent>>) fCustomName.get(null);
DataWatcherObject<Byte> entityFlags = (DataWatcherObject<Byte>) fEntityFlags.get(null);
DataWatcherObject<Integer> airTicks = (DataWatcherObject<Integer>) fAirTicks.get(null);
DataWatcherObject<Boolean> noGravity = (DataWatcherObject<Boolean>) fNoGravity.get(null);
DataWatcherObject<Byte> armorStandFlags = EntityArmorStand.a;
DataWatcher dataWatcher = new DataWatcher(null);
dataWatcher.register(entityFlags, (byte) 0b100000);
dataWatcher.register(airTicks, 300);
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, Optional.ofNullable(ChatSerializer.b(text))); // TODO: Json
dataWatcher.register(noGravity, true);
dataWatcher.register(armorStandFlags, (byte) 0b10000);
return dataWatcher;
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
return null;
}
private void setAccessible(AccessibleObject... args) {
Arrays.stream(args).forEach(arg -> arg.setAccessible(true));
}
}

34
nms/v13r2/pom.xml Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-v13r2</artifactId>
<version>1.13-SNAPSHOT</version>
<name>ShopChest NMS v1.13-R2</name>
<parent>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms</artifactId>
<version>1.13-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-interfaces</artifactId>
<version>1.13-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.13.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,183 @@
package de.epiceric.shopchest.shop.hologram;
import java.io.IOException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Optional;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
import io.netty.buffer.Unpooled;
import net.minecraft.server.v1_13_R2.DataWatcher;
import net.minecraft.server.v1_13_R2.DataWatcherObject;
import net.minecraft.server.v1_13_R2.Entity;
import net.minecraft.server.v1_13_R2.EntityArmorStand;
import net.minecraft.server.v1_13_R2.IChatBaseComponent;
import net.minecraft.server.v1_13_R2.Packet;
import net.minecraft.server.v1_13_R2.PacketDataSerializer;
import net.minecraft.server.v1_13_R2.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_13_R2.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_13_R2.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_13_R2.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_13_R2.PlayerConnection;
import net.minecraft.server.v1_13_R2.IChatBaseComponent.ChatSerializer;
public class HologramLine implements IHologramLine {
private PacketPlayOutSpawnEntity spawnPacket;
private DataWatcher dataWatcher;
private DataWatcherObject<Boolean> nameVisible;
private DataWatcherObject<Optional<IChatBaseComponent>> customName;
private int id;
private Location location;
private String text;
public HologramLine(Location location, String text) {
this.id = 5;
this.location = location.clone();
this.text = text;
this.spawnPacket = new PacketPlayOutSpawnEntity();
this.dataWatcher = createDataWatcher();
updatePacket();
}
@Override
public void setLocation(Location location) {
this.location = location.clone();
updatePacket();
PacketPlayOutEntityTeleport packet = createTeleportPacket();
location.getWorld().getPlayers().forEach(player -> sendPackets(player, packet));
}
@Override
public void setText(String text) {
this.text = text;
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, Optional.ofNullable(ChatSerializer.b(text)));
Packet<?> metadataPacket = new PacketPlayOutEntityMetadata(id, dataWatcher, true);
location.getWorld().getPlayers().forEach(player -> sendPackets(player, metadataPacket));
}
@Override
public void showPlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, spawnPacket, new PacketPlayOutEntityMetadata(id, dataWatcher, true));
}
@Override
public void hidePlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, new PacketPlayOutEntityDestroy(id));
}
@Override
public void destroy() {
location.getWorld().getPlayers().forEach(player -> hidePlayer(player));
}
private void sendPackets(Player player, Packet<?>... packets) {
PlayerConnection con = ((CraftPlayer) player).getHandle().playerConnection;
Arrays.stream(packets).forEach(packet -> con.sendPacket(packet));
}
private PacketPlayOutEntityTeleport createTeleportPacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY() + 1.975); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // yaw
s.writeByte(0); // pitch
s.writeBoolean(true); // on ground
try {
PacketPlayOutEntityTeleport packet = new PacketPlayOutEntityTeleport();
packet.a(s);
return packet;
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
return null;
}
private void updatePacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.a(UUID.randomUUID()); // uuid
s.writeByte(78); // type
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY() + 1.975); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // pitch
s.writeByte(0); // yaw
s.writeInt(0); // ?
s.writeShort(0); // mot x
s.writeShort(0); // mot y
s.writeShort(0); // mot z
try {
spawnPacket.a(s);
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
}
@SuppressWarnings("unchecked")
private DataWatcher createDataWatcher() {
try {
Field fEntityFlags = Entity.class.getDeclaredField("ac");
Field fAirTicks = Entity.class.getDeclaredField("aD");
Field fNameVisible = Entity.class.getDeclaredField("aF");
Field fCustomName = Entity.class.getDeclaredField("aE");
Field fNoGravity = Entity.class.getDeclaredField("aH");
setAccessible(fEntityFlags, fAirTicks, fNameVisible, fCustomName, fNoGravity);
nameVisible = (DataWatcherObject<Boolean>) fNameVisible.get(null);
customName = (DataWatcherObject<Optional<IChatBaseComponent>>) fCustomName.get(null);
DataWatcherObject<Byte> entityFlags = (DataWatcherObject<Byte>) fEntityFlags.get(null);
DataWatcherObject<Integer> airTicks = (DataWatcherObject<Integer>) fAirTicks.get(null);
DataWatcherObject<Boolean> noGravity = (DataWatcherObject<Boolean>) fNoGravity.get(null);
DataWatcherObject<Byte> armorStandFlags = EntityArmorStand.a;
DataWatcher dataWatcher = new DataWatcher(null);
dataWatcher.register(entityFlags, (byte) 0b100000);
dataWatcher.register(airTicks, 300);
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, Optional.ofNullable(ChatSerializer.b(text))); // TODO: Json
dataWatcher.register(noGravity, true);
dataWatcher.register(armorStandFlags, (byte) 0b10000);
return dataWatcher;
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
return null;
}
private void setAccessible(AccessibleObject... args) {
Arrays.stream(args).forEach(arg -> arg.setAccessible(true));
}
}

34
nms/v14r1/pom.xml Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-v14r1</artifactId>
<version>1.13-SNAPSHOT</version>
<name>ShopChest NMS v1.14-R1</name>
<parent>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms</artifactId>
<version>1.13-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-interfaces</artifactId>
<version>1.13-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.14.3-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,185 @@
package de.epiceric.shopchest.shop.hologram;
import java.io.IOException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Optional;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import io.netty.buffer.Unpooled;
import net.minecraft.server.v1_14_R1.DataWatcher;
import net.minecraft.server.v1_14_R1.DataWatcherObject;
import net.minecraft.server.v1_14_R1.Entity;
import net.minecraft.server.v1_14_R1.EntityArmorStand;
import net.minecraft.server.v1_14_R1.EntityTypes;
import net.minecraft.server.v1_14_R1.IChatBaseComponent;
import net.minecraft.server.v1_14_R1.IRegistry;
import net.minecraft.server.v1_14_R1.Packet;
import net.minecraft.server.v1_14_R1.PacketDataSerializer;
import net.minecraft.server.v1_14_R1.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_14_R1.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_14_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_14_R1.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_14_R1.PlayerConnection;
import net.minecraft.server.v1_14_R1.IChatBaseComponent.ChatSerializer;
public class HologramLine implements IHologramLine {
private PacketPlayOutSpawnEntity spawnPacket;
private DataWatcher dataWatcher;
private DataWatcherObject<Boolean> nameVisible;
private DataWatcherObject<Optional<IChatBaseComponent>> customName;
private int id;
private Location location;
private String text;
public HologramLine(Location location, String text) {
this.id = 5;
this.location = location.clone();
this.text = text;
this.spawnPacket = new PacketPlayOutSpawnEntity();
this.dataWatcher = createDataWatcher();
updatePacket();
}
@Override
public void setLocation(Location location) {
this.location = location.clone();
updatePacket();
PacketPlayOutEntityTeleport packet = createTeleportPacket();
location.getWorld().getPlayers().forEach(player -> sendPackets(player, packet));
}
@Override
public void setText(String text) {
this.text = text;
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, Optional.ofNullable(ChatSerializer.b(text)));
Packet<?> metadataPacket = new PacketPlayOutEntityMetadata(id, dataWatcher, true);
location.getWorld().getPlayers().forEach(player -> sendPackets(player, metadataPacket));
}
@Override
public void showPlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, spawnPacket, new PacketPlayOutEntityMetadata(id, dataWatcher, true));
}
@Override
public void hidePlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, new PacketPlayOutEntityDestroy(id));
}
@Override
public void destroy() {
location.getWorld().getPlayers().forEach(player -> hidePlayer(player));
}
private void sendPackets(Player player, Packet<?>... packets) {
PlayerConnection con = ((CraftPlayer) player).getHandle().playerConnection;
Arrays.stream(packets).forEach(packet -> con.sendPacket(packet));
}
private PacketPlayOutEntityTeleport createTeleportPacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY() + 1.975); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // yaw
s.writeByte(0); // pitch
s.writeBoolean(true); // on ground
try {
PacketPlayOutEntityTeleport packet = new PacketPlayOutEntityTeleport();
packet.a(s);
return packet;
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
return null;
}
private void updatePacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.a(UUID.randomUUID()); // uuid
s.d(IRegistry.ENTITY_TYPE.a(EntityTypes.ARMOR_STAND)); // type
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY()); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // pitch
s.writeByte(0); // yaw
s.writeInt(0); // ?
s.writeShort(0); // mot x
s.writeShort(0); // mot y
s.writeShort(0); // mot z
try {
spawnPacket.a(s);
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
}
@SuppressWarnings("unchecked")
private DataWatcher createDataWatcher() {
try {
Field fEntityFlags = Entity.class.getDeclaredField("W");
Field fAirTicks = Entity.class.getDeclaredField("AIR_TICKS");
Field fNameVisible = Entity.class.getDeclaredField("aA");
Field fCustomName = Entity.class.getDeclaredField("az");
Field fNoGravity = Entity.class.getDeclaredField("aC");
setAccessible(fEntityFlags, fAirTicks, fNameVisible, fCustomName, fNoGravity);
nameVisible = (DataWatcherObject<Boolean>) fNameVisible.get(null);
customName = (DataWatcherObject<Optional<IChatBaseComponent>>) fCustomName.get(null);
DataWatcherObject<Byte> entityFlags = (DataWatcherObject<Byte>) fEntityFlags.get(null);
DataWatcherObject<Integer> airTicks = (DataWatcherObject<Integer>) fAirTicks.get(null);
DataWatcherObject<Boolean> noGravity = (DataWatcherObject<Boolean>) fNoGravity.get(null);
DataWatcherObject<Byte> armorStandFlags = EntityArmorStand.b;
DataWatcher dataWatcher = new DataWatcher(null);
dataWatcher.register(entityFlags, (byte) 0b100000);
dataWatcher.register(airTicks, 300);
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, Optional.ofNullable(ChatSerializer.b(text)));
dataWatcher.register(noGravity, true);
dataWatcher.register(armorStandFlags, (byte) 0b10000);
return dataWatcher;
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
return null;
}
private void setAccessible(AccessibleObject... args) {
Arrays.stream(args).forEach(arg -> arg.setAccessible(true));
}
}

View File

@ -29,7 +29,7 @@ import net.minecraft.server.v1_15_R1.PlayerConnection;
import net.minecraft.server.v1_15_R1.IChatBaseComponent.ChatSerializer;
public class HologramLine implements IHologramLine {
private PacketPlayOutSpawnEntity packet;
private PacketPlayOutSpawnEntity spawnPacket;
private DataWatcher dataWatcher;
private DataWatcherObject<Boolean> nameVisible;
@ -44,7 +44,7 @@ public class HologramLine implements IHologramLine {
this.location = location.clone();
this.text = text;
this.packet = new PacketPlayOutSpawnEntity();
this.spawnPacket = new PacketPlayOutSpawnEntity();
this.dataWatcher = createDataWatcher();
updatePacket();
@ -55,7 +55,7 @@ public class HologramLine implements IHologramLine {
this.location = location.clone();
updatePacket();
PacketPlayOutEntityTeleport packet = new PacketPlayOutEntityTeleport();
PacketPlayOutEntityTeleport packet = createTeleportPacket();
location.getWorld().getPlayers().forEach(player -> sendPackets(player, packet));
}
@ -66,8 +66,8 @@ public class HologramLine implements IHologramLine {
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, Optional.ofNullable(ChatSerializer.b(text)));
location.getWorld().getPlayers()
.forEach(player -> sendPackets(player, new PacketPlayOutEntityMetadata(id, dataWatcher, true)));
Packet<?> metadataPacket = new PacketPlayOutEntityMetadata(id, dataWatcher, true);
location.getWorld().getPlayers().forEach(player -> sendPackets(player, metadataPacket));
}
@Override
@ -76,7 +76,7 @@ public class HologramLine implements IHologramLine {
return;
}
sendPackets(player, packet, new PacketPlayOutEntityMetadata(id, dataWatcher, true));
sendPackets(player, spawnPacket, new PacketPlayOutEntityMetadata(id, dataWatcher, true));
}
@Override
@ -98,7 +98,30 @@ public class HologramLine implements IHologramLine {
Arrays.stream(packets).forEach(packet -> con.sendPacket(packet));
}
public void updatePacket() {
private PacketPlayOutEntityTeleport createTeleportPacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY() + 1.975); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // yaw
s.writeByte(0); // pitch
s.writeBoolean(true); // on ground
try {
PacketPlayOutEntityTeleport packet = new PacketPlayOutEntityTeleport();
packet.a(s);
return packet;
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
return null;
}
private void updatePacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.a(UUID.randomUUID()); // uuid
@ -114,7 +137,7 @@ public class HologramLine implements IHologramLine {
s.writeShort(0); // mot z
try {
packet.a(s);
spawnPacket.a(s);
} catch (IOException e) {
e.printStackTrace();
} finally {
@ -123,7 +146,7 @@ public class HologramLine implements IHologramLine {
}
@SuppressWarnings("unchecked")
public DataWatcher createDataWatcher() {
private DataWatcher createDataWatcher() {
try {
Field fEntityFlags = Entity.class.getDeclaredField("T");
Field fAirTicks = Entity.class.getDeclaredField("AIR_TICKS");
@ -156,7 +179,7 @@ public class HologramLine implements IHologramLine {
return null;
}
void setAccessible(AccessibleObject... args) {
private void setAccessible(AccessibleObject... args) {
Arrays.stream(args).forEach(arg -> arg.setAccessible(true));
}
}

View File

@ -18,7 +18,7 @@ import net.minecraft.server.v1_8_R1.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_8_R1.PlayerConnection;
public class HologramLine implements IHologramLine {
private PacketPlayOutSpawnEntity packet;
private PacketPlayOutSpawnEntity spawnPacket;
private DataWatcher dataWatcher;
private int id;
@ -30,7 +30,7 @@ public class HologramLine implements IHologramLine {
this.location = location.clone();
this.text = text == null ? "" : text;
this.packet = new PacketPlayOutSpawnEntity();
this.spawnPacket = new PacketPlayOutSpawnEntity();
this.dataWatcher = createDataWatcher();
updatePacket();
@ -45,8 +45,8 @@ public class HologramLine implements IHologramLine {
int y = MathHelper.floor(location.getY() * 32d);
int z = MathHelper.floor(location.getZ() * 32d);
Packet packet = new PacketPlayOutEntityTeleport(id, x, y, z, (byte) 0, (byte) 0, true);
location.getWorld().getPlayers().forEach(player -> sendPackets(player, packet));
Packet teleportPacket = new PacketPlayOutEntityTeleport(id, x, y, z, (byte) 0, (byte) 0, true);
location.getWorld().getPlayers().forEach(player -> sendPackets(player, teleportPacket));
}
@Override
@ -56,8 +56,8 @@ public class HologramLine implements IHologramLine {
dataWatcher.a(2, this.text); // custom name
dataWatcher.a(3, (byte) (this.text.isEmpty() ? 0 : 1)); // name visible
location.getWorld().getPlayers()
.forEach(player -> sendPackets(player, new PacketPlayOutEntityMetadata(id, dataWatcher, true)));
Packet metadataPacket = new PacketPlayOutEntityMetadata(id, dataWatcher, true);
location.getWorld().getPlayers().forEach(player -> sendPackets(player, metadataPacket));
}
@Override
@ -66,7 +66,7 @@ public class HologramLine implements IHologramLine {
return;
}
sendPackets(player, packet, new PacketPlayOutEntityMetadata(id, dataWatcher, true));
sendPackets(player, spawnPacket, new PacketPlayOutEntityMetadata(id, dataWatcher, true));
}
@Override
@ -98,7 +98,7 @@ public class HologramLine implements IHologramLine {
serializer.writeByte(0); // pitch
serializer.writeByte(0); // yaw
serializer.writeInt(0); // has motion (?)
this.packet.a(serializer);
this.spawnPacket.a(serializer);
serializer.release();
}
@ -108,7 +108,7 @@ public class HologramLine implements IHologramLine {
dataWatcher.a(1, (short) 300); // air ticks
dataWatcher.a(2, text); // custom name
dataWatcher.a(3, (byte) (text.isEmpty() ? 0 : 1)); // name visible
dataWatcher.a(10, (byte) 0b1100); // armor stand flags
dataWatcher.a(10, (byte) 0); // armor stand flags
return dataWatcher;
}
}

34
nms/v8r2/pom.xml Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-v8r2</artifactId>
<version>1.13-SNAPSHOT</version>
<name>ShopChest NMS v1.8-R2</name>
<parent>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms</artifactId>
<version>1.13-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-interfaces</artifactId>
<version>1.13-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.8.3-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,121 @@
package de.epiceric.shopchest.shop.hologram;
import java.io.IOException;
import java.util.Arrays;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
import io.netty.buffer.Unpooled;
import net.minecraft.server.v1_8_R2.DataWatcher;
import net.minecraft.server.v1_8_R2.MathHelper;
import net.minecraft.server.v1_8_R2.Packet;
import net.minecraft.server.v1_8_R2.PacketDataSerializer;
import net.minecraft.server.v1_8_R2.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_8_R2.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_8_R2.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_8_R2.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_8_R2.PlayerConnection;
public class HologramLine implements IHologramLine {
private PacketPlayOutSpawnEntity spawnPacket;
private DataWatcher dataWatcher;
private int id;
private Location location;
private String text;
public HologramLine(Location location, String text) {
this.id = 5;
this.location = location.clone();
this.text = text == null ? "" : text;
this.spawnPacket = new PacketPlayOutSpawnEntity();
this.dataWatcher = createDataWatcher();
updatePacket();
}
@Override
public void setLocation(Location location) {
this.location = location.clone();
updatePacket();
int x = MathHelper.floor(location.getX() * 32d);
int y = MathHelper.floor((location.getY() + 1.975) * 32d);
int z = MathHelper.floor(location.getZ() * 32d);
Packet<?> teleportPacket = new PacketPlayOutEntityTeleport(id, x, y, z, (byte) 0, (byte) 0, true);
location.getWorld().getPlayers().forEach(player -> sendPackets(player, teleportPacket));
}
@Override
public void setText(String text) {
this.text = text == null ? "" : text;
dataWatcher.a(2, this.text); // custom name
dataWatcher.a(3, (byte) (this.text.isEmpty() ? 0 : 1)); // name visible
Packet<?> metadataPacket = new PacketPlayOutEntityMetadata(id, dataWatcher, true);
location.getWorld().getPlayers().forEach(player -> sendPackets(player, metadataPacket));
}
@Override
public void showPlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, spawnPacket, new PacketPlayOutEntityMetadata(id, dataWatcher, true));
}
@Override
public void hidePlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, new PacketPlayOutEntityDestroy(id));
}
@Override
public void destroy() {
location.getWorld().getPlayers().forEach(player -> hidePlayer(player));
}
private void sendPackets(Player player, Packet<?>... packets) {
PlayerConnection con = ((CraftPlayer) player).getHandle().playerConnection;
Arrays.stream(packets).forEach(packet -> con.sendPacket(packet));
}
private void updatePacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.b(id); // id
s.writeByte(78); // entity type
s.writeInt(MathHelper.floor(location.getX() * 32d)); // x
s.writeInt(MathHelper.floor((location.getY() + 1.975) * 32d)); // y
s.writeInt(MathHelper.floor(location.getZ() * 32d)); // z
s.writeByte(0); // pitch
s.writeByte(0); // yaw
s.writeInt(0); // has motion (?)
try {
spawnPacket.a(s);
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
}
private DataWatcher createDataWatcher() {
DataWatcher dataWatcher = new DataWatcher(null);
dataWatcher.a(0, 0b100000); // entity flags
dataWatcher.a(1, (short) 300); // air ticks
dataWatcher.a(2, text); // custom name
dataWatcher.a(3, (byte) (text.isEmpty() ? 0 : 1)); // name visible
dataWatcher.a(10, (byte) 0b10000); // armor stand flags
return dataWatcher;
}
}

34
nms/v8r3/pom.xml Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-v8r3</artifactId>
<version>1.13-SNAPSHOT</version>
<name>ShopChest NMS v1.8-R3</name>
<parent>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms</artifactId>
<version>1.13-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-interfaces</artifactId>
<version>1.13-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.8.8-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,121 @@
package de.epiceric.shopchest.shop.hologram;
import java.io.IOException;
import java.util.Arrays;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
import io.netty.buffer.Unpooled;
import net.minecraft.server.v1_8_R3.DataWatcher;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketDataSerializer;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_8_R3.PlayerConnection;
public class HologramLine implements IHologramLine {
private PacketPlayOutSpawnEntity spawnPacket;
private DataWatcher dataWatcher;
private int id;
private Location location;
private String text;
public HologramLine(Location location, String text) {
this.id = 5;
this.location = location.clone();
this.text = text == null ? "" : text;
this.spawnPacket = new PacketPlayOutSpawnEntity();
this.dataWatcher = createDataWatcher();
updatePacket();
}
@Override
public void setLocation(Location location) {
this.location = location.clone();
updatePacket();
int x = MathHelper.floor(location.getX() * 32d);
int y = MathHelper.floor((location.getY() + 1.975) * 32d);
int z = MathHelper.floor(location.getZ() * 32d);
Packet<?> teleportPacket = new PacketPlayOutEntityTeleport(id, x, y, z, (byte) 0, (byte) 0, true);
location.getWorld().getPlayers().forEach(player -> sendPackets(player, teleportPacket));
}
@Override
public void setText(String text) {
this.text = text == null ? "" : text;
dataWatcher.a(2, this.text); // custom name
dataWatcher.a(3, (byte) (this.text.isEmpty() ? 0 : 1)); // name visible
Packet<?> metadataPacket = new PacketPlayOutEntityMetadata(id, dataWatcher, true);
location.getWorld().getPlayers().forEach(player -> sendPackets(player, metadataPacket));
}
@Override
public void showPlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, spawnPacket, new PacketPlayOutEntityMetadata(id, dataWatcher, true));
}
@Override
public void hidePlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, new PacketPlayOutEntityDestroy(id));
}
@Override
public void destroy() {
location.getWorld().getPlayers().forEach(player -> hidePlayer(player));
}
private void sendPackets(Player player, Packet<?>... packets) {
PlayerConnection con = ((CraftPlayer) player).getHandle().playerConnection;
Arrays.stream(packets).forEach(packet -> con.sendPacket(packet));
}
private void updatePacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.b(id); // id
s.writeByte(78); // entity type
s.writeInt(MathHelper.floor(location.getX() * 32d)); // x
s.writeInt(MathHelper.floor((location.getY() + 1.975) * 32d)); // y
s.writeInt(MathHelper.floor(location.getZ() * 32d)); // z
s.writeByte(0); // pitch
s.writeByte(0); // yaw
s.writeInt(0); // has motion (?)
try {
spawnPacket.a(s);
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
}
private DataWatcher createDataWatcher() {
DataWatcher dataWatcher = new DataWatcher(null);
dataWatcher.a(0, 0b100000); // entity flags
dataWatcher.a(1, (short) 300); // air ticks
dataWatcher.a(2, text); // custom name
dataWatcher.a(3, (byte) (text.isEmpty() ? 0 : 1)); // name visible
dataWatcher.a(10, (byte) 0b10000); // armor stand flags
return dataWatcher;
}
}

34
nms/v9r1/pom.xml Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-v9r1</artifactId>
<version>1.13-SNAPSHOT</version>
<name>ShopChest NMS v1.9-R1</name>
<parent>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms</artifactId>
<version>1.13-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-interfaces</artifactId>
<version>1.13-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.9.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,179 @@
package de.epiceric.shopchest.shop.hologram;
import java.io.IOException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Optional;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_9_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import io.netty.buffer.Unpooled;
import net.minecraft.server.v1_9_R1.DataWatcher;
import net.minecraft.server.v1_9_R1.DataWatcherObject;
import net.minecraft.server.v1_9_R1.Entity;
import net.minecraft.server.v1_9_R1.EntityArmorStand;
import net.minecraft.server.v1_9_R1.IChatBaseComponent;
import net.minecraft.server.v1_9_R1.Packet;
import net.minecraft.server.v1_9_R1.PacketDataSerializer;
import net.minecraft.server.v1_9_R1.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_9_R1.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_9_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_9_R1.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_9_R1.PlayerConnection;
public class HologramLine implements IHologramLine {
private PacketPlayOutSpawnEntity spawnPacket;
private DataWatcher dataWatcher;
private DataWatcherObject<Boolean> nameVisible;
private DataWatcherObject<Optional<IChatBaseComponent>> customName;
private int id;
private Location location;
private String text;
public HologramLine(Location location, String text) {
this.id = 5;
this.location = location.clone();
this.text = text;
this.spawnPacket = new PacketPlayOutSpawnEntity();
this.dataWatcher = createDataWatcher();
updatePacket();
}
@Override
public void setLocation(Location location) {
this.location = location.clone();
updatePacket();
PacketPlayOutEntityTeleport packet = createTeleportPacket();
location.getWorld().getPlayers().forEach(player -> sendPackets(player, packet));
}
@Override
public void setText(String text) {
this.text = text;
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, text);
Packet<?> metadataPacket = new PacketPlayOutEntityMetadata(id, dataWatcher, true);
location.getWorld().getPlayers().forEach(player -> sendPackets(player, metadataPacket));
}
@Override
public void showPlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, spawnPacket, new PacketPlayOutEntityMetadata(id, dataWatcher, true));
}
@Override
public void hidePlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, new PacketPlayOutEntityDestroy(id));
}
@Override
public void destroy() {
location.getWorld().getPlayers().forEach(player -> hidePlayer(player));
}
private void sendPackets(Player player, Packet<?>... packets) {
PlayerConnection con = ((CraftPlayer) player).getHandle().playerConnection;
Arrays.stream(packets).forEach(packet -> con.sendPacket(packet));
}
private PacketPlayOutEntityTeleport createTeleportPacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY() + 1.975); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // yaw
s.writeByte(0); // pitch
s.writeBoolean(true); // on ground
try {
PacketPlayOutEntityTeleport packet = new PacketPlayOutEntityTeleport();
packet.a(s);
return packet;
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
return null;
}
private void updatePacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.a(UUID.randomUUID()); // uuid
s.writeByte(78); // type
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY() + 1.975); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // pitch
s.writeByte(0); // yaw
s.writeInt(0); // ?
s.writeShort(0); // mot x
s.writeShort(0); // mot y
s.writeShort(0); // mot z
try {
spawnPacket.a(s);
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
}
@SuppressWarnings("unchecked")
private DataWatcher createDataWatcher() {
try {
Field fEntityFlags = Entity.class.getDeclaredField("ax");
Field fAirTicks = Entity.class.getDeclaredField("ay");
Field fNameVisible = Entity.class.getDeclaredField("aA");
Field fCustomName = Entity.class.getDeclaredField("az");
setAccessible(fEntityFlags, fAirTicks, fNameVisible, fCustomName);
nameVisible = (DataWatcherObject<Boolean>) fNameVisible.get(null);
customName = (DataWatcherObject<Optional<IChatBaseComponent>>) fCustomName.get(null);
DataWatcherObject<Byte> entityFlags = (DataWatcherObject<Byte>) fEntityFlags.get(null);
DataWatcherObject<Integer> airTicks = (DataWatcherObject<Integer>) fAirTicks.get(null);
DataWatcherObject<Byte> armorStandFlags = EntityArmorStand.a;
DataWatcher dataWatcher = new DataWatcher(null);
dataWatcher.register(entityFlags, (byte) 0b100000);
dataWatcher.register(airTicks, 300);
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, text);
dataWatcher.register(armorStandFlags, (byte) 0b10000);
return dataWatcher;
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
return null;
}
private void setAccessible(AccessibleObject... args) {
Arrays.stream(args).forEach(arg -> arg.setAccessible(true));
}
}

34
nms/v9r2/pom.xml Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-v9r2</artifactId>
<version>1.13-SNAPSHOT</version>
<name>ShopChest NMS v1.9-R2</name>
<parent>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms</artifactId>
<version>1.13-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>de.epiceric.shopchest</groupId>
<artifactId>shopchest-nms-interfaces</artifactId>
<version>1.13-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.9.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,179 @@
package de.epiceric.shopchest.shop.hologram;
import java.io.IOException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Optional;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_9_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
import io.netty.buffer.Unpooled;
import net.minecraft.server.v1_9_R2.DataWatcher;
import net.minecraft.server.v1_9_R2.DataWatcherObject;
import net.minecraft.server.v1_9_R2.Entity;
import net.minecraft.server.v1_9_R2.EntityArmorStand;
import net.minecraft.server.v1_9_R2.IChatBaseComponent;
import net.minecraft.server.v1_9_R2.Packet;
import net.minecraft.server.v1_9_R2.PacketDataSerializer;
import net.minecraft.server.v1_9_R2.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_9_R2.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_9_R2.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_9_R2.PacketPlayOutSpawnEntity;
import net.minecraft.server.v1_9_R2.PlayerConnection;
public class HologramLine implements IHologramLine {
private PacketPlayOutSpawnEntity spawnPacket;
private DataWatcher dataWatcher;
private DataWatcherObject<Boolean> nameVisible;
private DataWatcherObject<Optional<IChatBaseComponent>> customName;
private int id;
private Location location;
private String text;
public HologramLine(Location location, String text) {
this.id = 5;
this.location = location.clone();
this.text = text;
this.spawnPacket = new PacketPlayOutSpawnEntity();
this.dataWatcher = createDataWatcher();
updatePacket();
}
@Override
public void setLocation(Location location) {
this.location = location.clone();
updatePacket();
PacketPlayOutEntityTeleport packet = createTeleportPacket();
location.getWorld().getPlayers().forEach(player -> sendPackets(player, packet));
}
@Override
public void setText(String text) {
this.text = text;
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, text);
Packet<?> metadataPacket = new PacketPlayOutEntityMetadata(id, dataWatcher, true);
location.getWorld().getPlayers().forEach(player -> sendPackets(player, metadataPacket));
}
@Override
public void showPlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, spawnPacket, new PacketPlayOutEntityMetadata(id, dataWatcher, true));
}
@Override
public void hidePlayer(Player player) {
if (player == null || !player.isOnline()) {
return;
}
sendPackets(player, new PacketPlayOutEntityDestroy(id));
}
@Override
public void destroy() {
location.getWorld().getPlayers().forEach(player -> hidePlayer(player));
}
private void sendPackets(Player player, Packet<?>... packets) {
PlayerConnection con = ((CraftPlayer) player).getHandle().playerConnection;
Arrays.stream(packets).forEach(packet -> con.sendPacket(packet));
}
private PacketPlayOutEntityTeleport createTeleportPacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY() + 1.975); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // yaw
s.writeByte(0); // pitch
s.writeBoolean(true); // on ground
try {
PacketPlayOutEntityTeleport packet = new PacketPlayOutEntityTeleport();
packet.a(s);
return packet;
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
return null;
}
private void updatePacket() {
PacketDataSerializer s = new PacketDataSerializer(Unpooled.buffer());
s.d(id); // id
s.a(UUID.randomUUID()); // uuid
s.writeByte(78); // type
s.writeDouble(location.getX()); // x
s.writeDouble(location.getY() + 1.975); // y
s.writeDouble(location.getZ()); // z
s.writeByte(0); // pitch
s.writeByte(0); // yaw
s.writeInt(0); // ?
s.writeShort(0); // mot x
s.writeShort(0); // mot y
s.writeShort(0); // mot z
try {
spawnPacket.a(s);
} catch (IOException e) {
e.printStackTrace();
} finally {
s.release();
}
}
@SuppressWarnings("unchecked")
private DataWatcher createDataWatcher() {
try {
Field fEntityFlags = Entity.class.getDeclaredField("ay");
Field fAirTicks = Entity.class.getDeclaredField("az");
Field fNameVisible = Entity.class.getDeclaredField("aB");
Field fCustomName = Entity.class.getDeclaredField("aA");
setAccessible(fEntityFlags, fAirTicks, fNameVisible, fCustomName);
nameVisible = (DataWatcherObject<Boolean>) fNameVisible.get(null);
customName = (DataWatcherObject<Optional<IChatBaseComponent>>) fCustomName.get(null);
DataWatcherObject<Byte> entityFlags = (DataWatcherObject<Byte>) fEntityFlags.get(null);
DataWatcherObject<Integer> airTicks = (DataWatcherObject<Integer>) fAirTicks.get(null);
DataWatcherObject<Byte> armorStandFlags = EntityArmorStand.a;
DataWatcher dataWatcher = new DataWatcher(null);
dataWatcher.register(entityFlags, (byte) 0b100000);
dataWatcher.register(airTicks, 300);
dataWatcher.register(nameVisible, !text.isEmpty());
dataWatcher.register(customName, text);
dataWatcher.register(armorStandFlags, (byte) 0b10000);
return dataWatcher;
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
return null;
}
private void setAccessible(AccessibleObject... args) {
Arrays.stream(args).forEach(arg -> arg.setAccessible(true));
}
}