Ir para conteúdo

Reflections - Metodos para todas versões


Terminall

Posts Recomendados

Reflections

 

Afinal,  pra que serve reflection?

Reflection é uma universal parte do java, neste tutorial, a principal função é 

acessar variáveis da Bukkit API. Usando reflections conseguimos 

fazer um plugin suportar desde da 1.5 até à 1.11. Como fazemos isso? É simples,

se você já trabalhou com Bukkit API, deve ter percebido que a cada

versão que ao importar certas classes, a classe importada vem com a versão

do spigot utilizada (Exemplo: org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer & org.bukkit.craftbukkit.v1_8_R1.entity.CraftPlayer).

Se utilizarmos uma versão do spigot  diferente do projeto, irá dar um erro no console (java.lang.ClassNotFoundfalando que a classe do projeto não foi encontrada.

 

Exemplos:

Titles:

 

 

import java.lang.reflect.Field;

import org.bukkit.entity.Player;

public class TitleAPI
{
    
    @Deprecated
    public static void setTible(final Player player, final Integer fadeIn, final Integer stay, final Integer fadeOut, final String title, final String subtitle) {
        sendTitle(player, fadeIn, stay, fadeOut, title, subtitle);
    }
    
    @Deprecated
    public static void sendSubtitle(final Player player, final Integer fadeIn, final Integer stay, final Integer fadeOut, final String message) {
        sendTitle(player, fadeIn, stay, fadeOut, null, message);
    }
    
    @Deprecated
    public static void sendFullTitle(final Player player, final Integer fadeIn, final Integer stay, final Integer fadeOut, final String title, final String subtitle) {
        sendTitle(player, fadeIn, stay, fadeOut, title, subtitle);
    }
    
    public static void sendPacket(final Player player, final Object packet) {
        try {
            final Object handle = player.getClass().getMethod("getHandle", (Class<?>[])new Class[0]).invoke(player, new Object[0]);
            final Object playerConnection = handle.getClass().getField("playerConnection").get(handle);
            playerConnection.getClass().getMethod("sendPacket", getNMSClass("Packet")).invoke(playerConnection, packet);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public static Class<?> getNMSClass(final String name) {
        final String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
        try {
            return Class.forName("net.minecraft.server." + version + "." + name);
        }
        catch (ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }
    
    public static void sendTitle(final Player player, final Integer fadeIn, final Integer stay, final Integer fadeOut, String title, String subtitle) {
        try {
            if (title != null) {
                title = ChatColor.translateAlternateColorCodes('&', title);
                title = title.replaceAll("%player%", player.getDisplayName());
                final Object enumTitle = getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0].getField("TITLE").get(null);
                final Object chatTitle = getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", String.class).invoke(null, "{\"text\":\"" + title + "\"}");
                final Constructor<?> titleConstructor = getNMSClass("PacketPlayOutTitle").getConstructor(getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0], getNMSClass("IChatBaseComponent"), Integer.TYPE, Integer.TYPE, Integer.TYPE);
                final Object titlePacket = titleConstructor.newInstance(enumTitle, chatTitle, fadeIn, stay, fadeOut);
                sendPacket(player, titlePacket);
            }
            if (subtitle != null) {
                subtitle = ChatColor.translateAlternateColorCodes('&', subtitle);
                subtitle = subtitle.replaceAll("%player%", player.getDisplayName());
                final Object enumSubtitle = getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0].getField("SUBTITLE").get(null);
                final Object chatSubtitle = getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", String.class).invoke(null, "{\"text\":\"" + subtitle + "\"}");
                final Constructor<?> subtitleConstructor = getNMSClass("PacketPlayOutTitle").getConstructor(getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0], getNMSClass("IChatBaseComponent"), Integer.TYPE, Integer.TYPE, Integer.TYPE);
                final Object subtitlePacket = subtitleConstructor.newInstance(enumSubtitle, chatSubtitle, fadeIn, stay, fadeOut);
                sendPacket(player, subtitlePacket);
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void sendTabTitle(final Player player, String header, String footer) {
        if (header == null) {
            header = "";
        }
        header = ChatColor.translateAlternateColorCodes('&', header);
        if (footer == null) {
            footer = "";
        }
        footer = ChatColor.translateAlternateColorCodes('&', footer);
        header = header.replaceAll("%player%", player.getDisplayName());
        footer = footer.replaceAll("%player%", player.getDisplayName());
        try {
            final Object tabHeader = getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", String.class).invoke(null, "{\"text\":\"" + header + "\"}");
            final Object tabFooter = getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", String.class).invoke(null, "{\"text\":\"" + footer + "\"}");
            final Constructor<?> titleConstructor = getNMSClass("PacketPlayOutPlayerListHeaderFooter").getConstructor(getNMSClass("IChatBaseComponent"));
            final Object packet = titleConstructor.newInstance(tabHeader);
            final Field field = packet.getClass().getDeclaredField("b");
            field.setAccessible(true);
            field.set(packet, tabFooter);
            sendPacket(player, packet);
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }

 

 

 

Como utilizar (Titles):

sendFullTitle(Player player, int entrada,int duracao, int saida, String titulo, String subtitlo);

 

ActionBar:


 

 

public class ActionBarSender
{
    private static Class<?> CRAFTPLAYERCLASS;
    private static Class<?> PACKET_PLAYER_CHAT_CLASS;
    private static Class<?> ICHATCOMP;
    private static Class<?> CHATMESSAGE;
    private static Class<?> PACKET_CLASS;
    private static Constructor<?> PACKET_PLAYER_CHAT_CONSTRUCTOR;
    private static Constructor<?> CHATMESSAGE_CONSTRUCTOR;
    private static final String SERVER_VERSION;
    
    static {
        String name = Bukkit.getServer().getClass().getName();
        name = name.substring(name.indexOf("craftbukkit.") + "craftbukkit.".length());
        name = (SERVER_VERSION = name.substring(0, name.indexOf(".")));
        try {
            ActionBarSender.CRAFTPLAYERCLASS = Class.forName("org.bukkit.craftbukkit." + ActionBarSender.SERVER_VERSION + ".entity.CraftPlayer");
            ActionBarSender.PACKET_PLAYER_CHAT_CLASS = Class.forName("net.minecraft.server." + ActionBarSender.SERVER_VERSION + ".PacketPlayOutChat");
            ActionBarSender.PACKET_CLASS = Class.forName("net.minecraft.server." + ActionBarSender.SERVER_VERSION + ".Packet");
            ActionBarSender.ICHATCOMP = Class.forName("net.minecraft.server." + ActionBarSender.SERVER_VERSION + ".IChatBaseComponent");
            ActionBarSender.PACKET_PLAYER_CHAT_CONSTRUCTOR = ActionBarSender.PACKET_PLAYER_CHAT_CLASS.getConstructor(ActionBarSender.ICHATCOMP, Byte.TYPE);
            ActionBarSender.CHATMESSAGE = Class.forName("net.minecraft.server." + ActionBarSender.SERVER_VERSION + ".ChatMessage");
            ActionBarSender.CHATMESSAGE_CONSTRUCTOR = ActionBarSender.CHATMESSAGE.getDeclaredConstructor(String.class, Object[].class);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void sendActionBarMessage(final Player player, final String message) {
        try {
            final Object icb = ActionBarSender.CHATMESSAGE_CONSTRUCTOR.newInstance(message, new Object[0]);
            final Object packet = ActionBarSender.PACKET_PLAYER_CHAT_CONSTRUCTOR.newInstance(icb, (byte)2);
            final Object craftplayerInst = ActionBarSender.CRAFTPLAYERCLASS.cast(player);
            final Method methodHandle = ActionBarSender.CRAFTPLAYERCLASS.getMethod("getHandle", (Class<?>[])new Class[0]);
            final Object methodhHandle = methodHandle.invoke(craftplayerInst, new Object[0]);
            final Object playerConnection = methodhHandle.getClass().getField("playerConnection").get(methodhHandle);
            playerConnection.getClass().getMethod("sendPacket", ActionBarSender.PACKET_CLASS).invoke(playerConnection, packet);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

 



 

Como utilizar (ActionBar):

sendActionBarMessage(Player player, String mensagem);

Link para o comentário
Compartilhar em outros sites

Participe da Conversa

Você pode postar agora e se cadastrar mais tarde. Se você tiver uma conta, a class='ipsType_brandedLink' href='https://gamersboard.com.br/login/' data-ipsDialog data-ipsDialog-size='medium' data-ipsDialog-title='Sign In Now'>acesse agora para postar com sua conta.
Observação: sua postagem exigirá aprovação do moderador antes de ficar visível.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.

Processando...
×
×
  • Criar Novo...