diff --git a/src/com/massivecraft/massivecore/MassiveCore.java b/src/com/massivecraft/massivecore/MassiveCore.java index 6d46e212..76f98df9 100644 --- a/src/com/massivecraft/massivecore/MassiveCore.java +++ b/src/com/massivecraft/massivecore/MassiveCore.java @@ -85,10 +85,13 @@ import com.massivecraft.massivecore.mixin.MixinWorld; import com.massivecraft.massivecore.mson.Mson; import com.massivecraft.massivecore.mson.MsonEvent; import com.massivecraft.massivecore.nms.NmsBasics; +import com.massivecraft.massivecore.nms.NmsChat; import com.massivecraft.massivecore.nms.NmsEntityGet; import com.massivecraft.massivecore.nms.NmsItemStackCreate; import com.massivecraft.massivecore.nms.NmsItemStackCreate17R4P; +import com.massivecraft.massivecore.nms.NmsItemStackTooltip; import com.massivecraft.massivecore.nms.NmsPlayerInventoryCreate; +import com.massivecraft.massivecore.nms.NmsSkullMeta; import com.massivecraft.massivecore.ps.PS; import com.massivecraft.massivecore.ps.PSAdapter; import com.massivecraft.massivecore.store.ModificationPollerLocal; @@ -252,9 +255,12 @@ public class MassiveCore extends MassivePlugin // Nms NmsBasics.class, + NmsChat.class, NmsEntityGet.class, NmsItemStackCreate.class, + NmsItemStackTooltip.class, NmsPlayerInventoryCreate.class, + NmsSkullMeta.class, // Writer, WriterItemStack.class, diff --git a/src/com/massivecraft/massivecore/command/requirement/RequirementTitlesAvailable.java b/src/com/massivecraft/massivecore/command/requirement/RequirementTitlesAvailable.java index 4fa1f9f7..b716ba33 100644 --- a/src/com/massivecraft/massivecore/command/requirement/RequirementTitlesAvailable.java +++ b/src/com/massivecraft/massivecore/command/requirement/RequirementTitlesAvailable.java @@ -25,7 +25,7 @@ public class RequirementTitlesAvailable extends RequirementAbstract @Override public boolean apply(CommandSender sender, MassiveCommand command) { - return MixinTitle.get().isTitlesAvailable(); + return MixinTitle.get().isAvailable(); } @Override diff --git a/src/com/massivecraft/massivecore/item/WriterItemStackMeta.java b/src/com/massivecraft/massivecore/item/WriterItemStackMeta.java index e5790a54..ffc8841b 100644 --- a/src/com/massivecraft/massivecore/item/WriterItemStackMeta.java +++ b/src/com/massivecraft/massivecore/item/WriterItemStackMeta.java @@ -32,8 +32,7 @@ public class WriterItemStackMeta extends WriterAbstractItemStackMetaMorph +public class WriterItemStackMetaSkull extends WriterAbstractItemStackMetaField { // -------------------------------------------- // // INSTANCE & CONSTRUCT // -------------------------------------------- // - private static final WriterItemStackMetaSkull18 i = new WriterItemStackMetaSkull18(); - public static WriterItemStackMetaSkull18 get() { return i; } - public WriterItemStackMetaSkull18() + private static final WriterItemStackMetaSkull i = new WriterItemStackMetaSkull(); + public static WriterItemStackMetaSkull get() { return i; } + public WriterItemStackMetaSkull() { super(SkullMeta.class); this.setMaterial(Material.SKULL_ITEM); @@ -50,16 +50,17 @@ public class WriterItemStackMetaSkull18 extends WriterAbstractItemStackMetaField public void setB(SkullMeta cb, String fb, ItemStack d) { String name = fb; - UUID id = null; - Couple resolved = NmsHead.resolve(name, id); + NmsSkullMeta nms = NmsSkullMeta.get(); + + Couple resolved = nms.resolve(name, id); name = resolved.getFirst(); id = resolved.getSecond(); if (name != null || id != null) { - NmsHead.set(cb, name, id); + nms.set(cb, name, id); } } diff --git a/src/com/massivecraft/massivecore/item/WriterItemStackMetaSkull17.java b/src/com/massivecraft/massivecore/item/WriterItemStackMetaSkull17.java deleted file mode 100644 index 116cb2f4..00000000 --- a/src/com/massivecraft/massivecore/item/WriterItemStackMetaSkull17.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.massivecraft.massivecore.item; - -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.SkullMeta; - -public class WriterItemStackMetaSkull17 extends WriterAbstractItemStackMetaField -{ - // -------------------------------------------- // - // INSTANCE & CONSTRUCT - // -------------------------------------------- // - - private static final WriterItemStackMetaSkull17 i = new WriterItemStackMetaSkull17(); - public static WriterItemStackMetaSkull17 get() { return i; } - public WriterItemStackMetaSkull17() - { - super(SkullMeta.class); - this.setMaterial(Material.SKULL_ITEM); - } - - // -------------------------------------------- // - // ACCESS - // -------------------------------------------- // - - @Override - public String getA(DataItemStack ca, ItemStack d) - { - return ca.getSkull(); - } - - @Override - public void setA(DataItemStack ca, String fa, ItemStack d) - { - ca.setSkull(fa); - } - - @Override - public String getB(SkullMeta cb, ItemStack d) - { - return cb.getOwner(); - } - - @Override - public void setB(SkullMeta cb, String fb, ItemStack d) - { - cb.setOwner(fb); - } - -} diff --git a/src/com/massivecraft/massivecore/mixin/MixinActionbar.java b/src/com/massivecraft/massivecore/mixin/MixinActionbar.java index 35f625a5..b52e0457 100644 --- a/src/com/massivecraft/massivecore/mixin/MixinActionbar.java +++ b/src/com/massivecraft/massivecore/mixin/MixinActionbar.java @@ -1,10 +1,9 @@ package com.massivecraft.massivecore.mixin; import org.bukkit.entity.Player; + import com.massivecraft.massivecore.mson.Mson; -import com.massivecraft.massivecore.nms.NmsPacket; -import com.massivecraft.massivecore.util.IdUtil; -import com.massivecraft.massivecore.util.Txt; +import com.massivecraft.massivecore.nms.NmsChat; public class MixinActionbar extends Mixin { @@ -17,40 +16,37 @@ public class MixinActionbar extends Mixin public static MixinActionbar get() { return i; } // -------------------------------------------- // - // METHODS + // AVAILABLE // -------------------------------------------- // - public boolean sendActionbarMessage(Object watcherObject, String message) + @Override + public boolean isAvailable() { - // Get the player - Player player = IdUtil.getPlayer(watcherObject); - if(player == null) return false; - - message = NmsPacket.toJson(message); - - return NmsPacket.sendActionbar(player, message); + return NmsChat.get().isAvailable(); + } + + // -------------------------------------------- // + // SEND + // -------------------------------------------- // + + public void sendActionbarRaw(Player player, String raw) + { + NmsChat.get().sendActionbarRaw(player, raw); + } + + public void sendActionbarMson(Object watcherObject, Mson mson) + { + NmsChat.get().sendActionbarMson(watcherObject, mson); + } + + public void sendActionbarMessage(Object watcherObject, String message) + { + NmsChat.get().sendActionbarMessage(watcherObject, message); } - public boolean sendActionbarMsg(Object watcherObject, String message) + public void sendActionbarMsg(Object watcherObject, String msg) { - return this.sendActionbarMessage(watcherObject, Txt.parse(message)); - } - - public boolean sendActionbarMson(Object watcherObject, Mson mson) - { - // Get the player - Player player = IdUtil.getPlayer(watcherObject); - if(player == null) return false; - - // Convert to raw - String message = mson.toRaw(); - - return NmsPacket.sendActionbar(player, message); - } - - public boolean isActionbarAvailable() - { - return NmsPacket.get().isAvailable(); + NmsChat.get().sendActionbarMsg(watcherObject, msg); } } diff --git a/src/com/massivecraft/massivecore/mixin/MixinMessage.java b/src/com/massivecraft/massivecore/mixin/MixinMessage.java index c318ec53..87d83fa6 100644 --- a/src/com/massivecraft/massivecore/mixin/MixinMessage.java +++ b/src/com/massivecraft/massivecore/mixin/MixinMessage.java @@ -5,10 +5,9 @@ import java.util.Collection; import java.util.Collections; import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; import com.massivecraft.massivecore.mson.Mson; -import com.massivecraft.massivecore.nms.NmsPacket; +import com.massivecraft.massivecore.nms.NmsChat; import com.massivecraft.massivecore.predicate.Predicate; import com.massivecraft.massivecore.util.IdUtil; import com.massivecraft.massivecore.util.Txt; @@ -179,15 +178,7 @@ public class MixinMessage extends Mixin else if (message instanceof Mson) { Mson mson = (Mson)message; - if (sendee instanceof Player && NmsPacket.get().isAvailable()) - { - Player player = (Player) sendee; - NmsPacket.sendRaw(player, mson.toRaw()); - } - else - { - sendee.sendMessage(mson.toPlain(true)); - } + NmsChat.get().sendChatMson(sendee, mson); } else { diff --git a/src/com/massivecraft/massivecore/mixin/MixinTitle.java b/src/com/massivecraft/massivecore/mixin/MixinTitle.java index d54730bf..4d4a7eda 100644 --- a/src/com/massivecraft/massivecore/mixin/MixinTitle.java +++ b/src/com/massivecraft/massivecore/mixin/MixinTitle.java @@ -2,9 +2,8 @@ package com.massivecraft.massivecore.mixin; import org.bukkit.entity.Player; -import com.massivecraft.massivecore.nms.NmsPacket; -import com.massivecraft.massivecore.util.IdUtil; -import com.massivecraft.massivecore.util.Txt; +import com.massivecraft.massivecore.mson.Mson; +import com.massivecraft.massivecore.nms.NmsChat; public class MixinTitle extends Mixin { @@ -17,35 +16,37 @@ public class MixinTitle extends Mixin public static MixinTitle get() { return i; } // -------------------------------------------- // - // METHODS + // AVAILABLE // -------------------------------------------- // - public boolean sendTitleMessage(Object watcherObject, int ticksIn, int ticksStay, int ticksOut, String titleMain, String titleSub) + @Override + public boolean isAvailable() { - // Get the player - Player player = IdUtil.getPlayer(watcherObject); - if (player == null) return false; - - // If we don't send any message (empty is ok) we might end up displaying old messages. - if (titleSub == null) titleSub = ""; - if (titleMain == null) titleMain = ""; - - titleSub = NmsPacket.toJson(titleSub); - titleMain = NmsPacket.toJson(titleMain); - - return NmsPacket.sendTitle(player, ticksIn, ticksStay, ticksOut, titleMain, titleSub); + return NmsChat.get().isAvailable(); } - public boolean sendTitleMsg(Object watcherObject, int ticksIn, int ticksStay, int ticksOut, String titleMain, String titleSub) + // -------------------------------------------- // + // SEND + // -------------------------------------------- // + + public void sendTitleRaw(Player player, int ticksIn, int ticksStay, int ticksOut, String rawMain, String rawSub) { - if (titleMain != null) titleMain = Txt.parse(titleMain); - if (titleSub != null) titleSub = Txt.parse(titleSub); - return this.sendTitleMessage(watcherObject, ticksIn, ticksStay, ticksOut, titleMain, titleSub); + NmsChat.get().sendTitleRaw(player, ticksIn, ticksStay, ticksOut, rawMain, rawSub); } - public boolean isTitlesAvailable() + public void sendTitleMson(Object watcherObject, int ticksIn, int ticksStay, int ticksOut, Mson msonMain, Mson msonSub) { - return NmsPacket.get().isAvailable(); + NmsChat.get().sendTitleMson(watcherObject, ticksIn, ticksStay, ticksOut, msonMain, msonSub); + } + + public void sendTitleMessage(Object watcherObject, int ticksIn, int ticksStay, int ticksOut, String messageMain, String messageSub) + { + NmsChat.get().sendTitleMessage(watcherObject, ticksIn, ticksStay, ticksOut, messageMain, messageSub); + } + + public void sendTitleMsg(Object watcherObject, int ticksIn, int ticksStay, int ticksOut, String msgMain, String msgSub) + { + NmsChat.get().sendTitleMsg(watcherObject, ticksIn, ticksStay, ticksOut, msgMain, msgSub); } } diff --git a/src/com/massivecraft/massivecore/mson/MsonEvent.java b/src/com/massivecraft/massivecore/mson/MsonEvent.java index df172ba6..5d8d4133 100644 --- a/src/com/massivecraft/massivecore/mson/MsonEvent.java +++ b/src/com/massivecraft/massivecore/mson/MsonEvent.java @@ -7,7 +7,7 @@ import java.util.Objects; import org.bukkit.inventory.ItemStack; import com.massivecraft.massivecore.command.MassiveCommand; -import com.massivecraft.massivecore.nms.NmsItem; +import com.massivecraft.massivecore.nms.NmsItemStackTooltip; import com.massivecraft.massivecore.util.MUtil; import com.massivecraft.massivecore.util.Txt; @@ -127,7 +127,10 @@ public final class MsonEvent implements Serializable public static MsonEvent item(ItemStack item) { if (item == null) throw new NullPointerException("item"); - return MsonEvent.valueOf(MsonEventAction.SHOW_ITEM, NmsItem.itemToString(item)); + String nbtStringTooltip = null; + NmsItemStackTooltip nms = NmsItemStackTooltip.get(); + if (nms.isAvailable()) nbtStringTooltip = nms.getNbtStringTooltip(item); + return MsonEvent.valueOf(MsonEventAction.SHOW_ITEM, nbtStringTooltip); } // -------------------------------------------- // diff --git a/src/com/massivecraft/massivecore/nms/NmsChat.java b/src/com/massivecraft/massivecore/nms/NmsChat.java new file mode 100644 index 00000000..bb3f9e76 --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/NmsChat.java @@ -0,0 +1,120 @@ +package com.massivecraft.massivecore.nms; + +import org.bukkit.command.CommandSender; +import org.json.simple.JSONObject; + +import com.massivecraft.massivecore.mixin.Mixin; +import com.massivecraft.massivecore.mson.Mson; +import com.massivecraft.massivecore.util.IdUtil; +import com.massivecraft.massivecore.util.Txt; + +public class NmsChat extends Mixin +{ + // -------------------------------------------- // + // DEFAULT + // -------------------------------------------- // + + private static NmsChat d = new NmsChat().setAlternatives( + NmsChat18R2P.class, + NmsChat18R1.class + ); + + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static NmsChat i = d; + public static NmsChat get() { return i; } + + // -------------------------------------------- // + // CHAT + // -------------------------------------------- // + + public void sendChatMson(Object sendeeObject, Mson mson) + { + CommandSender sendee = IdUtil.getSender(sendeeObject); + if (sendee == null) return; + + String message = mson.toPlain(true); + sendee.sendMessage(message); + } + + // -------------------------------------------- // + // TITLE + // -------------------------------------------- // + + public void sendTitleRaw(Object sendeeObject, int ticksIn, int ticksStay, int ticksOut, String rawMain, String rawSub) + { + + } + + public void sendTitleMson(Object sendeeObject, int ticksIn, int ticksStay, int ticksOut, Mson msonMain, Mson msonSub) + { + String rawMain = msonMain.toRaw(); + String rawSub = msonSub.toRaw(); + + this.sendTitleRaw(sendeeObject, ticksIn, ticksStay, ticksOut, rawMain, rawSub); + } + + public void sendTitleMessage(Object sendeeObject, int ticksIn, int ticksStay, int ticksOut, String messageMain, String messageSub) + { + // If we don't send any message (empty is ok) we might end up displaying old messages. + if (messageMain == null) messageMain = ""; + if (messageSub == null) messageSub = ""; + + String rawMain = messageToRaw(messageMain); + String rawSub = messageToRaw(messageSub); + + this.sendTitleRaw(sendeeObject, ticksIn, ticksStay, ticksOut, rawMain, rawSub); + } + + public void sendTitleMsg(Object sendeeObject, int ticksIn, int ticksStay, int ticksOut, String msgMain, String msgSub) + { + String messageMain = Txt.parse(msgMain); + String messageSub = Txt.parse(msgSub); + + this.sendTitleMessage(sendeeObject, ticksIn, ticksStay, ticksOut, messageMain, messageSub); + } + + // -------------------------------------------- // + // ACTIONBAR + // -------------------------------------------- // + + public void sendActionbarRaw(Object sendeeObject, String raw) + { + + } + + public void sendActionbarMson(Object sendeeObject, Mson mson) + { + String message = mson.toRaw(); + + this.sendActionbarRaw(sendeeObject, message); + } + + public void sendActionbarMessage(Object sendeeObject, String message) + { + message = messageToRaw(message); + + this.sendActionbarRaw(sendeeObject, message); + } + + public void sendActionbarMsg(Object sendeeObject, String msg) + { + String message = Txt.parse(msg); + + this.sendActionbarMessage(sendeeObject, message); + } + + // -------------------------------------------- // + // MESSAGE TO RAW + // -------------------------------------------- // + + public static String messageToRaw(String message) + { + message = JSONObject.escape(message); + message = "{\"text\": \"" + message + "\"}"; + return message; + } + +} diff --git a/src/com/massivecraft/massivecore/nms/NmsChat18R1.java b/src/com/massivecraft/massivecore/nms/NmsChat18R1.java new file mode 100644 index 00000000..ba34379d --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/NmsChat18R1.java @@ -0,0 +1,28 @@ +package com.massivecraft.massivecore.nms; + +import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType; +import com.massivecraft.massivecore.util.ReflectionUtil; + +public class NmsChat18R1 extends NmsChatAbstract +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static NmsChat18R1 i = new NmsChat18R1(); + public static NmsChat18R1 get() { return i; } + + // -------------------------------------------- // + // SETUP SPECIFIC + // -------------------------------------------- // + + @Override + public void setupSpecific() throws Throwable + { + this.classChatSerializer = PackageType.MINECRAFT_SERVER.getClass("ChatSerializer"); + this.methodChatSerializer = ReflectionUtil.getMethod(this.classChatSerializer, "a", String.class); + + this.classEnumTitleAction = PackageType.MINECRAFT_SERVER.getClass("EnumTitleAction"); + } + +} diff --git a/src/com/massivecraft/massivecore/nms/NmsChat18R2P.java b/src/com/massivecraft/massivecore/nms/NmsChat18R2P.java new file mode 100644 index 00000000..e5d393e5 --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/NmsChat18R2P.java @@ -0,0 +1,28 @@ +package com.massivecraft.massivecore.nms; + +import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType; +import com.massivecraft.massivecore.util.ReflectionUtil; + +public class NmsChat18R2P extends NmsChatAbstract +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static NmsChat18R2P i = new NmsChat18R2P(); + public static NmsChat18R2P get() { return i; } + + // -------------------------------------------- // + // SETUP SPECIFIC + // -------------------------------------------- // + + @Override + public void setupSpecific() throws Throwable + { + this.classChatSerializer = PackageType.MINECRAFT_SERVER.getClass("IChatBaseComponent$ChatSerializer"); + this.methodChatSerializer = ReflectionUtil.getMethod(this.classChatSerializer, "a", String.class); + + this.classEnumTitleAction = PackageType.MINECRAFT_SERVER.getClass("PacketPlayOutTitle$EnumTitleAction"); + } + +} diff --git a/src/com/massivecraft/massivecore/nms/NmsChatAbstract.java b/src/com/massivecraft/massivecore/nms/NmsChatAbstract.java new file mode 100644 index 00000000..216eff36 --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/NmsChatAbstract.java @@ -0,0 +1,180 @@ +package com.massivecraft.massivecore.nms; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import com.massivecraft.massivecore.mson.Mson; +import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType; +import com.massivecraft.massivecore.util.IdUtil; +import com.massivecraft.massivecore.util.ReflectionUtil; + +public abstract class NmsChatAbstract extends NmsChat +{ + // -------------------------------------------- // + // FIELDS + // -------------------------------------------- // + + // EnumTitleAction + protected Class classEnumTitleAction; + protected Enum enumEnumTitleActionMain; + protected Enum enumEnumTitleActionSub; + protected Enum enumEnumTitleActionTimes; + + // ChatSerializer + protected Class classChatSerializer; + protected Method methodChatSerializer; + + // IChatBaseComponent + protected Class classIChatBaseComponent; + + // PacketPlayOutTitle + protected Class classPacketPlayOutTitle; + protected Constructor constructorPacketPlayOutTitle; + protected Constructor constructorPacketPlayOutTitleTimes; + + // PacketPlayOutChat + protected Class classPacketPlayOutChat; + protected Constructor constructorPacketPlayOutChat; + protected Constructor constructorPacketPlayOutChatType; + + // -------------------------------------------- // + // PROVOKE + // -------------------------------------------- // + + @Override + public Class provoke() throws Throwable + { + // Require NmsBasics + NmsBasics.get().require(); + + // Require 1.8 + return ArmorStand.class; + } + + // -------------------------------------------- // + // SETUP + // -------------------------------------------- // + + @Override + public void setup() throws Throwable + { + this.setupSpecific(); + + for (Object object : this.classEnumTitleAction.getEnumConstants()) + { + Enum e = (Enum) object; + if (e.name().equalsIgnoreCase("TITLE")) this.enumEnumTitleActionMain = e; + else if (e.name().equalsIgnoreCase("SUBTITLE")) this.enumEnumTitleActionSub = e; + else if (e.name().equalsIgnoreCase("TIMES")) this.enumEnumTitleActionTimes = e; + } + + this.classIChatBaseComponent = PackageType.MINECRAFT_SERVER.getClass("IChatBaseComponent"); + + // Get title packet and it's constructor + this.classPacketPlayOutTitle = PackageType.MINECRAFT_SERVER.getClass("PacketPlayOutTitle"); + this.constructorPacketPlayOutTitle = ReflectionUtil.getConstructor(this.classPacketPlayOutTitle, this.classEnumTitleAction, this.classIChatBaseComponent); + + this.constructorPacketPlayOutTitleTimes = ReflectionUtil.getConstructor(this.classPacketPlayOutTitle, this.classEnumTitleAction, this.classIChatBaseComponent, int.class, int.class, int.class); + + // Get Chat packet and it's constructor + this.classPacketPlayOutChat = PackageType.MINECRAFT_SERVER.getClass("PacketPlayOutChat"); + this.constructorPacketPlayOutChat = ReflectionUtil.getConstructor(this.classPacketPlayOutChat, this.classIChatBaseComponent); + this.constructorPacketPlayOutChatType = ReflectionUtil.getConstructor(this.classPacketPlayOutChat, this.classIChatBaseComponent, Byte.TYPE); + } + + // -------------------------------------------- // + // SETUP SPECIFIC + // -------------------------------------------- // + + public abstract void setupSpecific() throws Throwable; + + // -------------------------------------------- // + // TO COMPONENT + // -------------------------------------------- // + + protected Object toComponent(String raw) + { + return ReflectionUtil.invokeMethod(this.methodChatSerializer, null, raw); + } + + // -------------------------------------------- // + // CHAT + // -------------------------------------------- // + + @Override + public void sendChatMson(Object sendeeObject, Mson mson) + { + CommandSender sendee = IdUtil.getSender(sendeeObject); + if (sendee == null) return; + + if (sendee instanceof Player) + { + Player player = (Player)sendee; + String raw = mson.toRaw(); + Object component = toComponent(raw); + Object packet = ReflectionUtil.invokeConstructor(this.constructorPacketPlayOutChat, component); + NmsBasics.get().sendPacket(player, packet); + } + else + { + String message = mson.toPlain(true); + sendee.sendMessage(message); + } + } + + // -------------------------------------------- // + // TITLE + // -------------------------------------------- // + + @Override + public void sendTitleRaw(Object sendeeObject, int ticksIn, int ticksStay, int ticksOut, String rawMain, String rawSub) + { + Player player = IdUtil.getPlayer(sendeeObject); + if (player == null) return; + + Object component; + Object packet; + Enum action; + + // in, stay, out + packet = ReflectionUtil.invokeConstructor(this.constructorPacketPlayOutTitleTimes, this.enumEnumTitleActionTimes, null, ticksIn, ticksStay, ticksOut); + NmsBasics.get().sendPacket(player, packet); + + // main + if (rawMain != null) + { + component = toComponent(rawMain); + action = this.enumEnumTitleActionMain; + packet = ReflectionUtil.invokeConstructor(this.constructorPacketPlayOutTitle, action, component); + NmsBasics.get().sendPacket(player, packet); + } + + // sub + if (rawSub != null) + { + component = toComponent(rawSub); + action = this.enumEnumTitleActionSub; + packet = ReflectionUtil.invokeConstructor(constructorPacketPlayOutTitle, action, component); + NmsBasics.get().sendPacket(player, packet); + } + } + + // -------------------------------------------- // + // ACTIONBAR + // -------------------------------------------- // + + @Override + public void sendActionbarRaw(Object sendeeObject, String raw) + { + Player player = IdUtil.getPlayer(sendeeObject); + if (player == null) return; + + Object component = toComponent(raw); + Object packet = ReflectionUtil.invokeConstructor(this.constructorPacketPlayOutChatType, component, (byte)2); + NmsBasics.get().sendPacket(player, packet); + } + +} diff --git a/src/com/massivecraft/massivecore/nms/NmsHead.java b/src/com/massivecraft/massivecore/nms/NmsHead.java deleted file mode 100644 index 0a77d11d..00000000 --- a/src/com/massivecraft/massivecore/nms/NmsHead.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.massivecraft.massivecore.nms; - -import java.lang.reflect.Field; -import java.util.UUID; - -import org.bukkit.inventory.meta.SkullMeta; - -import com.massivecraft.massivecore.Couple; -import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType; -import com.massivecraft.massivecore.util.IdData; -import com.massivecraft.massivecore.util.IdUtil; -import com.massivecraft.massivecore.util.MUtil; -import com.massivecraft.massivecore.util.ReflectionUtil; - -public class NmsHead extends NmsAbstract -{ - // -------------------------------------------- // - // INSTANCE & CONSTRUCT - // -------------------------------------------- // - - private static NmsHead i = new NmsHead(); - public static NmsHead get () { return i; } - - // -------------------------------------------- // - // FIELDS - // -------------------------------------------- // - - public static Class classCraftMetaSkull; - public static Field fieldCraftMetaSkullDotProfile; - - public static Class classGameProfile; - public static Field fieldGameProfileDotId; - public static Field fieldGameProfileDotName; - - // -------------------------------------------- // - // OVERRIDE - // -------------------------------------------- // - - @Override - public int getRequiredVersion() - { - return 8; - } - - @Override - protected void setup() throws Throwable - { - classCraftMetaSkull = PackageType.CRAFTBUKKIT_INVENTORY.getClass("CraftMetaSkull"); - fieldCraftMetaSkullDotProfile = ReflectionUtil.getField(classCraftMetaSkull, "profile"); - - classGameProfile = Class.forName("com.mojang.authlib.GameProfile"); - fieldGameProfileDotId = ReflectionUtil.getField(classGameProfile, "id"); - fieldGameProfileDotName = ReflectionUtil.getField(classGameProfile, "name"); - } - - // -------------------------------------------- // - // GAMEPROFILE: SIMPLE - // -------------------------------------------- // - - public static Object getGameProfile(SkullMeta meta) - { - return ReflectionUtil.getField(fieldCraftMetaSkullDotProfile, meta); - } - - public static void setGameProfile(SkullMeta meta, Object gameProfile) - { - ReflectionUtil.setField(fieldCraftMetaSkullDotProfile, meta, gameProfile); - } - - // -------------------------------------------- // - // GAMEPROFILE: GET - // -------------------------------------------- // - - public static String getGameProfileName(Object gameProfile) - { - return ReflectionUtil.getField(fieldGameProfileDotName, gameProfile); - } - - public static UUID getGameProfileId(Object gameProfile) - { - return ReflectionUtil.getField(fieldGameProfileDotId, gameProfile); - } - - // -------------------------------------------- // - // GAMEPROFILE: SET - // -------------------------------------------- // - - public static void setGameProfileName(Object gameProfile, String name) - { - ReflectionUtil.setField(fieldGameProfileDotName, gameProfile, name); - } - - public static void setGameProfileId(Object gameProfile, UUID id) - { - ReflectionUtil.setField(fieldGameProfileDotId, gameProfile, id); - } - - // -------------------------------------------- // - // SKULLMETA: RAW - // -------------------------------------------- // - - public static String getName(SkullMeta meta) - { - // Object gameProfile = getGameProfile(meta); - // if (gameProfile == null) return null; - // return getGameProfileName(gameProfile); - - return meta.getOwner(); - } - - public static UUID getId(SkullMeta meta) - { - Object gameProfile = getGameProfile(meta); - if (gameProfile == null) return null; - return getGameProfileId(gameProfile); - } - - public static void set(SkullMeta meta, String name, UUID id) - { - meta.setOwner(name != null ? name : "adsf"); - - Object gameProfile = getGameProfile(meta); - setGameProfileName(gameProfile, name); - setGameProfileId(gameProfile, id); - } - - // -------------------------------------------- // - // RESOLVE - // -------------------------------------------- // - // We resolve the locally best possible information using IdUtil. - - public static Couple resolve(String name, UUID id) - { - // Create Ret - // We default to the input. - String retName = name; - UUID retId = id; - - // Fetch IdData - // First by name then id. - IdData data = null; - if (name != null) data = IdUtil.getNameToData().get(name); - if (data == null && id != null) data = IdUtil.getIdToData().get(id.toString()); - - // Use that data if found - if (data != null) - { - retName = data.getName(); - retId = MUtil.asUuid(data.getId()); - } - - // Return Ret - return new Couple(retName, retId); - } - - public static Couple resolve(SkullMeta meta) - { - return resolve(getName(meta), getId(meta)); - } - -} diff --git a/src/com/massivecraft/massivecore/nms/NmsItem.java b/src/com/massivecraft/massivecore/nms/NmsItem.java deleted file mode 100644 index 33e19e1b..00000000 --- a/src/com/massivecraft/massivecore/nms/NmsItem.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.massivecraft.massivecore.nms; - -import java.lang.reflect.Method; - -import org.bukkit.inventory.ItemStack; - -import com.massivecraft.massivecore.particleeffect.ReflectionUtils; -import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType; - -public class NmsItem extends NmsAbstract -{ - // -------------------------------------------- // - // INSTANCE & CONSTRUCT - // -------------------------------------------- // - - private static NmsItem i = new NmsItem(); - public static NmsItem get () { return i; } - - // -------------------------------------------- // - // FIELDS - // -------------------------------------------- // - - // Handling tooltips - private static Method toNms; - private static Method toJson; - private static Class cbItem; - private static Class nmsItem; - private static Class nbtTag; - - // -------------------------------------------- // - // OVERRIDE - // -------------------------------------------- // - - @Override - public int getRequiredVersion() - { - return 8; - } - - @Override - protected void setup() throws Throwable - { - cbItem = PackageType.CRAFTBUKKIT_INVENTORY.getClass("CraftItemStack"); - nmsItem = PackageType.MINECRAFT_SERVER.getClass("ItemStack"); - nbtTag = PackageType.MINECRAFT_SERVER.getClass("NBTTagCompound"); - - toNms = ReflectionUtils.getMethod(cbItem, "asNMSCopy", ItemStack.class); - toJson = ReflectionUtils.getMethod(nmsItem, "save", nbtTag); - - // Set accessible - toNms.setAccessible(true); - toJson.setAccessible(true); - } - - - public static String itemToString(ItemStack item) - { - if (item == null) throw new NullPointerException("item"); - - if ( ! get().isAvailable()) return null; - try - { - Object nmsItem = toNms.invoke(null, item); - if (nmsItem == null) throw new RuntimeException(item.toString()); - String str = toJson.invoke(nmsItem, nbtTag.newInstance()).toString(); - return str; - } - catch (Exception ex) - { - ex.printStackTrace(); - return null; - } - } - -} diff --git a/src/com/massivecraft/massivecore/nms/NmsItemStackTooltip.java b/src/com/massivecraft/massivecore/nms/NmsItemStackTooltip.java new file mode 100644 index 00000000..68fadf0d --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/NmsItemStackTooltip.java @@ -0,0 +1,33 @@ +package com.massivecraft.massivecore.nms; + +import org.bukkit.inventory.ItemStack; + +import com.massivecraft.massivecore.mixin.Mixin; + +public class NmsItemStackTooltip extends Mixin +{ + // -------------------------------------------- // + // DEFAULT + // -------------------------------------------- // + + private static NmsItemStackTooltip d = new NmsItemStackTooltip().setAlternatives( + NmsItemStackTooltip18R1P.class + ); + + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static NmsItemStackTooltip i = d; + public static NmsItemStackTooltip get() { return i; } + + // -------------------------------------------- // + // TOOLTIP + // -------------------------------------------- // + + public String getNbtStringTooltip(ItemStack item) + { + throw notImplemented(); + } + +} diff --git a/src/com/massivecraft/massivecore/nms/NmsItemStackTooltip18R1P.java b/src/com/massivecraft/massivecore/nms/NmsItemStackTooltip18R1P.java new file mode 100644 index 00000000..a690df7a --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/NmsItemStackTooltip18R1P.java @@ -0,0 +1,81 @@ +package com.massivecraft.massivecore.nms; + +import java.lang.reflect.Method; + +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; + +import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType; +import com.massivecraft.massivecore.util.ReflectionUtil; + +public class NmsItemStackTooltip18R1P extends NmsItemStackTooltip +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static NmsItemStackTooltip18R1P i = new NmsItemStackTooltip18R1P(); + public static NmsItemStackTooltip18R1P get () { return i; } + + // -------------------------------------------- // + // FIELDS + // -------------------------------------------- // + + // org.bukkit.craftbukkit.inventory.CraftItemStack + private Class classCraftItemStack; + + // net.minecraft.server.ItemStack + private Class classNmsItemStack; + + // net.minecraft.serverNBTTagCompound + private Class classNmsNbtTagCompound; + + // org.bukkit.craftbukkit.inventory.CraftItemStack#asNmsCopy(net.minecraft.server.ItemStack) + private Method methodCraftItemStackAsNmsCopy; + + // net.minecraft.server.ItemStack#save(net.minecraft.serverNBTTagCompound) + private Method methodNmsItemStackSave; + + // -------------------------------------------- // + // PROVOKE + // -------------------------------------------- // + + @Override + public Class provoke() throws Throwable + { + // Demand 1.8 + // The rich chat system with clickables and tooltips were added in Minecraft 1.8. + // At Minecraft 1.7 the reflection in setup will succeed. + // The returned String is however an inferior and incompatible version. + return ArmorStand.class; + } + + // -------------------------------------------- // + // SETUP + // -------------------------------------------- // + + @Override + public void setup() throws Throwable + { + this.classCraftItemStack = PackageType.CRAFTBUKKIT_INVENTORY.getClass("CraftItemStack"); + this.classNmsItemStack = PackageType.MINECRAFT_SERVER.getClass("ItemStack"); + this.classNmsNbtTagCompound = PackageType.MINECRAFT_SERVER.getClass("NBTTagCompound"); + + this.methodCraftItemStackAsNmsCopy = ReflectionUtil.getMethod(this.classCraftItemStack, "asNMSCopy", ItemStack.class); + this.methodNmsItemStackSave = ReflectionUtil.getMethod(this.classNmsItemStack, "save", classNmsNbtTagCompound); + } + + // -------------------------------------------- // + // TOOLTIP + // -------------------------------------------- // + + @Override + public String getNbtStringTooltip(ItemStack item) + { + Object nmsItemStack = ReflectionUtil.invokeMethod(this.methodCraftItemStackAsNmsCopy, null, item); + Object nbtTagCompound = ReflectionUtil.newInstance(this.classNmsNbtTagCompound); + nbtTagCompound = ReflectionUtil.invokeMethod(this.methodNmsItemStackSave, nmsItemStack, nbtTagCompound); + return nbtTagCompound.toString(); + } + +} diff --git a/src/com/massivecraft/massivecore/nms/NmsPacket.java b/src/com/massivecraft/massivecore/nms/NmsPacket.java deleted file mode 100644 index e21eb0c4..00000000 --- a/src/com/massivecraft/massivecore/nms/NmsPacket.java +++ /dev/null @@ -1,253 +0,0 @@ -package com.massivecraft.massivecore.nms; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; - -import com.massivecraft.massivecore.util.Txt; -import org.bukkit.entity.Player; -import org.json.simple.JSONObject; - -import com.massivecraft.massivecore.MassiveCore; -import com.massivecraft.massivecore.particleeffect.ReflectionUtils; -import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType; - -public final class NmsPacket extends NmsAbstract -{ - // -------------------------------------------- // - // INSTANCE & CONSTRUCT - // -------------------------------------------- // - - private static NmsPacket i = new NmsPacket(); - public static NmsPacket get () { return i; } - - // -------------------------------------------- // - // FIELDS - // -------------------------------------------- // - - // The enums used to tell which packet it is. - // They correspond to the commands with the same name. - private static Class titleEnumClass; - private static Enum titleMainEnum; - private static Enum titleSubEnum; - private static Enum titleTimesEnum; - - // Method used to prepare text so it can be sent - private static Method chatSerializer; - // The object we send instead of a string - private static Class iChatBaseComponent; - - // The title packet and its constructor - private static Constructor titlePacketConstructor; - private static Constructor titlePacketConstructorTimes; - - // The chat packet and its constructors - private static Constructor chatPacketConstructor; - private static Constructor chatPacketActionbarConstructor; - - // -------------------------------------------- // - // OVERRIDE - // -------------------------------------------- // - - @Override - public int getRequiredVersion() - { - return 8; - } - - @Override - protected void setup() throws Throwable - { - NmsBasics.get().require(); - - // The enum used for titles - titleEnumClass = getTitleEnumClass(); - - // Get the title enum values. - for (Object o : titleEnumClass.getEnumConstants()) - { - Enum e = (Enum) o; - if (e.name().equalsIgnoreCase("TITLE")) titleMainEnum = e; - else if (e.name().equalsIgnoreCase("SUBTITLE")) titleSubEnum = e; - else if (e.name().equalsIgnoreCase("TIMES")) titleTimesEnum = e; - } - - // Get chatserializer and chat component. - iChatBaseComponent = PackageType.MINECRAFT_SERVER.getClass("IChatBaseComponent"); - - chatSerializer = getChatSerializer(); - - // Get title packet and it's constructor - Class titlePacketClass = PackageType.MINECRAFT_SERVER.getClass("PacketPlayOutTitle"); - titlePacketConstructor = ReflectionUtils.getConstructor(titlePacketClass, titleEnumClass, iChatBaseComponent); - titlePacketConstructorTimes = ReflectionUtils.getConstructor(titlePacketClass, titleEnumClass, iChatBaseComponent, Integer.class, Integer.class, Integer.class); - - // Get Chat packet and it's constructor - Class chatPacketClass = PackageType.MINECRAFT_SERVER.getClass("PacketPlayOutChat"); - chatPacketConstructor = ReflectionUtils.getConstructor(chatPacketClass, iChatBaseComponent); - chatPacketActionbarConstructor = ReflectionUtils.getConstructor(chatPacketClass, iChatBaseComponent, Byte.TYPE); - - // Set accessible - setAllAccessible(); - } - - public static Class getTitleEnumClass() throws ClassNotFoundException - { - Class ret; - try - { - ret = titleEnumClass = PackageType.MINECRAFT_SERVER.getClass("EnumTitleAction"); - } - catch (ClassNotFoundException e) - { - // Since 1.8.3 - ret = titleEnumClass = PackageType.MINECRAFT_SERVER.getClass("PacketPlayOutTitle$EnumTitleAction"); - } - - return ret; - } - - public static Method getChatSerializer() throws Exception - { - Method ret; - try - { - ret = chatSerializer = PackageType.MINECRAFT_SERVER.getClass("ChatSerializer").getDeclaredMethod("a", String.class); - } - catch (ClassNotFoundException e) - { - // Since 1.8.3 - ret = chatSerializer = PackageType.MINECRAFT_SERVER.getClass("IChatBaseComponent$ChatSerializer").getDeclaredMethod("a", String.class); - } - - return ret; - } - - public static void setAllAccessible() - { - chatSerializer.setAccessible(true); - titlePacketConstructor.setAccessible(true); - titlePacketConstructorTimes.setAccessible(true); - chatPacketConstructor.setAccessible(true); - } - - // -------------------------------------------- // - // SEND TITLES - // -------------------------------------------- // - - public static boolean sendTitle(Player player, int ticksIn, int ticksStay, int ticksOut, String titleMain, String titleSub) - { - if ( ! get().isAvailable()) return false; - - try - { - // Fadein, stay, fadeout - Object timesPacket = titlePacketConstructorTimes.newInstance(titleTimesEnum, null, ticksIn, ticksStay, ticksOut); - - NmsBasics.get().sendPacket(player, timesPacket); - - if (titleMain != null) - { - // Title - Object titleMainChat = toChatBaseComponent(titleMain); - Object titleMainPacket = titlePacketConstructor.newInstance(titleMainEnum, titleMainChat); - - NmsBasics.get().sendPacket(player, titleMainPacket); - } - - if (titleSub != null) - { - // SubTitle - Object titleSubChat = toChatBaseComponent(titleSub); - Object titleSubPacket = titlePacketConstructor.newInstance(titleSubEnum, titleSubChat); - - NmsBasics.get().sendPacket(player, titleSubPacket); - } - - } - catch (Exception ex) - { - MassiveCore.get().log(Txt.parse("Sending title failed!")); - ex.printStackTrace(); - // So we failed, didn't work. - return false; - } - - //It worked. - return true; - } - - // -------------------------------------------- // - // SEND RAW - // -------------------------------------------- // - - public static boolean sendRaw(Player player, String string) - { - if ( ! get().isAvailable()) return false; - - try - { - Object rawChat = toChatBaseComponent(string); - Object chatPacket = chatPacketConstructor.newInstance(rawChat); - - NmsBasics.get().sendPacket(player, chatPacket); - } - catch (Exception ex) - { - MassiveCore.get().log(Txt.parse("Sending raw chat failed!")); - ex.printStackTrace(); - // So we failed and it didn't work. - return false; - } - - return true; - } - - // -------------------------------------------- // - // SEND ACTIONBAR - // -------------------------------------------- // - - public static boolean sendActionbar(Player player, String string) - { - if ( ! get().isAvailable()) return false; - - try - { - Object actionbar = toChatBaseComponent(string); - Object chatPacket = chatPacketActionbarConstructor.newInstance(actionbar, (byte) 2); - - NmsBasics.get().sendPacket(player, chatPacket); - } - catch(Exception ex) - { - MassiveCore.get().log(Txt.parse("Sending actionbar failed!")); - ex.printStackTrace(); - // So we failed and it didn't work. - return false; - } - - return true; - } - - // -------------------------------------------- // - // UTIL - // -------------------------------------------- // - - public static Object toChatBaseComponent(String str) throws Exception - { - return chatSerializer.invoke(null, str); - } - - // -------------------------------------------- // - // JSON - // -------------------------------------------- // - - public static String toJson(String str) - { - str = JSONObject.escape(str); - - str = "{\"text\": \"" + str + "\"}"; - - return str; - } - -} diff --git a/src/com/massivecraft/massivecore/nms/NmsSkullMeta.java b/src/com/massivecraft/massivecore/nms/NmsSkullMeta.java new file mode 100644 index 00000000..4c6e24e0 --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/NmsSkullMeta.java @@ -0,0 +1,90 @@ +package com.massivecraft.massivecore.nms; + +import java.util.UUID; + +import org.bukkit.inventory.meta.SkullMeta; + +import com.massivecraft.massivecore.Couple; +import com.massivecraft.massivecore.mixin.Mixin; +import com.massivecraft.massivecore.util.IdData; +import com.massivecraft.massivecore.util.IdUtil; +import com.massivecraft.massivecore.util.MUtil; + +public class NmsSkullMeta extends Mixin +{ + // -------------------------------------------- // + // DEFAULT + // -------------------------------------------- // + + private static NmsSkullMeta d = new NmsSkullMeta().setAlternatives( + NmsSkullMeta18R1P.class, + NmsSkullMeta17R4.class, + NmsSkullMetaFallback.class + ); + + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static NmsSkullMeta i = d; + public static NmsSkullMeta get() { return i; } + + // -------------------------------------------- // + // RAW + // -------------------------------------------- // + + public String getName(SkullMeta meta) + { + // throw notImplemented(); + return meta.getOwner(); + // NOTE: This one is actually this simple. + // Bukkit does all the work for us. + } + + public UUID getId(SkullMeta meta) + { + throw notImplemented(); + } + + public void set(SkullMeta meta, String name, UUID id) + { + throw notImplemented(); + } + + // -------------------------------------------- // + // RESOLVE + // -------------------------------------------- // + // We resolve the locally best possible information using IdUtil. + + public Couple resolve(SkullMeta meta) + { + String name = this.getName(meta); + UUID id = this.getId(meta); + return this.resolve(name, id); + } + + public Couple resolve(String name, UUID id) + { + // Create Ret + // We default to the input. + String retName = name; + UUID retId = id; + + // Fetch IdData + // First by name then id. + IdData data = null; + if (name != null) data = IdUtil.getNameToData().get(name); + if (data == null && id != null) data = IdUtil.getIdToData().get(id.toString()); + + // Use that data if found + if (data != null) + { + retName = data.getName(); + retId = MUtil.asUuid(data.getId()); + } + + // Return Ret + return new Couple(retName, retId); + } + +} diff --git a/src/com/massivecraft/massivecore/nms/NmsSkullMeta17R4.java b/src/com/massivecraft/massivecore/nms/NmsSkullMeta17R4.java new file mode 100644 index 00000000..4099022b --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/NmsSkullMeta17R4.java @@ -0,0 +1,21 @@ +package com.massivecraft.massivecore.nms; + +public class NmsSkullMeta17R4 extends NmsSkullMetaAbstract +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static NmsSkullMeta17R4 i = new NmsSkullMeta17R4(); + public static NmsSkullMeta17R4 get () { return i; } + + // -------------------------------------------- // + // GAME PROFILE CLASS NAME + // -------------------------------------------- // + + public String getGameProfileClassName() + { + return "net.minecraft.util.com.mojang.authlib.GameProfile"; + } + +} diff --git a/src/com/massivecraft/massivecore/nms/NmsSkullMeta18R1P.java b/src/com/massivecraft/massivecore/nms/NmsSkullMeta18R1P.java new file mode 100644 index 00000000..345b5a4b --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/NmsSkullMeta18R1P.java @@ -0,0 +1,21 @@ +package com.massivecraft.massivecore.nms; + +public class NmsSkullMeta18R1P extends NmsSkullMetaAbstract +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static NmsSkullMeta18R1P i = new NmsSkullMeta18R1P(); + public static NmsSkullMeta18R1P get () { return i; } + + // -------------------------------------------- // + // GAME PROFILE CLASS NAME + // -------------------------------------------- // + + public String getGameProfileClassName() + { + return "com.mojang.authlib.GameProfile"; + } + +} diff --git a/src/com/massivecraft/massivecore/nms/NmsSkullMetaAbstract.java b/src/com/massivecraft/massivecore/nms/NmsSkullMetaAbstract.java new file mode 100644 index 00000000..9441b801 --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/NmsSkullMetaAbstract.java @@ -0,0 +1,115 @@ +package com.massivecraft.massivecore.nms; + +import java.lang.reflect.Field; +import java.util.UUID; + +import org.bukkit.inventory.meta.SkullMeta; + +import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType; +import com.massivecraft.massivecore.util.ReflectionUtil; + +public abstract class NmsSkullMetaAbstract extends NmsSkullMeta +{ + // -------------------------------------------- // + // FIELDS + // -------------------------------------------- // + + // org.bukkit.craftbukkit.inventory.CraftMetaSkull + public Class classCraftMetaSkull; + // org.bukkit.craftbukkit.inventory.CraftMetaSkull#profile + public Field fieldCraftMetaSkullProfile; + + // 17R4: net.minecraft.util.com.mojang.authlib.GameProfile + // 18R1P: com.mojang.authlib.GameProfile + public Class classGameProfile; + // ...#id + public Field fieldGameProfileId; + // ..#name + public Field fieldGameProfileName; + + // -------------------------------------------- // + // GAME PROFILE CLASS NAME + // -------------------------------------------- // + + public abstract String getGameProfileClassName(); + + // -------------------------------------------- // + // SETUP + // -------------------------------------------- // + + @Override + public void setup() throws Throwable + { + this.classCraftMetaSkull = PackageType.CRAFTBUKKIT_INVENTORY.getClass("CraftMetaSkull"); + this.fieldCraftMetaSkullProfile = ReflectionUtil.getField(this.classCraftMetaSkull, "profile"); + + this.classGameProfile = Class.forName(this.getGameProfileClassName()); + this.fieldGameProfileId = ReflectionUtil.getField(this.classGameProfile, "id"); + this.fieldGameProfileName = ReflectionUtil.getField(this.classGameProfile, "name"); + } + + // -------------------------------------------- // + // RAW + // -------------------------------------------- // + + @Override + public UUID getId(SkullMeta meta) + { + Object gameProfile = getGameProfile(meta); + if (gameProfile == null) return null; + return getGameProfileId(gameProfile); + } + + @Override + public void set(SkullMeta meta, String name, UUID id) + { + meta.setOwner(name != null ? name : "asdf"); + + Object gameProfile = getGameProfile(meta); + setGameProfileName(gameProfile, name); + setGameProfileId(gameProfile, id); + } + + // -------------------------------------------- // + // GAMEPROFILE + // -------------------------------------------- // + + protected T getGameProfile(SkullMeta meta) + { + return ReflectionUtil.getField(this.fieldCraftMetaSkullProfile, meta); + } + + protected void setGameProfile(SkullMeta meta, Object gameProfile) + { + ReflectionUtil.setField(this.fieldCraftMetaSkullProfile, meta, gameProfile); + } + + // -------------------------------------------- // + // GAMEPROFILE > GET + // -------------------------------------------- // + + protected String getGameProfileName(Object gameProfile) + { + return ReflectionUtil.getField(this.fieldGameProfileName, gameProfile); + } + + protected UUID getGameProfileId(Object gameProfile) + { + return ReflectionUtil.getField(this.fieldGameProfileId, gameProfile); + } + + // -------------------------------------------- // + // GAMEPROFILE > SET + // -------------------------------------------- // + + protected void setGameProfileName(Object gameProfile, String name) + { + ReflectionUtil.setField(this.fieldGameProfileName, gameProfile, name); + } + + protected void setGameProfileId(Object gameProfile, UUID id) + { + ReflectionUtil.setField(this.fieldGameProfileId, gameProfile, id); + } + +} diff --git a/src/com/massivecraft/massivecore/nms/NmsSkullMetaFallback.java b/src/com/massivecraft/massivecore/nms/NmsSkullMetaFallback.java new file mode 100644 index 00000000..7f4af55d --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/NmsSkullMetaFallback.java @@ -0,0 +1,32 @@ +package com.massivecraft.massivecore.nms; + +import java.util.UUID; + +import org.bukkit.inventory.meta.SkullMeta; + +public class NmsSkullMetaFallback extends NmsSkullMeta +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static NmsSkullMetaFallback i = new NmsSkullMetaFallback(); + public static NmsSkullMetaFallback get () { return i; } + + // -------------------------------------------- // + // RAW + // -------------------------------------------- // + + @Override + public UUID getId(SkullMeta meta) + { + return null; + } + + @Override + public void set(SkullMeta meta, String name, UUID id) + { + meta.setOwner(name); + } + +} diff --git a/src/com/massivecraft/massivecore/util/ReflectionUtil.java b/src/com/massivecraft/massivecore/util/ReflectionUtil.java index 82d92d2e..3b65e7f0 100644 --- a/src/com/massivecraft/massivecore/util/ReflectionUtil.java +++ b/src/com/massivecraft/massivecore/util/ReflectionUtil.java @@ -194,6 +194,23 @@ public class ReflectionUtil return (T) invokeConstructor(constructor, EMPTY_ARRAY_OF_OBJECT); } + // -------------------------------------------- // + // NEW INSTANCE + // -------------------------------------------- // + + @SuppressWarnings("unchecked") + public static T newInstance(Class clazz) + { + try + { + return (T) clazz.newInstance(); + } + catch (Exception e) + { + throw asRuntimeException(e); + } + } + // -------------------------------------------- // // SINGLETON INSTANCE // -------------------------------------------- //