[Free Code] Instant Firework Effect - Spigot 1.9 and 1.10

Discussion in 'Spigot Discussion' started by jeussa, Jun 5, 2016.

  1. Hi dere Spigot community,

    some time ago I posted the source code for an instant firework effect API on the spigot forums (https://www.spigotmc.org/threads/free-code-instant-firework.112252/). This code however stopped working in 1.9 due to certain changes in the packet protocols.

    Anyway, after some fiddling with the packet data (or actually a complete redo from scratch) I managed to get things working again.

    The code below fully works on java reflection and has no direct bindings to the minecraft server classes. This enables the code to not break when using a new spigot version. (unless the protocols are changed of course)

    ========================================================

    Compatibility

    The code you see below was tested and confirmed using the following versions:

    - 1.10
    - 1.9.4
    - 1.9.2

    Please do tell me if you've managed to get the code working on a different version ;)

    ========================================================

    1.8

    For servers using minecraft 1.8, please refer to my old thread:
    https://www.spigotmc.org/threads/free-code-instant-firework.112252/

    ========================================================

    Download

    The source code can also be found on github: https://github.com/jeussa/MC-Instant-Fireworks/tree/master/fireworks
    Or if you want a plugin version (to use as API), you can download it from http://tinyurl.com/hhagypd

    ========================================================

    Usage

    Code (Text):
    FireworkSpawner.spawn(<location>, <effect>, <players>);
    (the players can be specified individually, as an array or as a list)


    NOTE: PH_PO stands for PacketHandler_PlayOut. So if you take the class PH_PO_EntityStatus it means that the class is the PacketHandler for the PacketPlayOutEntityStatus packet.

    ========================================================

    Source

    Code (Text):
    package fireworks;

    import java.util.Arrays;
    import java.util.List;
    import java.util.UUID;

    import org.bukkit.FireworkEffect;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.FireworkMeta;

    public class FireworkSpawner {
     
        public static void spawn(Location location, FireworkEffect effect, Player...players){
            if(location==null||effect==null||players==null||players.length==0)return;
         
            //Generate some basic info
            int entityId=FireworkSpawner.getNextEntityId();
            UUID entityUuid=UUID.randomUUID();
         
            //Spawn firework entity
            new PH_PO_SpawnEntity(entityId, entityUuid, 76/*ID of firework entity type*/, 0, location.getX(), location.getY(), location.getZ(),
                    location.getYaw(), location.getPitch(), 0, 0, 0).send(players);
         
            //From here we put things inside a try-catch to make sure the player always receives a destroy packet (otherwise their client will crash)
            try{
                //Send firework meta
                ItemStack item=new ItemStack(Material.FIREWORK);
                FireworkMeta meta=(FireworkMeta)item.getItemMeta();
                meta.addEffect(effect);
                item.setItemMeta(meta);
             
                jDataWatcherItem<Byte> i1=new jDataWatcherItem<Byte>(jDataWatcherObject.entity_byte, (byte)0);
                jDataWatcherItem<Integer> i2=new jDataWatcherItem<Integer>(jDataWatcherObject.entity_int, 300);
                jDataWatcherItem<String> i3=new jDataWatcherItem<String>(jDataWatcherObject.entity_string, "");
                jDataWatcherItem<Boolean> i4=new jDataWatcherItem<Boolean>(jDataWatcherObject.entity_boolean1, false);
                jDataWatcherItem<Boolean> i5=new jDataWatcherItem<Boolean>(jDataWatcherObject.entity_boolean2, false);
                jDataWatcherItem<ItemStack> i6=new jDataWatcherItem<ItemStack>(jDataWatcherObject.entityfireworks_itemstack, item);
             
                i1.setFlag(false);
                i2.setFlag(false);
                i3.setFlag(false);
                i4.setFlag(false);
                i5.setFlag(false);
                i6.setFlag(false);
             
                new PH_PO_EntityMetadata(entityId, Arrays.asList(i1, i2, i3, i4, i5, i6)).send(players);
             
                //Play explosion effect
                new PH_PO_EntityStatus(entityId, (byte)17/*Explode status ID*/).send(players);
            }finally{
                //Send destroy packet (very important, otherwise the client will crash)
                new PH_PO_EntityDestroy(entityId).send(players);
            }
        }
        public static void spawn(Location location, FireworkEffect effect, List<Player> players){
            FireworkSpawner.spawn(location, effect, players.toArray(new Player[players.size()]));
        }
     
        /**
        * Utils
        */
        private static int currentEntityId=Integer.MAX_VALUE;
        private static int getNextEntityId(){
            return FireworkSpawner.currentEntityId--;
        }
    }
     

    Code (Text):
    package fireworks;

    import java.util.List;

    import org.bukkit.entity.Player;

    public abstract class aPacketHandler implements iNmsObject{

        /**
         * Send
         */
        public final void send(Player...players){
            if(players.length==0)return;

            try{
                Object packet=this.build();
                for(Player player:players)if(player!=null)ProtocolUtils.refl_sendPacket0(player, packet);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        public final void send(List<Player> players){
            this.send(players.toArray(new Player[players.size()]));
        }
    }
     

    Code (Text):
    package fireworks;

    public interface iNmsObject {

        /**
         * Build
         */
        public Object build()throws Exception;
    }
     

    Code (Text):
    package fireworks;

    import java.lang.reflect.Constructor;
    import java.lang.reflect.Method;

    import org.bukkit.inventory.ItemStack;

    import com.google.common.base.Optional;

    public class jDataWatcherItem<T> implements iNmsObject{

        private static Class<?> clazz;
        private static Constructor<?> constructor;
        private static Method method_flag_set;

        static{
            try{
                jDataWatcherItem.clazz=ProtocolUtils.getMinecraftClass("DataWatcher$Item");

                jDataWatcherItem.constructor=jDataWatcherItem.clazz.getDeclaredConstructor(new Class[]{ProtocolUtils.getMinecraftClass("DataWatcherObject"), Object.class});
                jDataWatcherItem.constructor.setAccessible(true);

                jDataWatcherItem.method_flag_set=jDataWatcherItem.clazz.getDeclaredMethod("a", new Class[]{boolean.class});
                jDataWatcherItem.method_flag_set.setAccessible(true);
            }catch(Exception e){
                e.printStackTrace();
            }
        }



        private final jDataWatcherObject<T> watcherobject;
        private T value;
        private boolean flag;

        public jDataWatcherItem(jDataWatcherObject<T> watcherobject, T value){
            this.watcherobject=watcherobject;
            this.value=value;
            this.flag=true;
        }

        /**
         * WatcherObject
         */
        //Get
        public jDataWatcherObject<T> getWatcherObject(){
            return this.watcherobject;
        }

        /**
         * Value
         */
        //Set
        public void setValue(T value){
            this.value=value;
        }
        //Get
        public T getValue(){
            return this.value;
        }

        /**
         * Flag
         */
        //Get
        public boolean getFlag(){
            return this.flag;
        }
        //Set
        public void setFlag(boolean flag){
            this.flag=flag;
        }

        /**
         * Build
         */
        @Override
        public Object build()throws Exception{
            Object val=null;

            if(this.value instanceof ItemStack)val=Optional.of(ProtocolUtils.refl_itemAsNMSCopy((ItemStack)this.value));
            else val=this.value;

            Object item=jDataWatcherItem.constructor.newInstance(this.watcherobject.build(), val);
            jDataWatcherItem.method_flag_set.invoke(item, this.flag);

            return item;
        }
    }
     

    Code (Text):
    package fireworks;

    import org.bukkit.inventory.ItemStack;

    public class jDataWatcherObject<T> implements iNmsObject{
     
        private static int version;
     
        static{
            String v=ProtocolUtils.version;
            if(v.startsWith("v1_9")){
                if(v.endsWith("R1"))jDataWatcherObject.version=0;
                else jDataWatcherObject.version=1;
            }
            else if(v.startsWith("v1_10")){
                jDataWatcherObject.version=2;
            }
        }
        private static String v(String...values){
            return values[jDataWatcherObject.version];
        }
     
        public static final jDataWatcherObject<Byte> entity_byte=new jDataWatcherObject<>(v("ax", "ay", "aa"), "Entity");
        public static final jDataWatcherObject<Integer> entity_int=new jDataWatcherObject<>(v("ay", "az", "az"), "Entity");
        public static final jDataWatcherObject<String> entity_string=new jDataWatcherObject<>(v("az", "aA", "aA"), "Entity");
        public static final jDataWatcherObject<Boolean> entity_boolean1=new jDataWatcherObject<>(v("aA", "aB", "aB"), "Entity");
        public static final jDataWatcherObject<Boolean> entity_boolean2=new jDataWatcherObject<>(v("aB", "aC", "aC"), "Entity");
        public static final jDataWatcherObject<Boolean> entity_boolean3=new jDataWatcherObject<>(v(null, null, "aD"), "Entity");
        public static final jDataWatcherObject<ItemStack> entityfireworks_itemstack=new jDataWatcherObject<>("FIREWORK_ITEM", "EntityFireworks");
     
     
     
        private final Object nms;
     
        private jDataWatcherObject(String fieldname, String classname){
            this.nms=ProtocolUtils.refl_fieldGet0(fieldname, classname);
        }
     
        /**
        * Build
        */
        @Override
        public Object build(){
            return this.nms;
        }
    }
     
     
    #1 jeussa, Jun 5, 2016
    Last edited: Jun 12, 2016
    • Useful Useful x 3
    • Like Like x 1
  2. Code (Text):
    package fireworks;

    import java.lang.reflect.Field;

    public class PH_PO_EntityDestroy extends aPacketHandler{
     
        public int[] entityIds;
     
        private static Class<?> clazz;
        private static Field field_entityIds;
     
        static{
            try{
                PH_PO_EntityDestroy.clazz=ProtocolUtils.getMinecraftClass("PacketPlayOutEntityDestroy");
             
                PH_PO_EntityDestroy.field_entityIds=PH_PO_EntityDestroy.clazz.getDeclaredField("a");
                PH_PO_EntityDestroy.field_entityIds.setAccessible(true);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
     
        public PH_PO_EntityDestroy(int...entityIds){
            this.entityIds=entityIds;
        }
     
        /**
         * Build
         */
        @Override
        public Object build()throws Exception{
            Object packet=PH_PO_EntityDestroy.clazz.newInstance();
         
            PH_PO_EntityDestroy.field_entityIds.set(packet, this.entityIds);
         
            return packet;
        }
    }
     

    Code (Text):
    package fireworks;

    import java.lang.reflect.Field;
    import java.util.LinkedList;
    import java.util.List;

    public class PH_PO_EntityMetadata extends aPacketHandler{
     
        public int entityId;
        public List<jDataWatcherItem<?>> metadata;
     
        private static Class<?> clazz;
        private static Field field_entityid;
        private static Field field_metadata;
     
        static{
            try{
                PH_PO_EntityMetadata.clazz=ProtocolUtils.getMinecraftClass("PacketPlayOutEntityMetadata");
             
                PH_PO_EntityMetadata.field_entityid=PH_PO_EntityMetadata.clazz.getDeclaredField("a");
                PH_PO_EntityMetadata.field_entityid.setAccessible(true);
             
                PH_PO_EntityMetadata.field_metadata=PH_PO_EntityMetadata.clazz.getDeclaredField("b");
                PH_PO_EntityMetadata.field_metadata.setAccessible(true);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
     
        public PH_PO_EntityMetadata(int entityId, List<jDataWatcherItem<?>> metadata){
            this.entityId=entityId;
            this.metadata=metadata;
        }
     
        /**
         * Build
         */
        @SuppressWarnings({"rawtypes", "unchecked"})
        @Override
        public Object build()throws Exception{
            Object packet=PH_PO_EntityMetadata.clazz.newInstance();
         
            PH_PO_EntityMetadata.field_entityid.set(packet, this.entityId);
         
            List list=new LinkedList<>();
            for(jDataWatcherItem<?> item:this.metadata)list.add(item.build());
            PH_PO_EntityMetadata.field_metadata.set(packet, list);
         
            return packet;
        }
    }
     

    Code (Text):
    package fireworks;

    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;

    public class PH_PO_EntityStatus extends aPacketHandler{
     
        public int entityId;
        public byte statusId;
     
        private static Class<?> clazz;
        private static Constructor<?> constructor;
        private static Field field_entityId;
        private static Field field_statusId;
     
        static{
            try{
                PH_PO_EntityStatus.clazz=ProtocolUtils.getMinecraftClass("PacketPlayOutEntityStatus");
                PH_PO_EntityStatus.constructor=PH_PO_EntityStatus.clazz.getDeclaredConstructor();
                PH_PO_EntityStatus.constructor.setAccessible(true);
             
                PH_PO_EntityStatus.field_entityId=PH_PO_EntityStatus.clazz.getDeclaredField("a");
                PH_PO_EntityStatus.field_entityId.setAccessible(true);
             
                PH_PO_EntityStatus.field_statusId=PH_PO_EntityStatus.clazz.getDeclaredField("b");
                PH_PO_EntityStatus.field_statusId.setAccessible(true);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
     
        public PH_PO_EntityStatus(int entityId, byte statusId){
            this.entityId=entityId;
            this.statusId=statusId;
        }
     
        /**
         * Build
         */
        @Override
        public Object build()throws Exception{
            Object packet=PH_PO_EntityStatus.constructor.newInstance();
         
            PH_PO_EntityStatus.field_entityId.set(packet, this.entityId);
            PH_PO_EntityStatus.field_statusId.set(packet, this.statusId);
         
            return packet;
        }
    }
     

    Code (Text):
    package fireworks;

    import java.lang.reflect.Field;
    import java.util.UUID;

    public class PH_PO_SpawnEntity extends aPacketHandler{

        public int entityId;
        public UUID entityUuid;
        public double x;
        public double y;
        public double z;
        public int velocityX;
        public int velocityY;
        public int velocityZ;
        public float pitch;
        public float yaw;
        public int entityTypeId;
        public int entityDataId;
     
        private static Class<?> clazz;
        private static Field field_entityId;
        private static Field field_entityUuid;
        private static Field field_x;
        private static Field field_y;
        private static Field field_z;
        private static Field field_velocityX;
        private static Field field_velocityY;
        private static Field field_velocityZ;
        private static Field field_pitch;
        private static Field field_yaw;
        private static Field field_entityTypeId;
        private static Field field_entityDataId;
     
        static{
            try{
                PH_PO_SpawnEntity.clazz=ProtocolUtils.getMinecraftClass("PacketPlayOutSpawnEntity");
             
                PH_PO_SpawnEntity.field_entityId=PH_PO_SpawnEntity.clazz.getDeclaredField("a");
                PH_PO_SpawnEntity.field_entityId.setAccessible(true);
             
                PH_PO_SpawnEntity.field_entityUuid=PH_PO_SpawnEntity.clazz.getDeclaredField("b");
                PH_PO_SpawnEntity.field_entityUuid.setAccessible(true);
             
                PH_PO_SpawnEntity.field_x=PH_PO_SpawnEntity.clazz.getDeclaredField("c");
                PH_PO_SpawnEntity.field_x.setAccessible(true);
             
                PH_PO_SpawnEntity.field_y=PH_PO_SpawnEntity.clazz.getDeclaredField("d");
                PH_PO_SpawnEntity.field_y.setAccessible(true);
             
                PH_PO_SpawnEntity.field_z=PH_PO_SpawnEntity.clazz.getDeclaredField("e");
                PH_PO_SpawnEntity.field_z.setAccessible(true);
             
                PH_PO_SpawnEntity.field_velocityX=PH_PO_SpawnEntity.clazz.getDeclaredField("f");
                PH_PO_SpawnEntity.field_velocityX.setAccessible(true);
             
                PH_PO_SpawnEntity.field_velocityY=PH_PO_SpawnEntity.clazz.getDeclaredField("g");
                PH_PO_SpawnEntity.field_velocityY.setAccessible(true);
             
                PH_PO_SpawnEntity.field_velocityZ=PH_PO_SpawnEntity.clazz.getDeclaredField("h");
                PH_PO_SpawnEntity.field_velocityZ.setAccessible(true);
             
                PH_PO_SpawnEntity.field_pitch=PH_PO_SpawnEntity.clazz.getDeclaredField("i");
                PH_PO_SpawnEntity.field_pitch.setAccessible(true);
             
                PH_PO_SpawnEntity.field_yaw=PH_PO_SpawnEntity.clazz.getDeclaredField("j");
                PH_PO_SpawnEntity.field_yaw.setAccessible(true);
             
                PH_PO_SpawnEntity.field_entityTypeId=PH_PO_SpawnEntity.clazz.getDeclaredField("k");
                PH_PO_SpawnEntity.field_entityTypeId.setAccessible(true);
             
                PH_PO_SpawnEntity.field_entityDataId=PH_PO_SpawnEntity.clazz.getDeclaredField("l");
                PH_PO_SpawnEntity.field_entityDataId.setAccessible(true);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
     
        public PH_PO_SpawnEntity(int entityId, UUID entityUuid, int entityTypeId, int entityDataId, double x, double y, double z, float yaw, float pitch,
                int velocityX, int velocityY, int velocityZ){
            this.entityId=entityId;
            this.entityUuid=entityUuid;
            this.x=x;
            this.y=y;
            this.z=z;
            this.velocityX=velocityX;
            this.velocityY=velocityY;
            this.velocityZ=velocityZ;
            this.pitch=pitch;
            this.yaw=yaw;
            this.entityTypeId=entityTypeId;
            this.entityDataId=entityDataId;
        }
     
        /**
         * Build
         */
        @Override
        public Object build()throws Exception{
            Object packet=PH_PO_SpawnEntity.clazz.newInstance();
         
            PH_PO_SpawnEntity.field_entityId.set(packet, this.entityId);
            PH_PO_SpawnEntity.field_entityUuid.set(packet, this.entityUuid);
            PH_PO_SpawnEntity.field_x.set(packet, this.x);
            PH_PO_SpawnEntity.field_y.set(packet, this.y);
            PH_PO_SpawnEntity.field_z.set(packet, this.z);
            PH_PO_SpawnEntity.field_velocityX.set(packet, this.ad(this.velocityX));
            PH_PO_SpawnEntity.field_velocityY.set(packet, this.ad(this.velocityY));
            PH_PO_SpawnEntity.field_velocityZ.set(packet, this.ad(this.velocityZ));
            PH_PO_SpawnEntity.field_pitch.set(packet, this.af(this.pitch));
            PH_PO_SpawnEntity.field_yaw.set(packet, this.af(this.yaw));
            PH_PO_SpawnEntity.field_entityTypeId.set(packet, this.entityTypeId);
            PH_PO_SpawnEntity.field_entityDataId.set(packet, this.entityDataId);
         
            return packet;
        }
     
        /**
         * Utils
         */
        private final int ad(double a){    
            if(a<3.9D)return ((int)(3.9D*8000.0D));
            else if(a>-3.9D)return ((int)(-3.9D*8000.0D));
            else return ((int)(a*8000.0D));
        }
        private final int af(float a){
            float f=a*256.0f/360.0f;
            int i=(int)f;
            return a<i?i-1:i;
        }
    }
     

    Code (Text):
    package fireworks;

    import java.lang.reflect.Field;
    import java.lang.reflect.Method;

    import org.bukkit.entity.Player;
    import org.bukkit.inventory.ItemStack;

    public class ProtocolUtils {
     
        public static final String version=org.bukkit.Bukkit.getServer().getClass().getName().split("\\.")[3];
        private static Method refl_item_asNMSCopy;
        private static Method refl_player_getHandle;
        private static Field refl_player_playerConnection;
        private static Method refl_player_sendPacket;
     
        static{
            try{
                ProtocolUtils.refl_item_asNMSCopy=ProtocolUtils.getCraftbukkitClass("inventory.CraftItemStack")
                        .getDeclaredMethod("asNMSCopy", new Class[]{ItemStack.class});
                ProtocolUtils.refl_item_asNMSCopy.setAccessible(true);
             
                Class<?> class_EntityPlayer=ProtocolUtils.getMinecraftClass("EntityPlayer");
                Class<?> class_CraftPlayer=ProtocolUtils.getCraftbukkitClass("entity.CraftPlayer");
                Class<?> class_PlayerConnection=ProtocolUtils.getMinecraftClass("PlayerConnection");
             
                ProtocolUtils.refl_player_getHandle=class_CraftPlayer.getDeclaredMethod("getHandle");
                ProtocolUtils.refl_player_playerConnection=class_EntityPlayer.getDeclaredField("playerConnection");
                ProtocolUtils.refl_player_sendPacket=class_PlayerConnection.getDeclaredMethod("sendPacket", new Class[]{ProtocolUtils.getMinecraftClass("Packet")});
            }catch(Exception e){
                e.printStackTrace();
            }
        }
     
        /**
         * GetMinecraftClass
         */
        public static Class<?> getMinecraftClass(String classname)throws ClassNotFoundException{
            return Class.forName("net.minecraft.server."+ProtocolUtils.version+"."+classname);
        }
     
        /**
         * GetCraftbukkitClass
         */
        public static Class<?> getCraftbukkitClass(String classname)throws ClassNotFoundException{
            return Class.forName("org.bukkit.craftbukkit."+ProtocolUtils.version+"."+classname);
        }
     
        /**
         * Reflection
         */
        //Field_Get
        public static Object refl_fieldGet(String fieldname, String classname)throws Exception{
            Field field=ProtocolUtils.getMinecraftClass(classname).getDeclaredField(fieldname);
            field.setAccessible(true);
            return field.get(null);
        }
        public static Object refl_fieldGet0(String fieldname, String classname){
            try{
                return ProtocolUtils.refl_fieldGet(fieldname, classname);
            }catch(Exception e){
                e.printStackTrace();
                return null;
            }
        }
        //Item_asNMSCopy
        public static Object refl_itemAsNMSCopy(ItemStack item)throws Exception{
            return ProtocolUtils.refl_item_asNMSCopy.invoke(null, item);
        }
        public static Object refl_itemAsNMSCopy0(ItemStack item){
            try{
                return ProtocolUtils.refl_itemAsNMSCopy(item);
            }catch(Exception e){
                e.printStackTrace();
                return null;
            }
        }
        //SendPacket
        public static void refl_sendPacket(Player player, Object packet)throws Exception{
            ProtocolUtils.refl_player_sendPacket.invoke(ProtocolUtils.refl_player_playerConnection.get(ProtocolUtils.refl_player_getHandle.invoke(player)), packet);
        }
        public static boolean refl_sendPacket0(Player player, Object packet){
            try{
                ProtocolUtils.refl_sendPacket(player, packet);
                return true;
            }catch(Exception e){
                e.printStackTrace();
                return false;
            }
        }
    }
     
     
    • Useful Useful x 2
  3. I can search and update it by myself but did you know if these classes works in spigot 1.9 instead of 1.9.4 ?
     
  4. Though I have not yet confirmed it, these classes should work with any 1.9 version.
     
    • Optimistic Optimistic x 1
  5. I've tested it and this error appears in console:
    Code (Text):
    [12:26:01] [Server thread/WARN]: java.lang.NoSuchFieldException: aC
    [12:26:01] [Server thread/WARN]:     at java.lang.Class.getDeclaredField(Class.java:1961)
    [12:26:01] [Server thread/WARN]:     at fr.asynchronous.sheepwars.entity.firework.ProtocolUtils.refl_fieldGet(ProtocolUtils.java:54)
    [12:26:01] [Server thread/WARN]:     at fr.asynchronous.sheepwars.entity.firework.ProtocolUtils.refl_fieldGet0(ProtocolUtils.java:60)
    [12:26:01] [Server thread/WARN]:     at fr.asynchronous.sheepwars.entity.firework.jDataWatcherObject.<init>(jDataWatcherObject.java:19)
    [12:26:01] [Server thread/WARN]:     at fr.asynchronous.sheepwars.entity.firework.jDataWatcherObject.<clinit>(jDataWatcherObject.java:11)
    [12:26:01] [Server thread/WARN]:     at fr.asynchronous.sheepwars.entity.firework.FireworkSpawner.spawn(FireworkSpawner.java:35)
    [12:26:01] [Server thread/WARN]:     at fr.asynchronous.sheepwars.SheepWarsPlugin$3$1.run(SheepWarsPlugin.java:764)
    [12:26:01] [Server thread/WARN]:     at org.bukkit.craftbukkit.v1_9_R1.scheduler.CraftTask.run(CraftTask.java:71)
    [12:26:01] [Server thread/WARN]:     at org.bukkit.craftbukkit.v1_9_R1.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:350)
    [12:26:01] [Server thread/WARN]:     at net.minecraft.server.v1_9_R1.MinecraftServer.D(MinecraftServer.java:729)
    [12:26:01] [Server thread/WARN]:     at net.minecraft.server.v1_9_R1.DedicatedServer.D(DedicatedServer.java:400)
    [12:26:01] [Server thread/WARN]:     at net.minecraft.server.v1_9_R1.MinecraftServer.C(MinecraftServer.java:660)
    [12:26:01] [Server thread/WARN]:     at net.minecraft.server.v1_9_R1.MinecraftServer.run(MinecraftServer.java:559)
    [12:26:01] [Server thread/WARN]:     at java.lang.Thread.run(Thread.java:745)
    [12:26:01] [Netty Epoll Server IO #3/ERROR]: java.lang.ClassCastException: java.lang.Byte cannot be cast to java.lang.Integer
    [12:26:01] [Netty Epoll Server IO #2/ERROR]: java.lang.ClassCastException: java.lang.Byte cannot be cast to java.lang.Integer
    That's a field error, i will check in spigot which field has changed ;)
     
  6. EDIT:

    I've find out the cause of this error in 1.9
    In 1.9, declared fields in jDataWatcherObject.java needs to be like this:
    Code (Text):
    public static final jDataWatcherObject<Byte> entity_ay=new jDataWatcherObject<>("ax", "Entity");
        public static final jDataWatcherObject<Integer> entity_az=new jDataWatcherObject<>("ay", "Entity");
        public static final jDataWatcherObject<String> entity_aA=new jDataWatcherObject<>("az", "Entity");
        public static final jDataWatcherObject<Boolean> entity_aB=new jDataWatcherObject<>("aA", "Entity");
        public static final jDataWatcherObject<Boolean> entity_aC=new jDataWatcherObject<>("aB", "Entity");
    instead of the 1.9.4 ones:
    Code (Text):
    public static final jDataWatcherObject<Byte> entity_ay=new jDataWatcherObject<>("ay", "Entity");
        public static final jDataWatcherObject<Integer> entity_az=new jDataWatcherObject<>("az", "Entity");
        public static final jDataWatcherObject<String> entity_aA=new jDataWatcherObject<>("aA", "Entity");
        public static final jDataWatcherObject<Boolean> entity_aB=new jDataWatcherObject<>("aB", "Entity");
        public static final jDataWatcherObject<Boolean> entity_aC=new jDataWatcherObject<>("aC", "Entity");
    And all works perfectly ! :)
     
    • Informative Informative x 1
  7. Thanks for noticing the error. I have adjusted the code so it now works on both 1.9.2 and 1.9.4 ;)
     
    • Winner Winner x 1
  8. Can you provide a better way to send the effect to the entire world, instead that on a per-player basis?
    Code (Text):
    public class FireworkSpawner {
     
        public static void spawn(Location location, FireworkEffect effect, Player...players){
            if(location==null||effect==null||players==null)return;
         
            // Add per-world support
            if (players.length == 0) {
                List<Player> list = location.getWorld().getPlayers();
                players = list.toArray(new Player[list.size()]);
            }

    ...
     
    #8 System, Jun 7, 2016
    Last edited: Jun 7, 2016
  9. As specified in the post, you can also send an array of players.
    I reckon I could add a method that converts a list to an array for you. Though that'll have to wait as I'm using my phone right now.
     
  10. Hex

    Hex
    IRC Staff

    Your naming conventions are killing me inside.
     
    • Agree Agree x 2
  11. I would just like to note that I have just added this method ;)

    What exactly do you mean?
     
  12. MiniDigger

    Supporter

    "PH_PO_EntityDestroy extends aPacketHandler"
    this is not how you name your classes normaly in the java world.
    I know that you uses PH and PO as shortcuts PacketHandler and PlayOut(?) but looking at the name does not tell an uninformed user what this class does, which is not want you want to have.
     
  13. I reckon that's just my way of coding then. Writing the entire name will spam the screen. Also, yap it means PacketHandler (PH) and PlayOut (PO)

    I will note it in the main post
     
  14. Just updated the source for 1.10 support ;)
     
  15. Geka

    Supporter

    I got this error:
    Code (Text):
    public static final jDataWatcherObject<Byte> entity_ay=new jDataWatcherObject<>("ax", "Entity");
        public static final jDataWatcherObject<Integer> entity_az=new jDataWatcherObject<>("ay", "Entity");
        public static final jDataWatcherObject<String> entity_aA=new jDataWatcherObject<>("az", "Entity");
        public static final jDataWatcherObject<Boolean> entity_aB=new jDataWatcherObject<>("aA", "Entity");
        public static final jDataWatcherObject<Boolean> entity_aC=new jDataWatcherObject<>("aB", "Entity");
     
  16. Wouldn't this be simpler like this ? :

    Code (Text):
                            int r = Integer.parseInt(f[0]);
                            int g = Integer.parseInt(f[1]);
                            int b = Integer.parseInt(f[2]);
                            String type = f[3];
                            FireworkEffect eff = FireworkEffect.builder().trail(false).flicker(false).withColor(Color.fromRGB(r, g, b)).with(Type.valueOf(type)).build();
                            Firework firework = e.getVictim().getWorld().spawn(e.getVictim().getLocation(), Firework.class);
                            FireworkMeta fwm = firework.getFireworkMeta();
                            fwm.clearEffects();
                            fwm.addEffect(eff);
                            firework.setFireworkMeta(fwm);
                            new BukkitRunnable() {
                                public void run() {
                                    firework.detonate();
                                }
                            }.runTaskLater(Commands.getPlugin(), 1);
     
    • Winner Winner x 1
  17. This code has, at least for me, never worked. It always launches a firework however never detonates it. Which is why I created the source above and posted it for public use.
     
    • Informative Informative x 1
  18. This is quite interesting.