MassiveCore - Mixin Stuff part 2

This commit is contained in:
Olof Larsson 2016-05-17 11:44:05 +02:00
parent 3f46a3bfac
commit 4301a8ff31
No known key found for this signature in database
GPG Key ID: BBEF14F97DA52474
24 changed files with 841 additions and 616 deletions

View File

@ -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,

View File

@ -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

View File

@ -32,8 +32,7 @@ public class WriterItemStackMeta extends WriterAbstractItemStackMetaMorph<Object
WriterItemStackMetaPotionEffects.class,
// SKULL
WriterItemStackMetaSkull17.class,
WriterItemStackMetaSkull18.class,
WriterItemStackMetaSkull.class,
// FIREWORK EFFECT
WriterItemStackMetaFireworkEffect.class,

View File

@ -7,17 +7,17 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import com.massivecraft.massivecore.Couple;
import com.massivecraft.massivecore.nms.NmsHead;
import com.massivecraft.massivecore.nms.NmsSkullMeta;
public class WriterItemStackMetaSkull18 extends WriterAbstractItemStackMetaField<SkullMeta, String, String>
public class WriterItemStackMetaSkull extends WriterAbstractItemStackMetaField<SkullMeta, String, String>
{
// -------------------------------------------- //
// 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<String, UUID> resolved = NmsHead.resolve(name, id);
NmsSkullMeta nms = NmsSkullMeta.get();
Couple<String, UUID> 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);
}
}

View File

@ -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<SkullMeta, String, String>
{
// -------------------------------------------- //
// 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);
}
}

View File

@ -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();
}
public boolean sendActionbarMsg(Object watcherObject, String message)
// -------------------------------------------- //
// SEND
// -------------------------------------------- //
public void sendActionbarRaw(Player player, String raw)
{
return this.sendActionbarMessage(watcherObject, Txt.parse(message));
NmsChat.get().sendActionbarRaw(player, raw);
}
public boolean sendActionbarMson(Object watcherObject, Mson mson)
public void 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);
NmsChat.get().sendActionbarMson(watcherObject, mson);
}
public boolean isActionbarAvailable()
public void sendActionbarMessage(Object watcherObject, String message)
{
return NmsPacket.get().isAvailable();
NmsChat.get().sendActionbarMessage(watcherObject, message);
}
public void sendActionbarMsg(Object watcherObject, String msg)
{
NmsChat.get().sendActionbarMsg(watcherObject, msg);
}
}

View File

@ -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
{

View File

@ -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);
}
}

View File

@ -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);
}
// -------------------------------------------- //

View File

@ -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;
}
}

View File

@ -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");
}
}

View File

@ -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");
}
}

View File

@ -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<ArmorStand> 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);
}
}

View File

@ -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<String, UUID> 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<String, UUID>(retName, retId);
}
public static Couple<String, UUID> resolve(SkullMeta meta)
{
return resolve(getName(meta), getId(meta));
}
}

View File

@ -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;
}
}
}

View File

@ -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();
}
}

View File

@ -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<ArmorStand> 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();
}
}

View File

@ -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("<b>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("<b>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("<b>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;
}
}

View File

@ -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<String, UUID> resolve(SkullMeta meta)
{
String name = this.getName(meta);
UUID id = this.getId(meta);
return this.resolve(name, id);
}
public Couple<String, UUID> 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<String, UUID>(retName, retId);
}
}

View File

@ -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";
}
}

View File

@ -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";
}
}

View File

@ -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> 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);
}
}

View File

@ -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);
}
}

View File

@ -194,6 +194,23 @@ public class ReflectionUtil
return (T) invokeConstructor(constructor, EMPTY_ARRAY_OF_OBJECT);
}
// -------------------------------------------- //
// NEW INSTANCE
// -------------------------------------------- //
@SuppressWarnings("unchecked")
public static <T> T newInstance(Class<?> clazz)
{
try
{
return (T) clazz.newInstance();
}
catch (Exception e)
{
throw asRuntimeException(e);
}
}
// -------------------------------------------- //
// SINGLETON INSTANCE
// -------------------------------------------- //