TabooLib/src/main/scala/io/izzel/taboolib/module/nms/NMSImpl.java

732 lines
38 KiB
Java
Raw Normal View History

package io.izzel.taboolib.module.nms;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import io.izzel.taboolib.Version;
2020-04-02 10:18:50 +00:00
import io.izzel.taboolib.module.nms.impl.Type;
import io.izzel.taboolib.module.lite.SimpleReflection;
2020-04-02 10:18:50 +00:00
import io.izzel.taboolib.module.locale.logger.TLogger;
import io.izzel.taboolib.module.nms.nbt.NBTList;
import io.izzel.taboolib.module.nms.nbt.*;
import io.izzel.taboolib.module.packet.TPacketHandler;
2020-02-02 06:55:20 +00:00
import io.izzel.taboolib.util.Ref;
import net.minecraft.server.v1_12_R1.ChatMessageType;
2019-05-22 00:41:34 +00:00
import net.minecraft.server.v1_12_R1.EntityVillager;
2019-01-20 08:45:02 +00:00
import net.minecraft.server.v1_12_R1.MinecraftServer;
2019-05-22 00:41:34 +00:00
import net.minecraft.server.v1_12_R1.NBTTagCompound;
2019-08-18 08:58:05 +00:00
import net.minecraft.server.v1_13_R2.EnumHand;
2019-05-22 00:41:34 +00:00
import net.minecraft.server.v1_13_R2.IRegistry;
2020-04-02 10:18:50 +00:00
import net.minecraft.server.v1_14_R1.*;
import net.minecraft.server.v1_15_R1.LightEngineThreaded;
import net.minecraft.server.v1_8_R3.ChatComponentText;
import net.minecraft.server.v1_8_R3.GenericAttributes;
import net.minecraft.server.v1_8_R3.NBTTagByte;
import net.minecraft.server.v1_8_R3.NBTTagByteArray;
import net.minecraft.server.v1_8_R3.NBTTagDouble;
import net.minecraft.server.v1_8_R3.NBTTagFloat;
import net.minecraft.server.v1_8_R3.NBTTagInt;
import net.minecraft.server.v1_8_R3.NBTTagIntArray;
import net.minecraft.server.v1_8_R3.NBTTagList;
import net.minecraft.server.v1_8_R3.NBTTagLong;
import net.minecraft.server.v1_8_R3.NBTTagShort;
import net.minecraft.server.v1_8_R3.NBTTagString;
import net.minecraft.server.v1_8_R3.PacketPlayOutChat;
import net.minecraft.server.v1_8_R3.PacketPlayOutTitle;
import org.bukkit.Chunk;
import org.bukkit.Particle;
2020-01-14 14:35:46 +00:00
import org.bukkit.World;
2020-04-02 10:18:50 +00:00
import org.bukkit.*;
2020-01-14 14:35:46 +00:00
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_12_R1.CraftParticle;
import org.bukkit.craftbukkit.v1_13_R2.CraftServer;
2020-01-14 14:35:46 +00:00
import org.bukkit.craftbukkit.v1_13_R2.CraftWorld;
2019-08-18 08:58:05 +00:00
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer;
2019-05-22 00:41:34 +00:00
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftVillager;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
2019-05-22 00:41:34 +00:00
import org.bukkit.entity.Villager;
2020-03-10 15:48:48 +00:00
import org.bukkit.event.entity.CreatureSpawnEvent;
2020-02-13 08:46:26 +00:00
import org.bukkit.event.entity.ProjectileHitEvent;
2019-05-22 00:41:34 +00:00
import org.bukkit.inventory.meta.PotionMeta;
2020-02-13 08:46:26 +00:00
import org.bukkit.util.Vector;
2019-05-22 00:41:34 +00:00
import java.lang.reflect.Field;
2019-05-24 16:08:37 +00:00
import java.util.List;
2019-06-13 15:42:47 +00:00
import java.util.Map;
import java.util.UUID;
2020-04-02 10:18:50 +00:00
import java.util.concurrent.atomic.AtomicInteger;
2020-03-10 15:48:48 +00:00
import java.util.function.Consumer;
/**
* @Author
* @Since 2018-11-09 14:42
*/
public class NMSImpl extends NMS {
2019-05-22 00:41:34 +00:00
private Field entityTypesField;
2020-05-17 13:48:41 +00:00
private final boolean is11300 = Version.isAfter(Version.v1_13);
2020-05-05 17:39:21 +00:00
private final boolean is11400 = Version.isAfter(Version.v1_14);
private final boolean is11500 = Version.isAfter(Version.v1_15);
2019-05-22 00:41:34 +00:00
2019-05-24 16:08:37 +00:00
static {
SimpleReflection.saveField(NBTTagString.class);
SimpleReflection.saveField(NBTTagDouble.class);
SimpleReflection.saveField(NBTTagInt.class);
SimpleReflection.saveField(NBTTagFloat.class);
SimpleReflection.saveField(NBTTagShort.class);
SimpleReflection.saveField(NBTTagLong.class);
SimpleReflection.saveField(NBTTagByte.class);
SimpleReflection.saveField(NBTTagIntArray.class);
SimpleReflection.saveField(NBTTagByteArray.class);
SimpleReflection.saveField(NBTTagList.class);
2019-06-13 15:42:47 +00:00
SimpleReflection.saveField(NBTTagCompound.class);
2019-05-24 16:08:37 +00:00
}
public NMSImpl() {
if (Version.isAfter(Version.v1_13)) {
SimpleReflection.saveField(net.minecraft.server.v1_12_R1.Entity.class);
for (Field declaredField : SimpleReflection.getFields(net.minecraft.server.v1_12_R1.Entity.class).values()) {
2019-05-22 00:41:34 +00:00
if (declaredField.getType().getSimpleName().equals("EntityTypes")) {
entityTypesField = declaredField;
break;
}
}
}
SimpleReflection.saveField(MinecraftServer.class);
}
2019-08-18 08:58:05 +00:00
@Override
2020-04-02 10:18:50 +00:00
public void openBook(Player player, org.bukkit.inventory.ItemStack book) {
2019-08-18 08:58:05 +00:00
// 你妈 1.14.3 的 a() 到 1.14.4 的 openBook() 不改 nms 版本号?都是 1_14_R1神经病吧
Object bookItem = org.bukkit.craftbukkit.v1_13_R2.inventory.CraftItemStack.asNMSCopy(book);
try {
((CraftPlayer) player).getHandle().a((net.minecraft.server.v1_13_R2.ItemStack) bookItem, EnumHand.MAIN_HAND);
} catch (Throwable ignored) {
try {
((org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer) player).getHandle().openBook((net.minecraft.server.v1_14_R1.ItemStack) bookItem, net.minecraft.server.v1_14_R1.EnumHand.MAIN_HAND);
} catch (Throwable ignored2) {
}
}
}
@Override
public boolean isRunning() {
return !SimpleReflection.getFieldValue(MinecraftServer.class, ((CraftServer) Bukkit.getServer()).getServer(), "hasStopped", false);
}
@Override
public Object toPacketPlayOutWorldParticles(Particle var1, boolean var2, float var3, float var4, float var5, float var6, float var7, float var8, float var9, int var10, Object var11) {
2020-05-17 13:48:41 +00:00
if (is11300) {
return new net.minecraft.server.v1_13_R2.PacketPlayOutWorldParticles(org.bukkit.craftbukkit.v1_13_R2.CraftParticle.toNMS(var1, var11), var2, var3, var4, var5, var6, var7, var8, var9, var10);
} else {
return new net.minecraft.server.v1_12_R1.PacketPlayOutWorldParticles(CraftParticle.toNMS(var1), var2, var3, var4, var5, var6, var7, var8, var9, var10, CraftParticle.toData(var1, var11));
}
2019-05-22 00:41:34 +00:00
}
2019-05-24 16:08:37 +00:00
@Override
public double[] getTPS() {
return MinecraftServer.getServer().recentTps;
}
2019-05-22 00:41:34 +00:00
@Override
2020-04-02 10:18:50 +00:00
public String getName(org.bukkit.inventory.ItemStack itemStack) {
2019-05-22 00:41:34 +00:00
Object nmsItem = CraftItemStack.asNMSCopy(itemStack);
if (Version.isAfter(Version.v1_13)) {
2019-05-22 00:41:34 +00:00
String name = ((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).getItem().getName();
if (itemStack.getItemMeta() instanceof PotionMeta) {
name += ".effect." + ((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).getTag().getString("Potion").replaceAll("minecraft:(strong_|long_)?", "");
}
return name;
} else if (Version.isAfter(Version.v1_11)) {
2019-05-22 00:41:34 +00:00
String name = ((net.minecraft.server.v1_12_R1.ItemStack) nmsItem).getItem().a((net.minecraft.server.v1_12_R1.ItemStack) nmsItem);
if (itemStack.getItemMeta() instanceof PotionMeta) {
2019-06-24 08:59:45 +00:00
return name.replace("item.", "") + ".effect." + ((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).getTag().getString("Potion").replaceAll("(minecraft:)?(strong_|long_)?", "");
}
return name + ".name";
} else {
String name = ((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).getItem().getName();
if (itemStack.getItemMeta() instanceof PotionMeta) {
return name.replace("item.", "") + ".effect." + ((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).getTag().getString("Potion").replaceAll("(minecraft:)?(strong_|long_)?", "");
2019-05-22 00:41:34 +00:00
}
return name + ".name";
}
}
@Override
public String getName(Entity entity) {
if (Version.isAfter(Version.v1_14)) {
2019-07-11 08:20:35 +00:00
Object minecraftKey = net.minecraft.server.v1_14_R1.EntityTypes.getName(((org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity) entity).getHandle().getEntityType());
return "entity.minecraft." + ((net.minecraft.server.v1_14_R1.MinecraftKey) minecraftKey).getKey();
} else if (Version.isAfter(Version.v1_13)) {
2019-06-24 13:53:36 +00:00
try {
2020-02-02 06:55:20 +00:00
String name = "entity.minecraft." + IRegistry.ENTITY_TYPE.getKey((net.minecraft.server.v1_13_R2.EntityTypes<?>) Ref.getField(((org.bukkit.craftbukkit.v1_13_R2.entity.CraftEntity) entity).getHandle(), entityTypesField)).getKey();
2019-06-24 13:53:36 +00:00
if (entity instanceof Villager && ((CraftVillager) entity).getCareer() != null) {
name += "." + String.valueOf(((CraftVillager) entity).getCareer()).toLowerCase();
}
return name;
} catch (Throwable t) {
t.printStackTrace();
}
return "entity.null";
} else {
2019-05-22 00:41:34 +00:00
try {
if (entity instanceof Player) {
return "entity.Player.name";
}
if (entity instanceof Villager) {
String name = "name";
Object villager = ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftVillager) entity).getHandle();
Object export = new NBTTagCompound();
((EntityVillager) villager).b((NBTTagCompound) export);
int career = ((NBTTagCompound) export).getInt("Career");
switch (((EntityVillager) villager).getProfession()) {
case 0:
if (career == 1) {
name = "farmer";
} else if (career == 2) {
name = "fisherman";
} else if (career == 3) {
name = "shepherd";
} else if (career == 4) {
name = "fletcher";
}
break;
case 1:
if (career == 1) {
name = "librarian";
} else if (career == 2) {
name = "cartographer";
}
break;
case 2:
name = "cleric";
break;
case 3:
if (career == 1) {
name = "armor";
} else if (career == 2) {
name = "weapon";
} else if (career == 3) {
name = "tool";
}
break;
case 4:
if (career == 1) {
name = "butcher";
} else if (career == 2) {
name = "leather";
}
break;
case 5:
name = "nitwit";
break;
}
return "entity.Villager." + name;
}
return "entity." + entity.getType().getEntityClass().getSimpleName() + ".name";
2020-01-23 10:14:06 +00:00
} catch (Throwable ignore) {
2019-05-22 00:41:34 +00:00
}
return "entity.null";
}
}
@Override
public void sendTitle(Player player, String title, int titleFadein, int titleStay, int titleFadeout, String subtitle, int subtitleFadein, int subtitleStay, int subtitleFadeout) {
2019-02-10 07:05:03 +00:00
TPacketHandler.sendPacket(player, new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.TIMES, new ChatComponentText(String.valueOf(title)), titleFadein, titleStay, titleFadeout));
TPacketHandler.sendPacket(player, new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.TITLE, new ChatComponentText(String.valueOf(title)), titleFadein, titleStay, titleFadeout));
TPacketHandler.sendPacket(player, new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.TIMES, new ChatComponentText(String.valueOf(subtitle)), subtitleFadein, subtitleStay, subtitleFadeout));
TPacketHandler.sendPacket(player, new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.SUBTITLE, new ChatComponentText(String.valueOf(subtitle)), subtitleFadein, subtitleStay, subtitleFadeout));
}
@Override
public void sendActionBar(Player player, String text) {
if (Version.isAfter(Version.v1_12)) {
TPacketHandler.sendPacket(player, new net.minecraft.server.v1_12_R1.PacketPlayOutChat(new net.minecraft.server.v1_12_R1.ChatComponentText(String.valueOf(text)), ChatMessageType.GAME_INFO));
} else {
TPacketHandler.sendPacket(player, new PacketPlayOutChat(new ChatComponentText(String.valueOf(text)), (byte) 2));
}
}
2019-01-20 08:45:02 +00:00
@Override
2020-04-02 10:18:50 +00:00
public org.bukkit.inventory.ItemStack _NBT(org.bukkit.inventory.ItemStack itemStack, Object compound) {
2019-05-24 16:08:37 +00:00
Object nmsItem = CraftItemStack.asNMSCopy(itemStack);
try {
((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).setTag((net.minecraft.server.v1_8_R3.NBTTagCompound) toNBTBase((io.izzel.taboolib.module.nms.nbt.NBTBase) compound));
2019-05-24 16:08:37 +00:00
} catch (Throwable t) {
t.printStackTrace();
}
2019-06-28 07:17:35 +00:00
return CraftItemStack.asBukkitCopy((net.minecraft.server.v1_8_R3.ItemStack) nmsItem);
2019-05-24 16:08:37 +00:00
}
@Override
2020-04-02 10:18:50 +00:00
public Object _NBT(org.bukkit.inventory.ItemStack itemStack) {
2019-05-24 16:08:37 +00:00
Object nmsItem = CraftItemStack.asNMSCopy(itemStack);
try {
return ((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).hasTag() ? fromNBTBase(((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).getTag()) : new NBTCompound();
} catch (Throwable t) {
t.printStackTrace();
}
return new NBTCompound();
}
@Override
2020-04-02 10:18:50 +00:00
public List<NBTAttribute> getBaseAttribute(org.bukkit.inventory.ItemStack item) {
List<NBTAttribute> list = Lists.newArrayList();
Object nmsItem = CraftItemStack.asNMSCopy(item);
Object attr;
if (Version.isAfter(Version.v1_9)) {
attr = ((net.minecraft.server.v1_12_R1.ItemStack) nmsItem).getItem().a(net.minecraft.server.v1_12_R1.EnumItemSlot.MAINHAND);
} else {
attr = ((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).getItem().i();
}
2020-03-08 08:31:34 +00:00
((Multimap) attr).asMap().forEach((k, v) -> {
Object nbt = net.minecraft.server.v1_12_R1.GenericAttributes.a((net.minecraft.server.v1_12_R1.AttributeModifier) v);
list.add(new NBTAttribute(
new UUID(((NBTTagCompound) nbt).getLong("UUIDMost"), ((NBTTagCompound) nbt).getLong("UUIDLeast")),
String.valueOf(k),
((NBTTagCompound) nbt).getString("Name"),
((NBTTagCompound) nbt).getDouble("Amount"),
NBTOperation.fromIndex(((NBTTagCompound) nbt).getInt("Operation"))
));
});
return list;
}
@Override
public Object toNMS(Attribute attribute) {
SimpleReflection.checkAndSave(GenericAttributes.class);
return SimpleReflection.getFieldValue(GenericAttributes.class, null, attribute.name());
}
2020-01-14 14:35:46 +00:00
@Override
public Entity getEntityById(int id) {
for (World world : Bukkit.getServer().getWorlds()) {
net.minecraft.server.v1_13_R2.Entity entity = ((CraftWorld) world).getHandle().getEntity(id);
if (entity != null) {
return entity.getBukkitEntity();
}
}
return null;
}
@Override
public io.izzel.taboolib.module.nms.impl.Position fromBlockPosition(Object blockPosition) {
return blockPosition instanceof net.minecraft.server.v1_12_R1.BlockPosition ? new io.izzel.taboolib.module.nms.impl.Position(((net.minecraft.server.v1_12_R1.BlockPosition) blockPosition).getX(), ((net.minecraft.server.v1_12_R1.BlockPosition) blockPosition).getY(), ((net.minecraft.server.v1_12_R1.BlockPosition) blockPosition).getZ()) : null;
}
@Override
public void openSignEditor(Player player, Block block) {
try {
((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) player).getHandle().playerConnection.sendPacket(new net.minecraft.server.v1_12_R1.PacketPlayOutOpenSignEditor(new net.minecraft.server.v1_12_R1.BlockPosition(block.getX(), block.getY(), block.getZ())));
} catch (Throwable t) {
t.printStackTrace();
}
}
private Object toNBTBase(io.izzel.taboolib.module.nms.nbt.NBTBase base) {
2019-05-26 07:02:29 +00:00
switch (base.getType().getId()) {
case 1:
2020-01-07 14:56:29 +00:00
if (Version.isAfter(Version.v1_15)) {
return net.minecraft.server.v1_15_R1.NBTTagByte.a(base.asByte());
} else {
return new NBTTagByte(base.asByte());
}
2019-05-26 07:02:29 +00:00
case 2:
2020-01-07 14:56:29 +00:00
if (Version.isAfter(Version.v1_15)) {
return net.minecraft.server.v1_15_R1.NBTTagShort.a(base.asShort());
} else {
return new NBTTagShort(base.asShort());
}
2019-05-26 07:02:29 +00:00
case 3:
2020-01-07 14:56:29 +00:00
if (Version.isAfter(Version.v1_15)) {
return net.minecraft.server.v1_15_R1.NBTTagInt.a(base.asInt());
} else {
return new NBTTagInt(base.asInt());
}
2019-05-26 07:02:29 +00:00
case 4:
2020-01-07 14:56:29 +00:00
if (Version.isAfter(Version.v1_15)) {
return net.minecraft.server.v1_15_R1.NBTTagLong.a(base.asLong());
} else {
return new NBTTagLong(base.asLong());
}
2019-05-26 07:02:29 +00:00
case 5:
2020-01-07 14:56:29 +00:00
if (Version.isAfter(Version.v1_15)) {
return net.minecraft.server.v1_15_R1.NBTTagFloat.a(base.asFloat());
} else {
return new NBTTagFloat(base.asFloat());
}
2019-05-26 07:02:29 +00:00
case 6:
2020-01-07 14:56:29 +00:00
if (Version.isAfter(Version.v1_15)) {
return net.minecraft.server.v1_15_R1.NBTTagDouble.a(base.asDouble());
} else {
return new NBTTagDouble(base.asDouble());
}
2019-05-26 07:02:29 +00:00
case 7:
2019-05-24 16:08:37 +00:00
return new NBTTagByteArray(base.asByteArray());
2019-05-26 07:02:29 +00:00
case 11:
return new NBTTagIntArray(base.asIntArray());
case 8:
2020-01-07 14:56:29 +00:00
if (Version.isAfter(Version.v1_15)) {
return net.minecraft.server.v1_15_R1.NBTTagString.a(base.asString());
} else {
return new NBTTagString(base.asString());
}
2019-05-26 07:02:29 +00:00
case 9:
2019-05-24 16:08:37 +00:00
Object nmsList = new NBTTagList();
for (io.izzel.taboolib.module.nms.nbt.NBTBase value : base.asList()) {
// 1.14+
if (Version.isAfter(Version.v1_14)) {
((net.minecraft.server.v1_14_R1.NBTTagList) nmsList).add(((net.minecraft.server.v1_14_R1.NBTTagList) nmsList).size(), (net.minecraft.server.v1_14_R1.NBTBase) toNBTBase(value));
}
2019-06-28 07:17:35 +00:00
// 1.13
else if (Version.isAfter(Version.v1_13)) {
2019-06-28 07:17:35 +00:00
((net.minecraft.server.v1_13_R2.NBTTagList) nmsList).add((net.minecraft.server.v1_13_R2.NBTBase) toNBTBase(value));
}
// 1.12-
else {
2020-04-02 10:18:50 +00:00
((NBTTagList) nmsList).add((net.minecraft.server.v1_8_R3.NBTBase) toNBTBase(value));
}
2019-06-13 15:42:47 +00:00
}
2019-05-24 16:08:37 +00:00
return nmsList;
2019-05-26 07:02:29 +00:00
case 10:
2019-05-24 16:08:37 +00:00
Object nmsTag = new net.minecraft.server.v1_8_R3.NBTTagCompound();
for (Map.Entry<String, io.izzel.taboolib.module.nms.nbt.NBTBase> entry : base.asCompound().entrySet()) {
2019-06-25 07:08:42 +00:00
((Map) SimpleReflection.getFieldValue(NBTTagCompound.class, nmsTag, "map")).put(entry.getKey(), toNBTBase(entry.getValue()));
2019-06-13 15:42:47 +00:00
}
2019-05-24 16:08:37 +00:00
return nmsTag;
}
return null;
}
private Object fromNBTBase(Object base) {
2019-06-13 15:42:47 +00:00
if (base instanceof net.minecraft.server.v1_8_R3.NBTTagCompound) {
NBTCompound nbtCompound = new NBTCompound();
for (Map.Entry<String, net.minecraft.server.v1_12_R1.NBTBase> entry : ((Map<String, net.minecraft.server.v1_12_R1.NBTBase>) SimpleReflection.getFieldValue(NBTTagCompound.class, base, "map")).entrySet()) {
nbtCompound.put(entry.getKey(), (io.izzel.taboolib.module.nms.nbt.NBTBase) fromNBTBase(entry.getValue()));
2019-06-13 15:42:47 +00:00
}
return nbtCompound;
} else if (base instanceof NBTTagList) {
NBTList nbtList = new NBTList();
for (Object v : (List) SimpleReflection.getFieldValue(NBTTagList.class, base, "list")) {
nbtList.add((io.izzel.taboolib.module.nms.nbt.NBTBase) fromNBTBase(v));
2019-06-13 15:42:47 +00:00
}
return nbtList;
} else if (base instanceof NBTTagString) {
return new io.izzel.taboolib.module.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagString.class, base, "data", ""));
2019-05-24 16:08:37 +00:00
} else if (base instanceof NBTTagDouble) {
return new io.izzel.taboolib.module.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagDouble.class, base, "data", 0D));
2019-05-24 16:08:37 +00:00
} else if (base instanceof NBTTagInt) {
return new io.izzel.taboolib.module.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagInt.class, base, "data", 0));
2019-05-24 16:08:37 +00:00
} else if (base instanceof NBTTagFloat) {
return new io.izzel.taboolib.module.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagFloat.class, base, "data", (float) 0));
2019-05-24 16:08:37 +00:00
} else if (base instanceof NBTTagShort) {
return new io.izzel.taboolib.module.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagShort.class, base, "data", (short) 0));
2019-05-24 16:08:37 +00:00
} else if (base instanceof NBTTagLong) {
return new io.izzel.taboolib.module.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagLong.class, base, "data", 0L));
2019-05-24 16:08:37 +00:00
} else if (base instanceof NBTTagByte) {
return new io.izzel.taboolib.module.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagByte.class, base, "data", (byte) 0D));
2019-05-24 16:08:37 +00:00
} else if (base instanceof NBTTagIntArray) {
return new io.izzel.taboolib.module.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagIntArray.class, base, "data", new int[0]));
2019-05-24 16:08:37 +00:00
} else if (base instanceof NBTTagByteArray) {
return new io.izzel.taboolib.module.nms.nbt.NBTBase(SimpleReflection.getFieldValue(NBTTagByteArray.class, base, "data", new byte[0]));
2019-05-24 16:08:37 +00:00
}
return null;
2019-01-20 08:45:02 +00:00
}
2020-02-13 08:46:26 +00:00
@Override
public boolean inBoundingBox(Entity entity, Vector vector) {
if (Version.isAfter(Version.v1_14)) {
return ((org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity) entity).getHandle().getBoundingBox().c(new net.minecraft.server.v1_14_R1.Vec3D(vector.getX(), vector.getY(), vector.getZ()));
} else {
return ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity) entity).getHandle().getBoundingBox().b(new net.minecraft.server.v1_12_R1.Vec3D(vector.getX(), vector.getY(), vector.getZ()));
}
}
@Override
public Location getLastLocation(ProjectileHitEvent event) {
Vector vector = event.getEntity().getVelocity().normalize().multiply(0.1);
Vector vectorEntity = event.getEntity().getLocation().toVector();
if (event.getHitBlock() != null) {
double i = 0;
double length = event.getHitBlock().getLocation().add(0.5, 0.5, 0.5).distance(event.getEntity().getLocation()) * 2;
while (i < length) {
Location location = vectorEntity.toLocation(event.getHitBlock().getWorld());
if (location.getBlock().getLocation().equals(event.getHitBlock().getLocation())) {
return location;
}
vectorEntity.add(vector);
i += 0.1;
}
}
if (event.getHitEntity() != null) {
double i = 0;
double length = event.getHitEntity().getLocation().distance(event.getEntity().getLocation()) * 2;
while (i < length) {
if (inBoundingBox(event.getHitEntity(), vectorEntity)) {
return vectorEntity.toLocation(event.getHitEntity().getWorld());
}
vectorEntity.add(vector);
i += 0.1;
}
}
return null;
}
2020-03-07 12:40:49 +00:00
@Override
public void sendPacketEntityDestroy(Player player, int entity) {
((CraftPlayer) player).getHandle().playerConnection.sendPacket(new net.minecraft.server.v1_13_R2.PacketPlayOutEntityDestroy(entity));
}
@Override
public void sendPacketEntityTeleport(Player player, int entity, Location location) {
Object teleport = new net.minecraft.server.v1_13_R2.PacketPlayOutEntityTeleport();
SimpleReflection.checkAndSave(net.minecraft.server.v1_13_R2.PacketPlayOutEntityTeleport.class);
SimpleReflection.setFieldValue(net.minecraft.server.v1_13_R2.PacketPlayOutEntityTeleport.class, teleport, "a", entity);
SimpleReflection.setFieldValue(net.minecraft.server.v1_13_R2.PacketPlayOutEntityTeleport.class, teleport, "b", location.getX());
SimpleReflection.setFieldValue(net.minecraft.server.v1_13_R2.PacketPlayOutEntityTeleport.class, teleport, "c", location.getY());
SimpleReflection.setFieldValue(net.minecraft.server.v1_13_R2.PacketPlayOutEntityTeleport.class, teleport, "d", location.getZ());
((CraftPlayer) player).getHandle().playerConnection.sendPacket((net.minecraft.server.v1_13_R2.PacketPlayOutEntityTeleport) teleport);
}
2020-03-10 15:48:48 +00:00
@Override
public <T extends Entity> T spawn(Location location, Class<T> entity, Consumer<T> e) {
if (Version.isAfter(Version.v1_12)) {
return location.getWorld().spawn(location, entity, e::accept);
} else {
Object createEntity = ((CraftWorld) location.getWorld()).createEntity(location, entity);
try {
2020-03-13 06:19:38 +00:00
e.accept((T) ((net.minecraft.server.v1_13_R2.Entity) createEntity).getBukkitEntity());
2020-03-10 15:48:48 +00:00
} catch (Throwable t) {
t.printStackTrace();
}
return ((CraftWorld) location.getWorld()).addEntity((net.minecraft.server.v1_13_R2.Entity) createEntity, CreatureSpawnEvent.SpawnReason.CUSTOM);
}
}
2020-03-16 14:21:25 +00:00
@Override
public Object ofChatComponentText(String source) {
return new net.minecraft.server.v1_12_R1.ChatComponentText(source);
}
@Override
public Class<?> asNMS(String name) {
try {
return Class.forName("net.minecraft.server." + Version.getBukkitVersion() + "." + name);
} catch (Throwable ignored) {
return null;
}
}
@Override
public Object asEntityType(String name) {
if (Version.isAfter(Version.v1_14)) {
return net.minecraft.server.v1_14_R1.EntityTypes.a(name).orElse(null);
} else {
return net.minecraft.server.v1_13_R2.EntityTypes.a(name);
}
}
2020-04-02 10:18:50 +00:00
@Override
public boolean createLight(Block block, Type lightType, int lightLevel) {
int level = getRawLightLevel(block, lightType);
setRawLightLevel(block, lightType, lightLevel);
recalculate(block, lightType);
return getRawLightLevel(block, lightType) >= level;
}
@Override
public boolean deleteLight(Block block, Type lightType) {
int level = getRawLightLevel(block, lightType);
setRawLightLevel(block, lightType, 0);
recalculate(block, lightType);
return getRawLightLevel(block, lightType) != level;
}
@Override
public void setRawLightLevel(Block block, Type lightType, int lightLevel) {
int level = Math.max(Math.min(lightLevel, 15), 0);
Object world = ((CraftWorld) block.getWorld()).getHandle();
Object position = new net.minecraft.server.v1_15_R1.BlockPosition(block.getX(), block.getY(), block.getZ());
if (is11400) {
sync(((net.minecraft.server.v1_14_R1.WorldServer) world).getChunkProvider().getLightEngine(), lightEngine -> {
if (lightType == Type.BLOCK) {
Object lightEngineLayer = ((net.minecraft.server.v1_14_R1.LightEngineThreaded) lightEngine).a(net.minecraft.server.v1_14_R1.EnumSkyBlock.BLOCK);
setRawLightLevelBlock(level, position, lightEngineLayer);
} else if (lightType == Type.SKY) {
Object lightEngineLayer = ((net.minecraft.server.v1_14_R1.LightEngineThreaded) lightEngine).a(net.minecraft.server.v1_14_R1.EnumSkyBlock.SKY);
setRawLightLevelSky(level, position, lightEngineLayer);
} else {
Object lightEngineLayer1 = ((net.minecraft.server.v1_14_R1.LightEngineThreaded) lightEngine).a(net.minecraft.server.v1_14_R1.EnumSkyBlock.BLOCK);
Object lightEngineLayer2 = ((net.minecraft.server.v1_14_R1.LightEngineThreaded) lightEngine).a(net.minecraft.server.v1_14_R1.EnumSkyBlock.SKY);
setRawLightLevelBlock(level, position, lightEngineLayer1);
setRawLightLevelSky(level, position, lightEngineLayer2);
}
});
} else {
if (lightType == Type.BLOCK) {
((net.minecraft.server.v1_13_R2.WorldServer) world).a(net.minecraft.server.v1_13_R2.EnumSkyBlock.BLOCK, (net.minecraft.server.v1_13_R2.BlockPosition) position, level);
} else if (lightType == Type.SKY) {
((net.minecraft.server.v1_13_R2.WorldServer) world).a(net.minecraft.server.v1_13_R2.EnumSkyBlock.SKY, (net.minecraft.server.v1_13_R2.BlockPosition) position, level);
} else {
((net.minecraft.server.v1_13_R2.WorldServer) world).a(net.minecraft.server.v1_13_R2.EnumSkyBlock.BLOCK, (net.minecraft.server.v1_13_R2.BlockPosition) position, level);
((net.minecraft.server.v1_13_R2.WorldServer) world).a(net.minecraft.server.v1_13_R2.EnumSkyBlock.SKY, (net.minecraft.server.v1_13_R2.BlockPosition) position, level);
}
}
}
@Override
public int getRawLightLevel(Block block, Type lightType) {
Object world = ((CraftWorld) block.getWorld()).getHandle();
Object position = new net.minecraft.server.v1_15_R1.BlockPosition(block.getX(), block.getY(), block.getZ());
if (lightType == Type.BLOCK) {
return ((net.minecraft.server.v1_13_R2.WorldServer) world).getBrightness(net.minecraft.server.v1_13_R2.EnumSkyBlock.BLOCK, (net.minecraft.server.v1_13_R2.BlockPosition) position);
} else if (lightType == Type.SKY) {
return ((net.minecraft.server.v1_13_R2.WorldServer) world).getBrightness(net.minecraft.server.v1_13_R2.EnumSkyBlock.SKY, (net.minecraft.server.v1_13_R2.BlockPosition) position);
} else {
return ((net.minecraft.server.v1_13_R2.WorldServer) world).getLightLevel((net.minecraft.server.v1_13_R2.BlockPosition) position);
}
}
@Override
public void recalculate(Block block, Type lightType) {
Object world = ((CraftWorld) block.getWorld()).getHandle();
Object position = new net.minecraft.server.v1_15_R1.BlockPosition(block.getX(), block.getY(), block.getZ());
if (is11400) {
Object lightEngine = ((net.minecraft.server.v1_14_R1.WorldServer) world).getChunkProvider().getLightEngine();
if (((net.minecraft.server.v1_14_R1.LightEngineThreaded) lightEngine).a()) {
sync(lightEngine, e -> {
Object[] lightEngineLayers;
if (lightType == Type.BLOCK) {
((LightEngineLayer) ((net.minecraft.server.v1_14_R1.LightEngineThreaded) lightEngine).a(net.minecraft.server.v1_14_R1.EnumSkyBlock.BLOCK)).a(Integer.MAX_VALUE, true, true);
} else if (lightType == Type.SKY) {
((LightEngineLayer) ((net.minecraft.server.v1_14_R1.LightEngineThreaded) lightEngine).a(net.minecraft.server.v1_14_R1.EnumSkyBlock.SKY)).a(Integer.MAX_VALUE, true, true);
} else {
Object b = ((net.minecraft.server.v1_14_R1.LightEngineThreaded) lightEngine).a(net.minecraft.server.v1_14_R1.EnumSkyBlock.BLOCK);
Object s = ((net.minecraft.server.v1_14_R1.LightEngineThreaded) lightEngine).a(net.minecraft.server.v1_14_R1.EnumSkyBlock.SKY);
int maxUpdateCount = Integer.MAX_VALUE;
int integer4 = maxUpdateCount / 2;
int integer5 = ((LightEngineLayer) b).a(integer4, true, true);
int integer6 = maxUpdateCount - integer4 + integer5;
int integer7 = ((LightEngineLayer) s).a(integer6, true, true);
if (integer5 == 0 && integer7 > 0) {
((LightEngineLayer) b).a(integer7, true, true);
}
}
});
}
} else {
if (lightType == Type.SKY) {
((net.minecraft.server.v1_13_R2.WorldServer) world).c(net.minecraft.server.v1_13_R2.EnumSkyBlock.SKY, (net.minecraft.server.v1_13_R2.BlockPosition) position);
} else if (lightType == Type.BLOCK) {
((net.minecraft.server.v1_13_R2.WorldServer) world).c(net.minecraft.server.v1_13_R2.EnumSkyBlock.BLOCK, (net.minecraft.server.v1_13_R2.BlockPosition) position);
} else {
((net.minecraft.server.v1_13_R2.WorldServer) world).c(net.minecraft.server.v1_13_R2.EnumSkyBlock.SKY, (net.minecraft.server.v1_13_R2.BlockPosition) position);
((net.minecraft.server.v1_13_R2.WorldServer) world).c(net.minecraft.server.v1_13_R2.EnumSkyBlock.BLOCK, (net.minecraft.server.v1_13_R2.BlockPosition) position);
}
}
}
@Override
public void update(Chunk chunk) {
for (Player player : Bukkit.getOnlinePlayers()) {
Object human = ((org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer) player).getHandle();
Object chunk1 = ((CraftWorld) player.getWorld()).getHandle().getChunkAt(chunk.getX(), chunk.getZ());
Object chunk2 = ((net.minecraft.server.v1_8_R3.EntityPlayer) human).world.getChunkAtWorldCoords(((net.minecraft.server.v1_8_R3.EntityPlayer) human).getChunkCoordinates());
if (distance(chunk2, chunk1) < distance(human)) {
if (is11400) {
TPacketHandler.sendPacket(player, new PacketPlayOutLightUpdate(((net.minecraft.server.v1_14_R1.Chunk) chunk1).getPos(), ((net.minecraft.server.v1_14_R1.Chunk) chunk1).e()));
} else {
TPacketHandler.sendPacket(player, new net.minecraft.server.v1_14_R1.PacketPlayOutMapChunk((net.minecraft.server.v1_14_R1.Chunk) chunk1, 0x1ffff));
}
}
}
}
public int distance(Object player) {
int viewDistance = Bukkit.getViewDistance();
try {
int playerViewDistance = ((net.minecraft.server.v1_14_R1.EntityPlayer) player).clientViewDistance;
if (playerViewDistance < viewDistance) {
viewDistance = playerViewDistance;
}
} catch (Exception ignored) {
}
return viewDistance;
}
private int distance(Object from, Object to) {
if (!((net.minecraft.server.v1_14_R1.Chunk) from).world.getWorldData().getName().equals(((net.minecraft.server.v1_14_R1.Chunk) to).world.getWorldData().getName())) {
return 100;
}
double var2 = ((net.minecraft.server.v1_14_R1.Chunk) to).getPos().x - ((net.minecraft.server.v1_14_R1.Chunk) from).getPos().x;
double var4 = ((net.minecraft.server.v1_14_R1.Chunk) to).getPos().z - ((net.minecraft.server.v1_14_R1.Chunk) from).getPos().z;
return (int) Math.sqrt(var2 * var2 + var4 * var4);
}
public void sync(Object lightEngine, Consumer<Object> task) {
try {
Object b = SimpleReflection.getFieldValueChecked(LightEngineThreaded.class, lightEngine, "b", true);
Object c = SimpleReflection.getFieldValueChecked(ThreadedMailbox.class, b, "c", true);
int flags;
long wait = -1L;
while (!((AtomicInteger) c).compareAndSet(flags = ((AtomicInteger) c).get() & ~2, flags | 2)) {
if ((flags & 1) != 0) {
if (wait == -1) {
wait = System.currentTimeMillis() + 3 * 1000;
TLogger.getGlobalLogger().info("ThreadedMailbox is closing. Will wait...");
} else if (System.currentTimeMillis() >= wait) {
TLogger.getGlobalLogger().warn("Failed to enter critical section while ThreadedMailbox is closing");
}
try {
Thread.sleep(50);
} catch (InterruptedException ignored) {
}
}
}
try {
task.accept(lightEngine);
} finally {
while (!((AtomicInteger) c).compareAndSet(flags = ((AtomicInteger) c).get(), flags & ~2))
;
SimpleReflection.invokeMethod(ThreadedMailbox.class, b, "f", new Object[0], true);
}
} catch (Throwable t) {
t.printStackTrace();
}
}
private void setRawLightLevelBlock(int level, Object position, Object lightEngineLayer) {
if (level == 0) {
((LightEngineBlock) lightEngineLayer).a((BlockPosition) position);
} else if (((LightEngineLayer) lightEngineLayer).a(SectionPosition.a((net.minecraft.server.v1_14_R1.BlockPosition) position)) != null) {
try {
((LightEngineLayer) lightEngineLayer).a((net.minecraft.server.v1_14_R1.BlockPosition) position, level);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
private void setRawLightLevelSky(int level, Object position, Object lightEngineLayer) {
if (level == 0) {
((LightEngineSky) lightEngineLayer).a((BlockPosition) position);
} else if (((LightEngineLayer) lightEngineLayer).a(SectionPosition.a((net.minecraft.server.v1_14_R1.BlockPosition) position)) != null) {
try {
Object s = SimpleReflection.getFieldValueChecked(LightEngineLayer.class, lightEngineLayer, "c", true);
if (is11500) {
SimpleReflection.invokeMethod(LightEngineStorage.class, s, "d", new Object[0], true);
} else {
SimpleReflection.invokeMethod(LightEngineStorage.class, s, "c", new Object[0], true);
}
SimpleReflection.invokeMethod(LightEngineGraph.class, lightEngineLayer, "a", new Object[] {9223372036854775807L, ((net.minecraft.server.v1_14_R1.BlockPosition) position).asLong(), 15 - level, true}, true);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}