Mixin Improvement Step 1

This commit is contained in:
Olof Larsson 2016-05-16 11:36:34 +02:00
parent 053a54190a
commit 3f46a3bfac
No known key found for this signature in database
GPG Key ID: BBEF14F97DA52474
41 changed files with 886 additions and 693 deletions

View File

@ -70,12 +70,12 @@ public class Integration extends Engine
this.integrationActive = integrationActive;
String message = Txt.parse(integrationActive ? "<g>Activated Integration <h>%s" : "<b>Deactivated Integration <h>%s", this.getName());
String message = Txt.parse(integrationActive ? "<g>Integration Activated <h>%s" : "<b>Integration Deactivated <h>%s", this.getName());
this.getPlugin().log(message);
}
catch (Throwable t)
{
String message = Txt.parse(integrationActive ? "<b>Activating Integration <h>%s<b> FAILED:" : "<b>Deactivating Integration <h>%s<b> FAILED:", this.getName());
String message = Txt.parse(integrationActive ? "<b>Integration Activation <h>%s<b> FAILED:" : "<b>Integration Deactivation <h>%s<b> FAILED:", this.getName());
this.getPlugin().log(message);
t.printStackTrace();
}

View File

@ -84,7 +84,11 @@ import com.massivecraft.massivecore.mixin.MixinVisibility;
import com.massivecraft.massivecore.mixin.MixinWorld;
import com.massivecraft.massivecore.mson.Mson;
import com.massivecraft.massivecore.mson.MsonEvent;
import com.massivecraft.massivecore.nms.NmsItemStack;
import com.massivecraft.massivecore.nms.NmsBasics;
import com.massivecraft.massivecore.nms.NmsEntityGet;
import com.massivecraft.massivecore.nms.NmsItemStackCreate;
import com.massivecraft.massivecore.nms.NmsItemStackCreate17R4P;
import com.massivecraft.massivecore.nms.NmsPlayerInventoryCreate;
import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.ps.PSAdapter;
import com.massivecraft.massivecore.store.ModificationPollerLocal;
@ -187,7 +191,7 @@ public class MassiveCore extends MassivePlugin
// ItemStack
ret.registerTypeAdapter(ItemStack.class, AdapterItemStack.get());
Class<?> classCraftItemStack = NmsItemStack.get().classCraftItemStack;
Class<?> classCraftItemStack = NmsItemStackCreate17R4P.getClassCraftItemStackCatch();
if (classCraftItemStack != null) ret.registerTypeAdapter(classCraftItemStack, AdapterItemStack.get());
// Inventory
@ -246,6 +250,12 @@ public class MassiveCore extends MassivePlugin
MassiveCoreMConfColl.class,
MassiveCoreMSponsorInfoColl.class,
// Nms
NmsBasics.class,
NmsEntityGet.class,
NmsItemStackCreate.class,
NmsPlayerInventoryCreate.class,
// Writer,
WriterItemStack.class,
@ -308,13 +318,6 @@ public class MassiveCore extends MassivePlugin
// Delete Files (at once and additionally after all plugins loaded)
MassiveCoreTaskDeleteFiles.get().run();
Bukkit.getScheduler().scheduleSyncDelayedTask(this, MassiveCoreTaskDeleteFiles.get());
// TEST
//PickerTest.get().action();
//this.activate(
// PickerTest.class
//);
//PickerTest.get().action();
}
@Override

View File

@ -3,7 +3,7 @@ package com.massivecraft.massivecore.item;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import com.massivecraft.massivecore.nms.NmsItemStack;
import com.massivecraft.massivecore.nms.NmsItemStackCreate;
public abstract class WriterAbstractItemStack<OB, CB, FA, FB> extends WriterAbstract<DataItemStack, OB, DataItemStack, CB, FA, FB, ItemStack>
{
@ -47,7 +47,7 @@ public abstract class WriterAbstractItemStack<OB, CB, FA, FB> extends WriterAbst
public ItemStack createItemStack()
{
ItemStack ret = NmsItemStack.get().createItemStack();
ItemStack ret = NmsItemStackCreate.get().create();
ret.setType(this.getMaterial());
return ret;
}

View File

@ -0,0 +1,221 @@
package com.massivecraft.massivecore.mixin;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.collections.MassiveMap;
import com.massivecraft.massivecore.util.ReflectionUtil;
import com.massivecraft.massivecore.util.Txt;
public class Mixin extends Engine
{
// -------------------------------------------- //
// DEFAULT
// -------------------------------------------- //
// The default class contains the static fields.
// It should never be abstract and should always be compatible.
// A default class instance is set as the default value. This avoids null.
// It is detected by the required static field d.
private final Class<?> defaultClass = ReflectionUtil.getSuperclassDeclaringField(this.getClass(), true, "d");
public Class<?> getDefaultClass() { return this.defaultClass; }
private Mixin defaultInstance = null;
public Mixin getDefault()
{
if (this.defaultInstance == null) this.defaultInstance = ReflectionUtil.getField(this.getDefaultClass(), "d", null);
return this.defaultInstance;
}
public boolean isDefault() { return this == this.getDefault(); }
// -------------------------------------------- //
// INSTANCE
// -------------------------------------------- //
// Access the active static instance using instance methods.
// This looks a bit strange but will save us a lot of repetitive source code down the road.
// These are not meant to be used for selection or activation.
// The standard active interface methods are used for that.
public Mixin getInstance() { return ReflectionUtil.getField(this.getDefaultClass(), "i", null); }
public void setInstance(Mixin i) { ReflectionUtil.setField(this.getDefaultClass(), "i", null, i); }
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
// This is the base name.
// It should describe the function supplied.
// It should be set in the base class constructor.
private String baseName = this.getDefaultClass().getSimpleName();
public String getBaseName() { return this.baseName; }
public void setBaseName(String baseName) { this.baseName = baseName; }
// This is the instance specific name.
// It should describe the circumstances for compatibility.
// It could for example contain a version number.
private String name = this.createName();
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
// Is the Default counted as the Mixin being available?
// And based off that information are we available?
// NOTE: This field must be set in the default constructor!
private Boolean availableDefault = null;
public boolean isAvailableDefault() { return (this.availableDefault != null ? this.availableDefault : this.getDefault().getAlternatives().isEmpty()); }
public void setAvailableDefault(boolean availableDefault) { this.setAvailableDefault(availableDefault); }
public boolean isAvailable() { return this.isAvailableDefault() || this.getInstance() != this.getDefault(); }
public void require() { if (this.isAvailable()) return; throw new IllegalStateException(this.getBaseName() + " is Required"); }
// This is the list of alternatives to choose from.
// The first compatible alternative will be chosen for activation.
// The list should thus start with the most provoking and detailed alternative.
// If the list is empty we simply offer ourselves.
private List<Class<?>> alternatives = new MassiveList<>();
public List<Class<?>> getAlternatives() { return this.alternatives; }
@SuppressWarnings("unchecked")
public <T extends Mixin> T setAlternatives(List<Class<?>> alternatives) { this.alternatives = alternatives; return (T) this; }
public <T extends Mixin> T setAlternatives(Class<?>... alternatives) { return this.setAlternatives(Arrays.asList(alternatives)); }
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public Mixin()
{
// Setup
try
{
this.provoke();
this.setup();
}
catch (Throwable t)
{
throw ReflectionUtil.asRuntimeException(t);
}
}
// -------------------------------------------- //
// PROVOKE
// -------------------------------------------- //
// This method is run from the constructor.
// It may throw upon incompatibility.
// --> Returns an object for easier provoking.
public Object provoke() throws Throwable
{
return null;
}
// -------------------------------------------- //
// SETUP
// -------------------------------------------- //
// This method is run from the constructor.
// It may throw upon incompatibility.
// --> Does not return anything.
public void setup() throws Throwable
{
}
// -------------------------------------------- //
// ACTIVE
// -------------------------------------------- //
// We need to modify the active logic sightly.
//
// We make use of the standard engine isActive.
// That one looks at the engine registry and does not care about the instance.
// That behavior tends to work out well for us in this case.
//
// The reason for this is that the default will be set as the instance from the start.
// That does however not mean that it's active.
// It means it will be used to set the active which may or may not be itself.
@Override
public void setActive(boolean active)
{
// NoChange
if (this.isActive() == active) return;
// Before and After
Mixin before = this.getInstance();
Mixin after = (active ? ReflectionUtil.getSingletonInstanceFirstCombatible(this.getAlternatives(), this) : this.getDefault());
before.setPluginSoft(this.getPlugin());
after.setPluginSoft(this.getPlugin());
// Deactivate Before
if (before != this) before.setActive(false);
// Set Instance
this.setInstance(after);
// Activate After
if (after != this) after.setActive(true);
// This
if (after != this) return;
// Inform
String message = Txt.parse("<i>Mixin <h>%s<i> set to <h>%s", this.getBaseName(), this.getName());
after.getPlugin().log(message);
// Super
super.setActive(active);
}
// -------------------------------------------- //
// NOT IMPLEMENTED
// -------------------------------------------- //
public RuntimeException notImplemented()
{
return new UnsupportedOperationException("not implemented");
}
// -------------------------------------------- //
// CREATE NAME
// -------------------------------------------- //
private static final Map<String, String> NAME_MAP = new MassiveMap<>(
"", "Default",
"Fallback", "Fallback (Generic and Weaker)",
"17R4", "Minecraft 1.7.10 [1_7_R4]",
"17R4P", "Minecraft 1.7.10+ [1_7_R4+]",
"18R1", "Minecraft 1.8.0 --> 1.8.2 [1_8_R1]",
"18R1P", "Minecraft 1.8.0+ [1_8_R1+]",
"18R2", "Minecraft 1.8.3 [1_8_R2]",
"18R2P", "Minecraft 1.8.3+ [1_8_R2+]",
"18R3", "Minecraft 1.8.4 --> 1.8.9 [1_8_R3]",
"18R3P", "Minecraft 1.8.4+ [1_8_R3+]",
"19R1", "Minecraft 1.9.0 --> 1.9.3 [1_9_R1]",
"19R1P", "Minecraft 1.9.0+ [1_9_R1+]",
"19R2", "Minecraft 1.9.4 --> ? [1_9_R2]",
"19R2P", "Minecraft 1.9.4+ [1_9_R2+]"
);
public String createName()
{
// Create
String ret = this.getClass().getSimpleName();
// Tweak
String baseName = this.getBaseName();
if (ret.startsWith(baseName)) ret = ret.substring(baseName.length());
String name = NAME_MAP.get(ret);
if (name != null) ret = name;
// Return
return ret;
}
}

View File

@ -1,39 +0,0 @@
package com.massivecraft.massivecore.mixin;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.util.ReflectionUtil;
public class MixinAbstract extends Engine
{
// -------------------------------------------- //
// STATIC REFLECTION
// -------------------------------------------- //
private Class<?> clazz = ReflectionUtil.getSuperclassDeclaringField(this.getClass(), true, "d");
public MixinAbstract getDefault() { return ReflectionUtil.getField(this.clazz, "d", null); }
public MixinAbstract getInstance() { return ReflectionUtil.getField(this.clazz, "i", null); }
public void setInstance(MixinAbstract i) { ReflectionUtil.setField(this.clazz, "i", null, i); }
// -------------------------------------------- //
// ACTIVE
// -------------------------------------------- //
@Override
public boolean isActive()
{
return this.getInstance() == this;
}
@Override
public void setActive(boolean active)
{
this.setActiveMixin(active);
super.setActive(active);
}
public void setActiveMixin(boolean active)
{
this.setInstance(active ? this : this.getDefault());
}
}

View File

@ -6,7 +6,7 @@ import com.massivecraft.massivecore.nms.NmsPacket;
import com.massivecraft.massivecore.util.IdUtil;
import com.massivecraft.massivecore.util.Txt;
public class MixinActionbar extends MixinAbstract
public class MixinActionbar extends Mixin
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -15,7 +15,6 @@ public class MixinActionbar extends MixinAbstract
private static MixinActionbar d = new MixinActionbar();
private static MixinActionbar i = d;
public static MixinActionbar get() { return i; }
public static void set(MixinActionbar i) { MixinActionbar.i = i; }
// -------------------------------------------- //
// METHODS

View File

@ -4,7 +4,7 @@ import org.bukkit.event.player.PlayerJoinEvent;
import com.massivecraft.massivecore.event.EventMassiveCorePlayerLeave;
public class MixinActual extends MixinAbstract
public class MixinActual extends Mixin
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -13,7 +13,6 @@ public class MixinActual extends MixinAbstract
private static MixinActual d = new MixinActual();
private static MixinActual i = d;
public static MixinActual get() { return i; }
public static void set(MixinActual i) { MixinActual.i = i; }
// -------------------------------------------- //
// METHODS

View File

@ -4,7 +4,7 @@ import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.util.IdUtil;
public class MixinCommand extends MixinAbstract
public class MixinCommand extends Mixin
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -13,7 +13,6 @@ public class MixinCommand extends MixinAbstract
private static MixinCommand d = new MixinCommand();
private static MixinCommand i = d;
public static MixinCommand get() { return i; }
public static void set(MixinCommand i) { MixinCommand.i = i; }
// -------------------------------------------- //
// METHODS

View File

@ -5,7 +5,7 @@ import org.bukkit.entity.Player;
import com.massivecraft.massivecore.mson.Mson;
import com.massivecraft.massivecore.util.IdUtil;
public class MixinDisplayName extends MixinAbstract
public class MixinDisplayName extends Mixin
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -14,7 +14,6 @@ public class MixinDisplayName extends MixinAbstract
private static MixinDisplayName d = new MixinDisplayName();
private static MixinDisplayName i = d;
public static MixinDisplayName get() { return i; }
public static void set(MixinDisplayName i) { MixinDisplayName.i = i; }
// -------------------------------------------- //
// METHODS

View File

@ -5,7 +5,7 @@ import java.io.Serializable;
import org.bukkit.Bukkit;
import org.bukkit.event.Event;
public class MixinEvent extends MixinAbstract
public class MixinEvent extends Mixin
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -14,7 +14,6 @@ public class MixinEvent extends MixinAbstract
private static MixinEvent d = new MixinEvent();
private static MixinEvent i = d;
public static MixinEvent get() { return i; }
public static void set(MixinEvent i) { MixinEvent.i = i; }
// -------------------------------------------- //
// METHODS

View File

@ -5,7 +5,7 @@ import org.bukkit.entity.Player;
import com.massivecraft.massivecore.util.IdUtil;
public class MixinGamemode extends MixinAbstract
public class MixinGamemode extends Mixin
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -14,7 +14,6 @@ public class MixinGamemode extends MixinAbstract
private static MixinGamemode d = new MixinGamemode();
private static MixinGamemode i = d;
public static MixinGamemode get() { return i; }
public static void set(MixinGamemode i) { MixinGamemode.i = i; }
// -------------------------------------------- //
// METHODS

View File

@ -5,9 +5,9 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.PlayerInventory;
import com.massivecraft.massivecore.nms.NmsInventory;
import com.massivecraft.massivecore.nms.NmsPlayerInventoryCreate;
public class MixinInventory extends MixinAbstract
public class MixinInventory extends Mixin
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -16,7 +16,6 @@ public class MixinInventory extends MixinAbstract
private static MixinInventory d = new MixinInventory();
private static MixinInventory i = d;
public static MixinInventory get() { return i; }
public static void set(MixinInventory i) { MixinInventory.i = i; }
// -------------------------------------------- //
// METHODS
@ -24,7 +23,9 @@ public class MixinInventory extends MixinAbstract
public PlayerInventory createPlayerInventory()
{
return NmsInventory.createPlayerInventory();
NmsPlayerInventoryCreate nmsPlayerInventory = NmsPlayerInventoryCreate.get();
if ( ! nmsPlayerInventory.isAvailable()) return null;
return nmsPlayerInventory.create();
}
public Inventory createInventory(InventoryHolder holder, int size, String title)

View File

@ -4,7 +4,7 @@ import org.bukkit.entity.Player;
import com.massivecraft.massivecore.util.IdUtil;
public class MixinKick extends MixinAbstract
public class MixinKick extends Mixin
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -13,7 +13,6 @@ public class MixinKick extends MixinAbstract
private static MixinKick d = new MixinKick();
private static MixinKick i = d;
public static MixinKick get() { return i; }
public static void set(MixinKick i) { MixinKick.i = i; }
// -------------------------------------------- //
// METHODS

View File

@ -13,7 +13,7 @@ import com.massivecraft.massivecore.predicate.Predicate;
import com.massivecraft.massivecore.util.IdUtil;
import com.massivecraft.massivecore.util.Txt;
public class MixinMessage extends MixinAbstract
public class MixinMessage extends Mixin
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -22,7 +22,6 @@ public class MixinMessage extends MixinAbstract
private static MixinMessage d = new MixinMessage();
private static MixinMessage i = d;
public static MixinMessage get() { return i; }
public static void set(MixinMessage i) { MixinMessage.i = i; }
// -------------------------------------------- //
// MSG > ALL

View File

@ -3,7 +3,7 @@ package com.massivecraft.massivecore.mixin;
import com.massivecraft.massivecore.store.Coll;
import com.massivecraft.massivecore.store.Entity;
public class MixinModification extends MixinAbstract
public class MixinModification extends Mixin
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -12,7 +12,6 @@ public class MixinModification extends MixinAbstract
private static MixinModification d = new MixinModification();
private static MixinModification i = d;
public static MixinModification get() { return i; }
public static void set(MixinModification i) { MixinModification.i = i; }
// -------------------------------------------- //
// METHODS

View File

@ -9,7 +9,7 @@ import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.util.IdUtil;
import com.massivecraft.massivecore.util.MUtil;
public class MixinPlayed extends MixinAbstract
public class MixinPlayed extends Mixin
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -18,7 +18,6 @@ public class MixinPlayed extends MixinAbstract
private static MixinPlayed d = new MixinPlayed();
private static MixinPlayed i = d;
public static MixinPlayed get() { return i; }
public static void set(MixinPlayed i) { MixinPlayed.i = i; }
// -------------------------------------------- //
// METHODS

View File

@ -5,7 +5,7 @@ import org.bukkit.entity.Player;
import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.util.IdUtil;
public class MixinSenderPs extends MixinAbstract
public class MixinSenderPs extends Mixin
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -14,7 +14,6 @@ public class MixinSenderPs extends MixinAbstract
private static MixinSenderPs d = new MixinSenderPs();
private static MixinSenderPs i = d;
public static MixinSenderPs get() { return i; }
public static void set(MixinSenderPs i) { MixinSenderPs.i = i; }
// -------------------------------------------- //
// METHODS

View File

@ -16,7 +16,7 @@ import com.massivecraft.massivecore.teleport.ScheduledTeleport;
import com.massivecraft.massivecore.util.IdUtil;
import com.massivecraft.massivecore.util.Txt;
public class MixinTeleport extends MixinAbstract
public class MixinTeleport extends Mixin
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -25,7 +25,6 @@ public class MixinTeleport extends MixinAbstract
private static MixinTeleport d = new MixinTeleport();
private static MixinTeleport i = d;
public static MixinTeleport get() { return i; }
public static void set(MixinTeleport i) { MixinTeleport.i = i; }
// -------------------------------------------- //
// METHODS

View File

@ -6,7 +6,7 @@ import com.massivecraft.massivecore.nms.NmsPacket;
import com.massivecraft.massivecore.util.IdUtil;
import com.massivecraft.massivecore.util.Txt;
public class MixinTitle extends MixinAbstract
public class MixinTitle extends Mixin
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -15,7 +15,6 @@ public class MixinTitle extends MixinAbstract
private static MixinTitle d = new MixinTitle();
private static MixinTitle i = d;
public static MixinTitle get() { return i; }
public static void set(MixinTitle i) { MixinTitle.i = i; }
// -------------------------------------------- //
// METHODS

View File

@ -4,7 +4,7 @@ import org.bukkit.entity.Player;
import com.massivecraft.massivecore.util.IdUtil;
import com.massivecraft.massivecore.util.MUtil;
public class MixinVisibility extends MixinAbstract
public class MixinVisibility extends Mixin
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -13,7 +13,6 @@ public class MixinVisibility extends MixinAbstract
private static MixinVisibility d = new MixinVisibility();
private static MixinVisibility i = d;
public static MixinVisibility get() { return i; }
public static void set(MixinVisibility i) { MixinVisibility.i = i; }
// -------------------------------------------- //
// METHODS

View File

@ -14,7 +14,7 @@ import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.ps.PSFormatDesc;
import com.massivecraft.massivecore.util.MUtil;
public class MixinWorld extends MixinAbstract
public class MixinWorld extends Mixin
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -23,7 +23,6 @@ public class MixinWorld extends MixinAbstract
private static MixinWorld d = new MixinWorld();
private static MixinWorld i = d;
public static MixinWorld get() { return i; }
public static void set(MixinWorld i) { MixinWorld.i = i; }
// -------------------------------------------- //
// METHODS

View File

@ -0,0 +1,75 @@
package com.massivecraft.massivecore.nms;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.Team;
import com.massivecraft.massivecore.mixin.Mixin;
public class NmsBasics extends Mixin
{
// -------------------------------------------- //
// DEFAULT
// -------------------------------------------- //
private static NmsBasics d = new NmsBasics().setAlternatives(
NmsBasics17R4P.class
);
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static NmsBasics i = d;
public static NmsBasics get() { return i; }
// -------------------------------------------- //
// GET HANDLE
// -------------------------------------------- //
public <T> T getHandle(Entity entity)
{
throw this.notImplemented();
}
public <T> T getHandle(World world)
{
throw this.notImplemented();
}
public <T> T getHandle(Team team)
{
throw this.notImplemented();
}
// -------------------------------------------- //
// GET BUKKIT
// -------------------------------------------- //
public <T extends Entity> T getBukkit(Object handle)
{
throw this.notImplemented();
}
// -------------------------------------------- //
// CONNECTION & PACKET
// -------------------------------------------- //
public <T> T getConnection(Player player)
{
throw this.notImplemented();
}
public void sendPacket(Player player, Object packet)
{
Object connection = this.getConnection(player);
this.sendPacket(connection, packet);
}
public void sendPacket(Object connection, Object packet)
{
throw this.notImplemented();
}
}

View File

@ -0,0 +1,143 @@
package com.massivecraft.massivecore.nms;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.Team;
import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType;
import com.massivecraft.massivecore.util.ReflectionUtil;
public class NmsBasics17R4P extends NmsBasics
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static NmsBasics17R4P i = new NmsBasics17R4P();
public static NmsBasics17R4P get() { return i; }
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
// GET HANDLE
// org.bukkit.craftbukkit.entity.CraftEntity
private Class<?> classCraftEntity;
// org.bukkit.craftbukkit.entity.Entity#getHandle()
private Method methodCraftEntityGetHandle;
// org.bukkit.craftbukkit.CraftWorld
public Class<?> classCraftWorld;
// org.bukkit.craftbukkit.CraftWorld#world
public Field fieldCraftWorldWorld;
// org.bukkit.craftbukkit.scoreboard.CraftTeam
private Class<?> classCraftTeam;
// org.bukkit.craftbukkit.scoreboard.CraftTeam#team
private Field fieldCraftTeamHandle;
// GET BUKKIT
// net.minecraft.server.Entity
private Class<?> classNmsEntity;
// net.minecraft.server.Entity#getBukkitEntity()
private Method methodNmsEntityGetBukkitEntity;
// CONNECTION & PACKET
// net.minecraft.server.EntityPlayer
private Class<?> classNmsPlayer;
// net.minecraft.server.EntityPlayer#playerConnection
private Field fieldNmsPlayerPlayerConnection;
// net.minecraft.server.Packet
private Class<?> classNmsPacket;
// net.minecraft.server.PlayerConnection
private Class<?> classNmsPlayerConnection;
// net.minecraft.server.PlayerConnection#sendPacket(Packet)
private Method methodPlayerConnectionsendPacket;
// -------------------------------------------- //
// SETUP
// -------------------------------------------- //
@Override
public void setup() throws Throwable
{
// GET HANDLE
this.classCraftEntity = PackageType.CRAFTBUKKIT_ENTITY.getClass("CraftEntity");
this.methodCraftEntityGetHandle = ReflectionUtil.getMethod(this.classCraftEntity, "getHandle");
this.classCraftWorld = PackageType.CRAFTBUKKIT.getClass("CraftWorld");
this.fieldCraftWorldWorld = ReflectionUtil.getField(this.classCraftWorld, "world");
this.classCraftTeam = PackageType.CRAFTBUKKIT_SCOREBOARD.getClass("CraftTeam");
this.fieldCraftTeamHandle = ReflectionUtil.getField(this.classCraftTeam, "team");
// GET BUKKIT
this.classNmsEntity = PackageType.MINECRAFT_SERVER.getClass("Entity");
this.methodNmsEntityGetBukkitEntity = ReflectionUtil.getMethod(this.classNmsEntity, "getBukkitEntity");
// CONNECTION & PACKET
this.classNmsPlayer = PackageType.MINECRAFT_SERVER.getClass("EntityPlayer");
this.fieldNmsPlayerPlayerConnection = ReflectionUtil.getField(this.classNmsPlayer, "playerConnection");
this.classNmsPacket = PackageType.MINECRAFT_SERVER.getClass("Packet");
this.classNmsPlayerConnection = PackageType.MINECRAFT_SERVER.getClass("PlayerConnection");
this.methodPlayerConnectionsendPacket = ReflectionUtil.getMethod(this.classNmsPlayerConnection, "sendPacket", this.classNmsPacket);
}
// -------------------------------------------- //
// GET HANDLE
// -------------------------------------------- //
@Override
public <T> T getHandle(Entity entity)
{
return ReflectionUtil.invokeMethod(this.methodCraftEntityGetHandle, entity);
}
@Override
public <T> T getHandle(World world)
{
return ReflectionUtil.getField(this.fieldCraftWorldWorld, world);
}
@Override
public <T> T getHandle(Team team)
{
return ReflectionUtil.getField(this.fieldCraftTeamHandle, team);
}
// -------------------------------------------- //
// GET BUKKIT
// -------------------------------------------- //
@Override
public <T extends Entity> T getBukkit(Object handle)
{
return ReflectionUtil.invokeMethod(this.methodNmsEntityGetBukkitEntity, handle);
}
// -------------------------------------------- //
// CONNECTION & PACKET
// -------------------------------------------- //
@Override
public <T> T getConnection(Player player)
{
Object handle = this.getHandle(player);
return ReflectionUtil.getField(this.fieldNmsPlayerPlayerConnection, handle);
}
@Override
public void sendPacket(Object connection, Object packet)
{
ReflectionUtil.invokeMethod(this.methodPlayerConnectionsendPacket, connection, packet);
}
}

View File

@ -26,12 +26,6 @@ public class NmsBoard extends NmsAbstract
// FIELDS
// -------------------------------------------- //
// org.bukkit.craftbukkit.scoreboard.CraftTeam
private Class<?> classCraftTeam;
// org.bukkit.craftbukkit.scoreboard.CraftTeam#team
private Field fieldCraftTeamHandle;
// net.minecraft.server.ScoreboardTeam
private Class<?> classNmsTeam;
@ -66,8 +60,8 @@ public class NmsBoard extends NmsAbstract
@Override
protected void setup() throws Throwable
{
this.classCraftTeam = PackageType.CRAFTBUKKIT_SCOREBOARD.getClass("CraftTeam");
this.fieldCraftTeamHandle = ReflectionUtil.getField(this.classCraftTeam, "team");
// TODO: Move to provoke?
NmsBasics.get().require();
this.classNmsTeam = PackageType.MINECRAFT_SERVER.getClass("ScoreboardTeam");
this.fieldNmsTeamColor = ReflectionUtil.getField(this.classNmsTeam, "k");
@ -88,7 +82,7 @@ public class NmsBoard extends NmsAbstract
{
if ( ! this.isAvailable()) return null;
Object nmsTeam = getTeamHandle(team);
Object nmsTeam = NmsBasics.get().getHandle(team);
Object nmsColor = ReflectionUtil.getField(this.fieldNmsTeamColor, nmsTeam);
return convertColor(nmsColor);
@ -98,7 +92,7 @@ public class NmsBoard extends NmsAbstract
{
if ( ! this.isAvailable()) return;
Object nmsTeam = getTeamHandle(team);
Object nmsTeam = NmsBasics.get().getHandle(team);
Object nmsColor = convertColor(color);
ReflectionUtil.setField(this.fieldNmsTeamColor, nmsTeam, nmsColor);
@ -107,15 +101,6 @@ public class NmsBoard extends NmsAbstract
team.setDisplayName(team.getDisplayName());
}
// -------------------------------------------- //
// TEAM
// -------------------------------------------- //
public <T> T getTeamHandle(Team team)
{
return ReflectionUtil.getField(this.fieldCraftTeamHandle, team);
}
// -------------------------------------------- //
// PACKET
// -------------------------------------------- //
@ -126,14 +111,14 @@ public class NmsBoard extends NmsAbstract
public <T> T createTeamUpdatePacket(Team team)
{
Object handle = getTeamHandle(team);
Object handle = NmsBasics.get().getHandle(team);
return ReflectionUtil.invokeConstructor(this.constructorPacketTeamUpdate, handle, PACKET_UPDATE_MODE);
}
public void sendTeamUpdatePacket(Team team, Player player)
{
Object packet = this.createTeamUpdatePacket(team);
NmsPacket.sendPacket(player, packet);
NmsBasics.get().sendPacket(player, packet);
}
// -------------------------------------------- //

View File

@ -1,145 +0,0 @@
package com.massivecraft.massivecore.nms;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.UUID;
import java.util.WeakHashMap;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType;
import com.massivecraft.massivecore.util.ReflectionUtil;
public class NmsEntity extends NmsAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static NmsEntity i = new NmsEntity();
public static NmsEntity get () { return i; }
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
// org.bukkit.craftbukkit.CraftWorld#world
public static Class<?> classCraftWorld;
public static Field fieldCraftWorldDotWorld;
// net.minecraft.server.WorldServer#entitiesByUUID
public static Class<?> classWorldServer;
public static Field fieldWorldServerDotEntitiesByUUID;
// net.minecraft.server.Entity#getBukkitEntity()
public static Class<?> classEntity;
public static Method methodEntityDotGetBukkitEntity;
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
// NOTE: This has been properly researched.
// NOTE: The field "WorldServer.entitiesByUUID" was added in 1.8.
@Override
public int getRequiredVersion()
{
return 8;
}
@Override
protected void setup() throws Throwable
{
classCraftWorld = PackageType.CRAFTBUKKIT.getClass("CraftWorld");
fieldCraftWorldDotWorld = ReflectionUtil.getField(classCraftWorld, "world");
classWorldServer = PackageType.MINECRAFT_SERVER.getClass("WorldServer");
fieldWorldServerDotEntitiesByUUID = ReflectionUtil.getField(classWorldServer, "entitiesByUUID");
classEntity = PackageType.MINECRAFT_SERVER.getClass("Entity");
methodEntityDotGetBukkitEntity = ReflectionUtil.getMethod(classEntity, "getBukkitEntity");
}
// -------------------------------------------- //
// REFLECTION METHODS > WORLD MAP
// -------------------------------------------- //
public Object getNmsWorld(World world)
{
if (world == null) throw new NullPointerException("world");
return ReflectionUtil.getField(fieldCraftWorldDotWorld, world);
}
public Map<UUID, Object> getNmsWorldMap(Object nmsWorld)
{
if (nmsWorld == null) throw new NullPointerException("nmsWorld");
return ReflectionUtil.getField(fieldWorldServerDotEntitiesByUUID, nmsWorld);
}
// -------------------------------------------- //
// REFLECTION METHODS > ENTITY
// -------------------------------------------- //
public Entity getBukkitEntity(Object nmsEntity)
{
if (nmsEntity == null) throw new NullPointerException("nmsEntity");
return ReflectionUtil.invokeMethod(methodEntityDotGetBukkitEntity, nmsEntity);
}
// -------------------------------------------- //
// WORLD MAP
// -------------------------------------------- //
protected Map<World, Map<UUID, Object>> worldMaps = new WeakHashMap<World, Map<UUID, Object>>();
public Map<UUID, Object> getWorldMap(World world)
{
if (world == null) throw new NullPointerException("world");
Map<UUID, Object> ret = this.worldMaps.get(world);
if (ret == null)
{
Object nmsWorld = this.getNmsWorld(world);
ret = this.getNmsWorldMap(nmsWorld);
this.worldMaps.put(world, ret);
}
return ret;
}
// -------------------------------------------- //
// GET ENTITY
// -------------------------------------------- //
public Entity getEntity(World world, UUID uuid)
{
if (world == null) throw new NullPointerException("world");
if (uuid == null) return null;
Map<UUID, Object> worldMap = this.getWorldMap(world);
Object nmsEntity = worldMap.get(uuid);
if (nmsEntity == null) return null;
return this.getBukkitEntity(nmsEntity);
}
public Entity getEntity(UUID uuid)
{
if (uuid == null) return null;
for (World world : Bukkit.getWorlds())
{
Entity ret = this.getEntity(world, uuid);
if (ret != null) return ret;
}
return null;
}
}

View File

@ -0,0 +1,41 @@
package com.massivecraft.massivecore.nms;
import java.util.UUID;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import com.massivecraft.massivecore.mixin.Mixin;
public class NmsEntityGet extends Mixin
{
// -------------------------------------------- //
// DEFAULT
// -------------------------------------------- //
private static NmsEntityGet d = new NmsEntityGet().setAlternatives(
NmsEntityGet18R1P.class,
NmsEntityGetFallback.class
);
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static NmsEntityGet i = d;
public static NmsEntityGet get() { return i; }
// -------------------------------------------- //
// GET ENTITY
// -------------------------------------------- //
public Entity getEntity(UUID uuid)
{
throw notImplemented();
}
public Entity getEntity(World world, UUID uuid)
{
throw notImplemented();
}
}

View File

@ -0,0 +1,108 @@
package com.massivecraft.massivecore.nms;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.UUID;
import java.util.WeakHashMap;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType;
import com.massivecraft.massivecore.util.ReflectionUtil;
public class NmsEntityGet18R1P extends NmsEntityGet
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static NmsEntityGet18R1P i = new NmsEntityGet18R1P();
public static NmsEntityGet18R1P get () { return i; }
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
// net.minecraft.server.WorldServer
private Class<?> classNmsWorldServer;
// net.minecraft.server.WorldServer#entitiesByUUID
private Field fieldNmsWorldServerEntitiesByUuid;
// -------------------------------------------- //
// SETUP
// -------------------------------------------- //
@Override
public void setup() throws Throwable
{
NmsBasics.get().require();
this.classNmsWorldServer = PackageType.MINECRAFT_SERVER.getClass("WorldServer");
this.fieldNmsWorldServerEntitiesByUuid = ReflectionUtil.getField(this.classNmsWorldServer, "entitiesByUUID");
}
// -------------------------------------------- //
// GET ENTITY
// -------------------------------------------- //
@Override
public Entity getEntity(UUID uuid)
{
if (uuid == null) return null;
for (World world : Bukkit.getWorlds())
{
Entity ret = this.getEntity(world, uuid);
if (ret != null) return ret;
}
return null;
}
@Override
public Entity getEntity(World world, UUID uuid)
{
if (world == null) throw new NullPointerException("world");
if (uuid == null) return null;
Map<UUID, Object> worldMap = this.getWorldMap(world);
Object nmsEntity = worldMap.get(uuid);
if (nmsEntity == null) return null;
return NmsBasics.get().getBukkit(nmsEntity);
}
// -------------------------------------------- //
// INTERNAL
// -------------------------------------------- //
private Map<World, Map<UUID, Object>> worldMaps = new WeakHashMap<World, Map<UUID, Object>>();
private Map<UUID, Object> getWorldMap(Object handle)
{
if (handle == null) throw new NullPointerException("handle");
return ReflectionUtil.getField(this.fieldNmsWorldServerEntitiesByUuid, handle);
}
private Map<UUID, Object> getWorldMap(World world)
{
if (world == null) throw new NullPointerException("world");
Map<UUID, Object> ret = this.worldMaps.get(world);
if (ret == null)
{
Object handle = NmsBasics.get().getHandle(world);
ret = this.getWorldMap(handle);
this.worldMaps.put(world, ret);
}
return ret;
}
}

View File

@ -0,0 +1,50 @@
package com.massivecraft.massivecore.nms;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Entity;
public class NmsEntityGetFallback extends NmsEntityGet
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static NmsEntityGetFallback i = new NmsEntityGetFallback();
public static NmsEntityGetFallback get () { return i; }
// -------------------------------------------- //
// GET ENTITY
// -------------------------------------------- //
@Override
public Entity getEntity(UUID uuid)
{
if (uuid == null) return null;
for (World world : Bukkit.getWorlds())
{
Entity ret = this.getEntity(world, uuid);
if (ret != null) return ret;
}
return null;
}
@Override
public Entity getEntity(World world, UUID uuid)
{
if (world == null) throw new NullPointerException("world");
if (uuid == null) return null;
for (Entity entity : world.getEntities())
{
if (entity.getUniqueId().equals(uuid)) return entity;
}
return null;
}
}

View File

@ -1,63 +0,0 @@
package com.massivecraft.massivecore.nms;
import java.lang.reflect.Constructor;
import org.bukkit.inventory.PlayerInventory;
import com.massivecraft.massivecore.particleeffect.ReflectionUtils;
public class NmsInventory extends NmsAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static NmsInventory i = new NmsInventory();
public static NmsInventory get () { return i; }
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
private static Class<?> playerInventoryClass;
private static Class<?> entityHumanClass;
private static Constructor<?> playerInventoryConstructor;
private static Class<?> craftInventoryPlayerClass;
private static Constructor<?> craftInventoryPlayerConstructor;
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
protected void setup() throws Throwable
{
playerInventoryClass = ReflectionUtils.PackageType.MINECRAFT_SERVER.getClass("PlayerInventory");
entityHumanClass = ReflectionUtils.PackageType.MINECRAFT_SERVER.getClass("EntityHuman");
playerInventoryConstructor = ReflectionUtils.getConstructor(playerInventoryClass, entityHumanClass);
craftInventoryPlayerClass = ReflectionUtils.PackageType.CRAFTBUKKIT_INVENTORY.getClass("CraftInventoryPlayer");
craftInventoryPlayerConstructor = ReflectionUtils.getConstructor(craftInventoryPlayerClass, playerInventoryClass);
}
// -------------------------------------------- //
// CREATE PLAYERINVENTORY
// -------------------------------------------- //
public static PlayerInventory createPlayerInventory()
{
if ( ! get().isAvailable()) return null;
try
{
Object playerInventory = playerInventoryConstructor.newInstance(new Object[]{null});
Object craftInventoryPlayer = craftInventoryPlayerConstructor.newInstance(playerInventory);
return (PlayerInventory)craftInventoryPlayer;
}
catch (Exception e)
{
e.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 NmsItemStackCreate extends Mixin
{
// -------------------------------------------- //
// DEFAULT
// -------------------------------------------- //
private static NmsItemStackCreate d = new NmsItemStackCreate().setAlternatives(
NmsItemStackCreate17R4P.class,
NmsItemStackCreateFallback.class
);
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static NmsItemStackCreate i = d;
public static NmsItemStackCreate get() { return i; }
// -------------------------------------------- //
// CREATE
// -------------------------------------------- //
public ItemStack create()
{
throw notImplemented();
}
}

View File

@ -6,70 +6,69 @@ import org.bukkit.inventory.ItemStack;
import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType;
import com.massivecraft.massivecore.util.ReflectionUtil;
public class NmsItemStack extends NmsAbstract
public class NmsItemStackCreate17R4P extends NmsItemStackCreate
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static NmsItemStack i = new NmsItemStack();
public static NmsItemStack get () { return i; }
private static NmsItemStackCreate17R4P i = new NmsItemStackCreate17R4P();
public static NmsItemStackCreate17R4P get () { return i; }
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
// net.minecraft.server.ItemStack
public Class<?> classNmsItemStack;
private Class<?> classNmsItemStack;
// org.bukkit.craftbukkit.inventory.CraftItemStack
public Class<?> classCraftItemStack;
private Class<?> classCraftItemStack;
// org.bukkit.craftbukkit.inventory.CraftItemStack(net.minecraft.server.ItemStack)
public Constructor<?> constructorCraftItemStack;
private Constructor<?> constructorCraftItemStack;
// -------------------------------------------- //
// OVERRIDE
// SETUP
// -------------------------------------------- //
// NOTE: This has been properly researched.
// NOTE: The constructor have been the same for quite some time!
@Override
public int getRequiredVersion()
public void setup() throws Throwable
{
return 6;
}
@Override
protected void setup() throws Throwable
{
this.classNmsItemStack = PackageType.MINECRAFT_SERVER.getClass("ItemStack");
this.classNmsItemStack = getClassCraftItemStack();
this.classCraftItemStack = PackageType.CRAFTBUKKIT_INVENTORY.getClass("CraftItemStack");
this.constructorCraftItemStack = ReflectionUtil.getConstructor(this.classCraftItemStack, this.classNmsItemStack);
}
// -------------------------------------------- //
// METHOD
// CREATE
// -------------------------------------------- //
@SuppressWarnings("deprecation")
public ItemStack createItemStack()
@Override
public ItemStack create()
{
// Create
ItemStack ret = null;
// Fill
if (this.isAvailable())
{
ret = ReflectionUtil.invokeConstructor(this.constructorCraftItemStack, (Object)null);
}
else
{
ret = new ItemStack(0);
return ReflectionUtil.invokeConstructor(this.constructorCraftItemStack, (Object)null);
}
// Return
return ret;
// -------------------------------------------- //
// UTIL
// -------------------------------------------- //
public static Class<?> getClassCraftItemStack() throws ClassNotFoundException
{
return PackageType.MINECRAFT_SERVER.getClass("ItemStack");
}
public static Class<?> getClassCraftItemStackCatch()
{
try
{
return getClassCraftItemStack();
}
catch (Throwable t)
{
return null;
}
}
}

View File

@ -0,0 +1,25 @@
package com.massivecraft.massivecore.nms;
import org.bukkit.inventory.ItemStack;
public class NmsItemStackCreateFallback extends NmsItemStackCreate
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static NmsItemStackCreateFallback i = new NmsItemStackCreateFallback();
public static NmsItemStackCreateFallback get () { return i; }
// -------------------------------------------- //
// CREATE
// -------------------------------------------- //
@SuppressWarnings("deprecation")
@Override
public ItemStack create()
{
return new ItemStack(0);
}
}

View File

@ -1,10 +1,8 @@
package com.massivecraft.massivecore.nms;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.massivecraft.massivecore.util.ReflectionUtil;
import com.massivecraft.massivecore.util.Txt;
import org.bukkit.entity.Player;
import org.json.simple.JSONObject;
@ -38,11 +36,6 @@ public final class NmsPacket extends NmsAbstract
// The object we send instead of a string
private static Class<?> iChatBaseComponent;
// Handling the players conenction
private static Method getHandle;
private static Field playerConnection;
private static Method sendPacket;
// The title packet and its constructor
private static Constructor<?> titlePacketConstructor;
private static Constructor<?> titlePacketConstructorTimes;
@ -64,6 +57,8 @@ public final class NmsPacket extends NmsAbstract
@Override
protected void setup() throws Throwable
{
NmsBasics.get().require();
// The enum used for titles
titleEnumClass = getTitleEnumClass();
@ -91,11 +86,6 @@ public final class NmsPacket extends NmsAbstract
chatPacketConstructor = ReflectionUtils.getConstructor(chatPacketClass, iChatBaseComponent);
chatPacketActionbarConstructor = ReflectionUtils.getConstructor(chatPacketClass, iChatBaseComponent, Byte.TYPE);
// Player connection
getHandle = ReflectionUtils.getMethod("CraftPlayer", PackageType.CRAFTBUKKIT_ENTITY, "getHandle");
playerConnection = ReflectionUtils.getField("EntityPlayer", PackageType.MINECRAFT_SERVER, false, "playerConnection");
sendPacket = ReflectionUtils.getMethod(playerConnection.getType(), "sendPacket", PackageType.MINECRAFT_SERVER.getClass("Packet"));
// Set accessible
setAllAccessible();
}
@ -138,9 +128,6 @@ public final class NmsPacket extends NmsAbstract
titlePacketConstructor.setAccessible(true);
titlePacketConstructorTimes.setAccessible(true);
chatPacketConstructor.setAccessible(true);
getHandle.setAccessible(true);
playerConnection.setAccessible(true);
sendPacket.setAccessible(true);
}
// -------------------------------------------- //
@ -155,15 +142,16 @@ public final class NmsPacket extends NmsAbstract
{
// Fadein, stay, fadeout
Object timesPacket = titlePacketConstructorTimes.newInstance(titleTimesEnum, null, ticksIn, ticksStay, ticksOut);
sendPacket(player, timesPacket);
NmsBasics.get().sendPacket(player, timesPacket);
if (titleMain != null)
{
// Title
Object titleMainChat = toChatBaseComponent(titleMain);
Object titleMainPacket = titlePacketConstructor.newInstance(titleMainEnum, titleMainChat);
sendPacket(player, titleMainPacket);
NmsBasics.get().sendPacket(player, titleMainPacket);
}
if (titleSub != null)
@ -171,7 +159,8 @@ public final class NmsPacket extends NmsAbstract
// SubTitle
Object titleSubChat = toChatBaseComponent(titleSub);
Object titleSubPacket = titlePacketConstructor.newInstance(titleSubEnum, titleSubChat);
sendPacket(player, titleSubPacket);
NmsBasics.get().sendPacket(player, titleSubPacket);
}
}
@ -200,7 +189,7 @@ public final class NmsPacket extends NmsAbstract
Object rawChat = toChatBaseComponent(string);
Object chatPacket = chatPacketConstructor.newInstance(rawChat);
sendPacket(player, chatPacket);
NmsBasics.get().sendPacket(player, chatPacket);
}
catch (Exception ex)
{
@ -226,7 +215,7 @@ public final class NmsPacket extends NmsAbstract
Object actionbar = toChatBaseComponent(string);
Object chatPacket = chatPacketActionbarConstructor.newInstance(actionbar, (byte) 2);
sendPacket(player, chatPacket);
NmsBasics.get().sendPacket(player, chatPacket);
}
catch(Exception ex)
{
@ -243,23 +232,6 @@ public final class NmsPacket extends NmsAbstract
// UTIL
// -------------------------------------------- //
public static void sendPacket(Player player, Object packet)
{
Object connection = getPlayerConnection(player);
ReflectionUtil.invokeMethod(sendPacket, connection, packet);
}
public static <T> T getPlayerConnection(Player player)
{
Object handle = getHandle(player);
return ReflectionUtil.getField(playerConnection, handle);
}
public static <T> T getHandle(Player player)
{
return ReflectionUtil.invokeMethod(getHandle, player);
}
public static Object toChatBaseComponent(String str) throws Exception
{
return chatSerializer.invoke(null, str);

View File

@ -0,0 +1,33 @@
package com.massivecraft.massivecore.nms;
import org.bukkit.inventory.PlayerInventory;
import com.massivecraft.massivecore.mixin.Mixin;
public class NmsPlayerInventoryCreate extends Mixin
{
// -------------------------------------------- //
// DEFAULT
// -------------------------------------------- //
private static NmsPlayerInventoryCreate d = new NmsPlayerInventoryCreate().setAlternatives(
NmsPlayerInventoryCreate17R4P.class
);
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static NmsPlayerInventoryCreate i = d;
public static NmsPlayerInventoryCreate get() { return i; }
// -------------------------------------------- //
// CREATE
// -------------------------------------------- //
public PlayerInventory create()
{
throw notImplemented();
}
}

View File

@ -0,0 +1,56 @@
package com.massivecraft.massivecore.nms;
import java.lang.reflect.Constructor;
import org.bukkit.inventory.PlayerInventory;
import com.massivecraft.massivecore.particleeffect.ReflectionUtils;
import com.massivecraft.massivecore.util.ReflectionUtil;
public class NmsPlayerInventoryCreate17R4P extends NmsPlayerInventoryCreate
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static NmsPlayerInventoryCreate17R4P i = new NmsPlayerInventoryCreate17R4P();
public static NmsPlayerInventoryCreate17R4P get () { return i; }
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
private Class<?> classNmsPlayerInventory;
private Class<?> classNmsEntityHuman;
private Constructor<?> constructorNmsPlayerInventory;
private Class<?> classCraftInventoryPlayer;
private Constructor<?> constructorCraftInventoryPlayer;
// -------------------------------------------- //
// SETUP
// -------------------------------------------- //
@Override
public void setup() throws Throwable
{
this.classNmsPlayerInventory = ReflectionUtils.PackageType.MINECRAFT_SERVER.getClass("PlayerInventory");
this.classNmsEntityHuman = ReflectionUtils.PackageType.MINECRAFT_SERVER.getClass("EntityHuman");
this.constructorNmsPlayerInventory = ReflectionUtils.getConstructor(this.classNmsPlayerInventory, this.classNmsEntityHuman);
this.classCraftInventoryPlayer = ReflectionUtils.PackageType.CRAFTBUKKIT_INVENTORY.getClass("CraftInventoryPlayer");
this.constructorCraftInventoryPlayer = ReflectionUtils.getConstructor(this.classCraftInventoryPlayer, this.classNmsPlayerInventory);
}
// -------------------------------------------- //
// CREATE
// -------------------------------------------- //
@Override
public PlayerInventory create()
{
Object nmsInventory = ReflectionUtil.invokeConstructor(this.constructorNmsPlayerInventory, (Object)null);
return ReflectionUtil.invokeConstructor(this.constructorCraftInventoryPlayer, nmsInventory);
}
}

View File

@ -1,158 +0,0 @@
package com.massivecraft.massivecore.picker;
import java.util.Arrays;
import java.util.List;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.util.ReflectionUtil;
// TODO: Rename to Mixin... because that's what we are trying to replace.
@SuppressWarnings("unchecked")
public class Picker extends Engine
{
// -------------------------------------------- //
// DEFAULT
// -------------------------------------------- //
// The default class contains the static fields.
// It should never be abstract and should always be compatible.
// A default class instance is set as the default value. This avoids null.
// It is detected by the required static field d.
private final Class<?> defaultClass = ReflectionUtil.getSuperclassDeclaringField(this.getClass(), true, "d");
public Class<?> getDefaultClass() { return this.defaultClass; }
public Picker getDefault() { return ReflectionUtil.getField(this.getDefaultClass(), "d", null); }
public boolean isDefault() { return this == this.getDefault(); }
// -------------------------------------------- //
// INSTANCE
// -------------------------------------------- //
// Access the active static instance using instance methods.
// This looks a bit strange but will save us a lot of repetitive source code down the road.
// These are not meant to be used for selection or activation.
// The standard active interface methods are used for that.
public Picker getInstance() { return ReflectionUtil.getField(this.getDefaultClass(), "i", null); }
public void setInstance(Picker i) { ReflectionUtil.setField(this.getDefaultClass(), "i", null, i); }
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
// This is the base name.
// It should describe the function supplied.
// It should be set in the base class constructor.
private String baseName = this.getDefaultClass().getClass().getSimpleName();
public String getBaseName() { return this.baseName; }
public void setBaseName(String baseName) { this.baseName = baseName; }
// This is the instance specific name.
// It should describe the circumstances for compatibility.
// It could for example contain a version number.
private String name = this.getClass().getSimpleName();
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
// This is the list of alternatives to choose from.
// The first compatible alternative will be chosen for activation.
// The list should thus start with the most provoking and detailed alternative.
// If the list is empty we simply offer ourselves.
private List<Class<?>> alternatives = new MassiveList<>();
public List<Class<?>> getAlternatives() { return this.alternatives; }
public <T extends Picker> T setAlternatives(List<Class<?>> alternatives) { this.alternatives = alternatives; return (T) this; }
public <T extends Picker> T setAlternatives(Class<?>... alternatives) { return this.setAlternatives(Arrays.asList(alternatives)); }
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public Picker()
{
// Provoke!
try
{
this.provoke();
}
catch (Throwable t)
{
throw ReflectionUtil.asRuntimeException(t);
}
}
// -------------------------------------------- //
// PROVOKE
// -------------------------------------------- //
// Provoke your exceptions and errors here.
// If a throwable is thrown here the instance is not compatible with the circumstances.
public Object provoke() throws Throwable
{
return null;
}
// -------------------------------------------- //
// ACTIVE
// -------------------------------------------- //
// We need to modify the active logic sightly.
//
// We make use of the standard engine isActive.
// That one looks at the engine registry and does not care about the instance.
// That behavior tends to work out well for us in this case.
//
// The reason for this is that the default will be set as the instance from the start.
// That does however not mean that it's active.
// It means it will be used to set the active which may or may not be itself.
@Override
public void setActive(boolean active)
{
// NoChange
if (this.isActive() == active) return;
// Before
Picker before = this.getInstance();
// After
Picker after;
if (active)
{
// This
after = this;
// Alternatives
for (Class<?> alternative : this.getAlternatives())
{
try
{
Picker alternativeInstance = ReflectionUtil.getSingletonInstance(alternative);
after = alternativeInstance;
break;
}
catch (Throwable t)
{
// Not Compatible
}
}
}
else
{
// Default
after = this.getDefault();
}
// Deactivate Before
if (before != this) before.setActive(false);
// Set Instance
this.setInstance(after);
// Activate After
if (after != this) after.setActive(true);
// Super
if (after == this) super.setActive(active);
}
}

View File

@ -1,49 +0,0 @@
package com.massivecraft.massivecore.picker;
import com.massivecraft.massivecore.MassiveCore;
import com.massivecraft.massivecore.util.Txt;
public class PickerTest extends Picker
{
// -------------------------------------------- //
// DEFAULT
// -------------------------------------------- //
private static final PickerTest d = new PickerTest().setAlternatives(
PickerTestImpossible.class,
PickerTestPossible.class
);
// -------------------------------------------- //
// INSTANCE
// -------------------------------------------- //
private static final PickerTest i = d;
public static PickerTest get() { return i; }
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public PickerTest()
{
}
// -------------------------------------------- //
// METHODS
// -------------------------------------------- //
public void action()
{
String msg = this.getMsg();
String message = Txt.parse(msg);
MassiveCore.get().log(message);
}
public String getMsg()
{
return "<silver>Default...";
}
}

View File

@ -1,32 +0,0 @@
package com.massivecraft.massivecore.picker;
public class PickerTestImpossible extends PickerTest
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static final PickerTestImpossible i = new PickerTestImpossible();
public static PickerTestImpossible get() { return i; }
// -------------------------------------------- //
// PROVOKE
// -------------------------------------------- //
@Override
public Object provoke() throws Throwable
{
throw new RuntimeException("so provokative!");
}
// -------------------------------------------- //
// METHODS
// -------------------------------------------- //
@Override
public String getMsg()
{
return "<rose>Impossible and Unexpected";
}
}

View File

@ -1,22 +0,0 @@
package com.massivecraft.massivecore.picker;
public class PickerTestPossible extends PickerTest
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static final PickerTestPossible i = new PickerTestPossible();
public static PickerTestPossible get() { return i; }
// -------------------------------------------- //
// METHODS
// -------------------------------------------- //
@Override
public String getMsg()
{
return "<lime>Possible and Expected";
}
}

View File

@ -66,7 +66,7 @@ import com.massivecraft.massivecore.engine.EngineMassiveCoreDatabase;
import com.massivecraft.massivecore.engine.EngineMassiveCoreMain;
import com.massivecraft.massivecore.engine.EngineMassiveCoreWorldNameSet;
import com.massivecraft.massivecore.mixin.MixinMessage;
import com.massivecraft.massivecore.nms.NmsEntity;
import com.massivecraft.massivecore.nms.NmsEntityGet;
import com.massivecraft.massivecore.predicate.Predicate;
import com.massivecraft.massivecore.util.extractor.Extractor;
import com.massivecraft.massivecore.util.extractor.ExtractorPlayer;
@ -189,57 +189,12 @@ public class MUtil
public static Entity getEntity(World world, UUID uuid)
{
if (world == null) throw new NullPointerException("world");
if (uuid == null) return null;
if (NmsEntity.get().isAvailable())
{
return NmsEntity.get().getEntity(world, uuid);
}
else
{
return getEntityFallback(world, uuid);
}
return NmsEntityGet.get().getEntity(world, uuid);
}
public static Entity getEntity(UUID uuid)
{
if (uuid == null) return null;
if (NmsEntity.get().isAvailable())
{
return NmsEntity.get().getEntity(uuid);
}
else
{
return getEntityFallback(uuid);
}
}
private static Entity getEntityFallback(World world, UUID uuid)
{
if (world == null) throw new NullPointerException("world");
if (uuid == null) return null;
for (Entity entity : world.getEntities())
{
if (entity.getUniqueId().equals(uuid)) return entity;
}
return null;
}
private static Entity getEntityFallback(UUID uuid)
{
if (uuid == null) return null;
for (World world : Bukkit.getWorlds())
{
Entity ret = getEntityFallback(world, uuid);
if (ret != null) return ret;
}
return null;
return NmsEntityGet.get().getEntity(uuid);
}
// -------------------------------------------- //

View File

@ -207,6 +207,22 @@ public class ReflectionUtil
return ret;
}
public static <T> T getSingletonInstanceFirstCombatible(Iterable<Class<?>> classes, T fallback)
{
for (Class<?> c : classes)
{
try
{
return ReflectionUtil.getSingletonInstance(c);
}
catch (Throwable t)
{
// Not Compatible
}
}
return fallback;
}
// -------------------------------------------- //
// FIELD > GET
// -------------------------------------------- //