├── .gitignore ├── imgs └── colors.png ├── benchmark └── test 400000 particles.png ├── ParticleNativeAPI-core └── src │ ├── test │ └── java │ │ └── com │ │ └── github │ │ └── fierioziy │ │ └── particlenativeapi │ │ └── core │ │ ├── mocks │ │ ├── nms │ │ │ ├── common │ │ │ │ ├── Packet.java │ │ │ │ ├── Entity.java │ │ │ │ └── ItemStack.java │ │ │ ├── v1_13 │ │ │ │ ├── IBlockData.java │ │ │ │ ├── ParticleParam.java │ │ │ │ ├── Particle.java │ │ │ │ ├── ParticleType.java │ │ │ │ ├── IBlockDataMock.java │ │ │ │ ├── Particles_1_13.java │ │ │ │ ├── ParticleParamBlock.java │ │ │ │ ├── ParticleParamRedstone_1_13.java │ │ │ │ ├── ParticleParamItem.java │ │ │ │ └── PacketPlayOutWorldParticles_1_13.java │ │ │ ├── v1_17 │ │ │ │ ├── PositionSource.java │ │ │ │ ├── EntityPlayer_1_17.java │ │ │ │ ├── BlockPositionSource.java │ │ │ │ ├── BlockPosition.java │ │ │ │ ├── MinecraftKey.java │ │ │ │ ├── EntityPositionSource_1_17.java │ │ │ │ ├── VibrationPath.java │ │ │ │ ├── VibrationParticleOption_1_17.java │ │ │ │ ├── PlayerConnection_1_17.java │ │ │ │ ├── ParticleParamRedstone_1_17.java │ │ │ │ ├── Particles_1_17.java │ │ │ │ ├── DustColorTransitionOptions_1_17.java │ │ │ │ └── IRegistry_1_17.java │ │ │ ├── v1_20_2 │ │ │ │ ├── PlayerConnection_1_20_2.java │ │ │ │ ├── EntityPlayer_1_20_2.java │ │ │ │ └── ServerCommonPacketListenerImpl_1_20_2.java │ │ │ ├── v1_8 │ │ │ │ ├── EnumParticle.java │ │ │ │ └── PacketPlayOutWorldParticles_1_8.java │ │ │ ├── v1_19_3 │ │ │ │ ├── IRegistry_1_19_3.java │ │ │ │ ├── ParticleParamRedstone_1_19_3.java │ │ │ │ ├── DustColorTransitionOptions_1_19_3.java │ │ │ │ └── BuiltInRegistries.java │ │ │ ├── v1_7 │ │ │ │ ├── PlayerConnection_1_7.java │ │ │ │ ├── EntityPlayer_1_7.java │ │ │ │ └── PacketPlayOutWorldParticles_1_7.java │ │ │ ├── v1_18 │ │ │ │ ├── EntityPlayer_1_18.java │ │ │ │ ├── PlayerConnection_1_18.java │ │ │ │ └── Particles_1_18.java │ │ │ ├── v1_19 │ │ │ │ ├── ShriekParticleOption.java │ │ │ │ ├── SculkChargeParticleOptions.java │ │ │ │ ├── EntityPositionSource_1_19.java │ │ │ │ ├── VibrationParticleOption_1_19.java │ │ │ │ └── Particles_1_19.java │ │ │ ├── v1_21_3 │ │ │ │ ├── ParticleParamRedstone_1_21_3.java │ │ │ │ └── DustColorTransitionOptions_1_21_3.java │ │ │ ├── v1_20_5 │ │ │ │ ├── ServerCommonPacketListenerImpl_1_20_5.java │ │ │ │ ├── ColorParticleOption.java │ │ │ │ └── Particles_1_20_5.java │ │ │ ├── v1_15 │ │ │ │ └── PacketPlayOutWorldParticles_1_15.java │ │ │ ├── v1_21_10 │ │ │ │ ├── PowerParticleOption.java │ │ │ │ ├── SpellParticleOption.java │ │ │ │ └── Particles_1_21_10.java │ │ │ └── v1_21_4 │ │ │ │ └── PacketPlayOutWorldParticles_1_21_4.java │ │ ├── mojang │ │ │ └── common │ │ │ │ ├── Vector3f.java │ │ │ │ └── Vector3fa.java │ │ ├── obc │ │ │ ├── v1_13 │ │ │ │ ├── inventory │ │ │ │ │ └── CraftItemStack.java │ │ │ │ └── block │ │ │ │ │ └── data │ │ │ │ │ └── CraftBlockData.java │ │ │ ├── common │ │ │ │ └── CraftEntity.java │ │ │ ├── v1_7 │ │ │ │ └── entity │ │ │ │ │ └── CraftPlayer_1_7.java │ │ │ ├── v1_17 │ │ │ │ └── entity │ │ │ │ │ └── CraftPlayer_1_17.java │ │ │ ├── v1_18 │ │ │ │ └── entity │ │ │ │ │ └── CraftPlayer_1_18.java │ │ │ └── v1_20_2 │ │ │ │ └── entity │ │ │ │ └── CraftPlayer_1_20_2.java │ │ ├── StaticMock.java │ │ └── StaticMockServerExtension.java │ │ ├── particle │ │ └── type │ │ │ ├── ParticleTypeItemMotionTest.java │ │ │ ├── CraftBlockDataMock.java │ │ │ ├── ParticleTypeBlockTest.java │ │ │ ├── ParticleTypeSpellTest.java │ │ │ ├── FakePacket.java │ │ │ ├── ParticleTypeBlockMotionTest.java │ │ │ └── ParticleTypeColorTest.java │ │ ├── asm │ │ └── particle │ │ │ └── type │ │ │ └── ParticleTypesUtils.java │ │ ├── SpigotClassRegistryProvider_1_7.java │ │ └── SpigotClassRegistryProvider_1_8.java │ └── main │ └── java │ └── com │ └── github │ └── fierioziy │ └── particlenativeapi │ └── core │ ├── asm │ ├── mapping │ │ ├── SpigotClassRegistryProvider.java │ │ ├── ClassMapping.java │ │ └── RegisteredClassMapping.java │ ├── packet │ │ ├── ParticlePacketProvider.java │ │ ├── ParticlePacketProvider_1_7.java │ │ ├── ParticlePacketProvider_1_17.java │ │ └── ParticlePacketProvider_1_20_2.java │ ├── utils │ │ ├── SpigotParticleVersion.java │ │ └── SpigotVersion.java │ ├── particle │ │ ├── type │ │ │ ├── ParticleTypesProvider.java │ │ │ ├── v1_17 │ │ │ │ ├── skeleton │ │ │ │ │ ├── ParticleTypeSimpleSkeletonASM_1_17.java │ │ │ │ │ └── ParticleTypeComplexSkeletonASM_1_17.java │ │ │ │ └── ParticleTypeDustASM_1_17.java │ │ │ ├── v1_7 │ │ │ │ └── skeleton │ │ │ │ │ └── ParticleTypeComplexSkeletonASM_1_7.java │ │ │ ├── v1_13 │ │ │ │ ├── skeleton │ │ │ │ │ └── ParticleTypeComplexSkeletonASM_1_13.java │ │ │ │ └── ParticleTypeDustASM_1_13.java │ │ │ ├── skeleton │ │ │ │ ├── ParticleTypeSimpleSkeletonASM.java │ │ │ │ └── ParticleTypeComplexSkeletonASM.java │ │ │ ├── v1_8 │ │ │ │ ├── skeleton │ │ │ │ │ └── ParticleTypeComplexSkeletonASM_1_8.java │ │ │ │ └── ParticleTypeItemASM_1_8.java │ │ │ ├── v1_19 │ │ │ │ ├── ParticleTypeShriekASM_1_19.java │ │ │ │ └── ParticleTypeSculkChargeASM_1_19.java │ │ │ └── v1_19_3 │ │ │ │ └── ParticleTypeDustASM_1_19_3.java │ │ ├── ParticleListASM.java │ │ └── ParticleListProvider.java │ ├── BaseASM.java │ └── skeleton │ │ └── ClassSkeletonASM.java │ ├── ParticleNativeAPI_Impl.java │ ├── particle │ └── type │ │ ├── ParticleTypeShriekImpl.java │ │ ├── ParticleTypeItemMotionImpl.java │ │ ├── ParticleTypePowerMotionImpl.java │ │ ├── ParticleTypeSculkChargeMotionImpl.java │ │ ├── ParticleTypeBlockImpl.java │ │ ├── ParticleTypeBlockMotionImpl.java │ │ ├── ParticleTypeSpellImpl.java │ │ ├── ParticleTypeColorImpl.java │ │ ├── ParticleTypeVibrationImpl.java │ │ ├── ParticleTypeDustFloatImpl.java │ │ ├── ParticleTypeDustIntImpl.java │ │ ├── ParticleTypeDustColorTransitionFloatImpl.java │ │ ├── ParticleTypeDustColorTransitionIntImpl.java │ │ ├── ParticleTypeMotionImpl.java │ │ ├── ParticleTypeColorableImpl.java │ │ └── ParticleTypeVibrationSingleImpl.java │ └── utils │ └── ParticleNativeClassLoader.java ├── ParticleNativeAPI-plugin └── src │ ├── main │ └── resources │ │ └── plugin.yml │ └── assembly │ └── dist.xml ├── ParticleNativeAPI-plugin-benchmark └── src │ └── main │ ├── java │ └── com │ │ └── github │ │ └── fierioziy │ │ └── particlenativebenchmark │ │ ├── spawners │ │ ├── ParticleSpawner.java │ │ ├── ParticleSpawnerSpigot.java │ │ ├── ParticleSpawnerPNA.java │ │ ├── ParticleSpawnerNMS.java │ │ └── ParticleSpawnerReflection.java │ │ ├── command │ │ └── BenchmarkCase.java │ │ └── ParticleNativeBenchmarkPlugin.java │ └── resources │ └── plugin.yml ├── ParticleNativeAPI-plugin-test └── src │ └── main │ ├── resources │ └── plugin.yml │ └── java │ └── com │ └── github │ └── fierioziy │ └── particlenativetest │ ├── command │ └── utils │ │ ├── ParticleListFields_1_19.java │ │ ├── SneakToggle.java │ │ └── ParticleListFields_1_8.java │ └── ParticleNativeTestPlugin.java ├── ParticleNativeAPI-api ├── src │ └── main │ │ └── java │ │ └── com │ │ └── github │ │ └── fierioziy │ │ └── particlenativeapi │ │ └── api │ │ ├── utils │ │ ├── ParticleException.java │ │ └── Shared.java │ │ └── particle │ │ ├── ParticleSupplier_1_19_Part.java │ │ ├── type │ │ ├── ParticleTypeShriek.java │ │ ├── ParticleTypePowerMotion.java │ │ ├── ParticleTypeItemMotion.java │ │ ├── ParticleTypeSculkChargeMotion.java │ │ ├── ParticleTypeSpell.java │ │ ├── ParticleTypeBlock.java │ │ └── ParticleTypeBlockMotion.java │ │ └── ParticleList_1_19_Part.java └── pom.xml ├── LICENSE.txt └── License-ASM.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/* 2 | **/target/* 3 | *.bat 4 | *.iml 5 | *.xml 6 | !**/pom.xml -------------------------------------------------------------------------------- /imgs/colors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fierioziy/ParticleNativeAPI/HEAD/imgs/colors.png -------------------------------------------------------------------------------- /benchmark/test 400000 particles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fierioziy/ParticleNativeAPI/HEAD/benchmark/test 400000 particles.png -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/common/Packet.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.common; 2 | 3 | public interface Packet {} 4 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_13/IBlockData.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13; 2 | 3 | public interface IBlockData {} 4 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_13/ParticleParam.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13; 2 | 3 | public interface ParticleParam {} 4 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_17/PositionSource.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17; 2 | 3 | public interface PositionSource { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_13/Particle.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13; 2 | 3 | public class Particle implements ParticleParam {} 4 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_13/ParticleType.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13; 2 | 3 | public class ParticleType extends Particle { 4 | } 5 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/mapping/SpigotClassRegistryProvider.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.mapping; 2 | 3 | public interface SpigotClassRegistryProvider { 4 | SpigotClassRegistry provideRegistry(); 5 | } 6 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/mapping/ClassMapping.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.mapping; 2 | 3 | public interface ClassMapping { 4 | String internalName(); 5 | String className(); 6 | String desc(); 7 | } 8 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeItemMotionTest.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | public class ParticleTypeItemMotionTest { 4 | /* 5 | Nothing to test here yet 6 | */ 7 | } 8 | -------------------------------------------------------------------------------- /ParticleNativeAPI-plugin/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: ParticleNativeAPI 2 | version: ${project.version} 3 | main: com.github.fierioziy.particlenativeapi.plugin.ParticleNativePlugin 4 | 5 | author: Fierioziy 6 | description: "Provides API for spawning particles." 7 | 8 | load: STARTUP 9 | api-version: "1.13" -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_20_2/PlayerConnection_1_20_2.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_20_2; 2 | 3 | public class PlayerConnection_1_20_2 extends ServerCommonPacketListenerImpl_1_20_2 { 4 | 5 | public PlayerConnection_1_20_2() {} 6 | 7 | } 8 | -------------------------------------------------------------------------------- /ParticleNativeAPI-plugin-benchmark/src/main/java/com/github/fierioziy/particlenativebenchmark/spawners/ParticleSpawner.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativebenchmark.spawners; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | public interface ParticleSpawner { 6 | 7 | void spawnParticle(Player player, double x, double y, double z); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_8/EnumParticle.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_8; 2 | 3 | public enum EnumParticle { 4 | LAVA, 5 | FALLING_DUST, 6 | BLOCK_CRACK, 7 | SPELL_MOB, 8 | ITEM_CRACK, 9 | FLAME, 10 | NOTE, 11 | REDSTONE 12 | } 13 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/common/Entity.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.common; 2 | 3 | public class Entity { 4 | 5 | public double x, y, z; 6 | 7 | public Entity(double x, double y, double z) { 8 | this.x = x; 9 | this.y = y; 10 | this.z = z; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_19_3/IRegistry_1_19_3.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_19_3; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17.MinecraftKey; 4 | 5 | public interface IRegistry_1_19_3 { 6 | 7 | MinecraftKey getKey_possiblyObfuscated(T paramT); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/mojang/common/Vector3f.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.mojang.common; 2 | 3 | public class Vector3f { 4 | 5 | public float x, y, z; 6 | 7 | public Vector3f(float x, float y, float z) { 8 | this.x = x; 9 | this.y = y; 10 | this.z = z; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/mojang/common/Vector3fa.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.mojang.common; 2 | 3 | public class Vector3fa { 4 | 5 | public float x, y, z; 6 | 7 | public Vector3fa(float x, float y, float z) { 8 | this.x = x; 9 | this.y = y; 10 | this.z = z; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/common/ItemStack.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.common; 2 | 3 | public class ItemStack { 4 | 5 | public org.bukkit.inventory.ItemStack bukkitStack; 6 | 7 | public ItemStack(org.bukkit.inventory.ItemStack bukkitStack) { 8 | this.bukkitStack = bukkitStack; 9 | } 10 | 11 | 12 | } 13 | -------------------------------------------------------------------------------- /ParticleNativeAPI-plugin-benchmark/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: ParticleNativeAPI-benchmark 2 | version: ${project.version} 3 | main: com.github.fierioziy.particlenativebenchmark.ParticleNativeBenchmarkPlugin 4 | 5 | author: Fierioziy 6 | description: "ParticleNativeAPI benchmark plugin" 7 | 8 | load: STARTUP 9 | api-version: "1.13" 10 | commands: 11 | pnab: 12 | description: "Measures execution time of particle spawning" -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_7/PlayerConnection_1_7.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_7; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.common.Packet; 4 | 5 | public class PlayerConnection_1_7 { 6 | 7 | public PlayerConnection_1_7() {} 8 | 9 | // required 10 | public void sendPacket(Packet packet) {} 11 | } 12 | -------------------------------------------------------------------------------- /ParticleNativeAPI-plugin-test/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: ParticleNativeAPI-test 2 | version: ${project.version} 3 | main: com.github.fierioziy.particlenativetest.ParticleNativeTestPlugin 4 | 5 | author: Fierioziy 6 | description: "ParticleNativeAPI test plugin" 7 | 8 | load: STARTUP 9 | api-version: "1.13" 10 | commands: 11 | pnat: 12 | description: "Spawns all particles (except irritating ones) with different methods" 13 | pnal: 14 | description: "Spawns redstone color spectrum used as logo front image on websites" -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/obc/v1_13/inventory/CraftItemStack.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.obc.v1_13.inventory; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.common.ItemStack; 4 | 5 | public class CraftItemStack { 6 | 7 | public static ItemStack nmsItemStack = null; 8 | 9 | // required 10 | public static ItemStack asNMSCopy(org.bukkit.inventory.ItemStack bukkitStack) { 11 | return nmsItemStack; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/packet/ParticlePacketProvider.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.packet; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.BaseASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 5 | 6 | public abstract class ParticlePacketProvider extends BaseASM { 7 | 8 | public ParticlePacketProvider(ContextASM context) { 9 | super(context); 10 | } 11 | 12 | public abstract void registerClasses(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_7/EntityPlayer_1_7.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_7; 2 | 3 | public class EntityPlayer_1_7 { 4 | 5 | public double x, y, z; 6 | 7 | // required 8 | public PlayerConnection_1_7 playerConnection; 9 | 10 | public EntityPlayer_1_7(PlayerConnection_1_7 pc, double x, double y, double z) { 11 | this.playerConnection = pc; 12 | this.x = x; 13 | this.y = y; 14 | this.z = z; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_17/EntityPlayer_1_17.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17; 2 | 3 | public class EntityPlayer_1_17 { 4 | 5 | public double x, y, z; 6 | 7 | // required 8 | public PlayerConnection_1_17 playerConnection; 9 | 10 | public EntityPlayer_1_17(PlayerConnection_1_17 pc, double x, double y, double z) { 11 | this.playerConnection = pc; 12 | this.x = x; 13 | this.y = y; 14 | this.z = z; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_18/EntityPlayer_1_18.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_18; 2 | 3 | public class EntityPlayer_1_18 { 4 | 5 | public double x, y, z; 6 | 7 | // required 8 | public PlayerConnection_1_18 playerConnection_obf; 9 | 10 | public EntityPlayer_1_18(PlayerConnection_1_18 pc, double x, double y, double z) { 11 | this.playerConnection_obf = pc; 12 | this.x = x; 13 | this.y = y; 14 | this.z = z; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ParticleNativeAPI-plugin-test/src/main/java/com/github/fierioziy/particlenativetest/command/utils/ParticleListFields_1_19.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativetest.command.utils; 2 | 3 | public class ParticleListFields_1_19 { 4 | 5 | public static final String[] FIELDS = { 6 | // 1.19 7 | "VIBRATION", 8 | 9 | // 1.20.5 10 | "ENTITY_EFFECT", 11 | 12 | // 1.21.10 13 | "FLASH", 14 | "DRAGON_BREATH", 15 | "EFFECT", 16 | "INSTANT_EFFECT", 17 | }; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_20_2/EntityPlayer_1_20_2.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_20_2; 2 | 3 | public class EntityPlayer_1_20_2 { 4 | 5 | public double x, y, z; 6 | 7 | // required 8 | public PlayerConnection_1_20_2 playerConnection_obf; 9 | 10 | public EntityPlayer_1_20_2(PlayerConnection_1_20_2 pc, double x, double y, double z) { 11 | this.playerConnection_obf = pc; 12 | this.x = x; 13 | this.y = y; 14 | this.z = z; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ParticleNativeAPI-api/src/main/java/com/github/fierioziy/particlenativeapi/api/utils/ParticleException.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.api.utils; 2 | 3 | public class ParticleException extends RuntimeException { 4 | 5 | public ParticleException() { 6 | super(); 7 | } 8 | 9 | public ParticleException(String message) { 10 | super(message); 11 | } 12 | 13 | public ParticleException(String message, Throwable cause) { 14 | super(message, cause); 15 | } 16 | 17 | public ParticleException(Throwable cause) { 18 | super(cause); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/obc/common/CraftEntity.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.obc.common; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.common.Entity; 4 | 5 | /* 6 | It has to be abstract, we don't want to implement tons of Player's methods. 7 | */ 8 | public abstract class CraftEntity implements org.bukkit.entity.Entity { 9 | 10 | public Entity entity; 11 | 12 | public CraftEntity() {} 13 | 14 | // required 15 | public Entity getHandle() { 16 | return entity; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_17/BlockPositionSource.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17; 2 | 3 | public class BlockPositionSource implements PositionSource { 4 | 5 | public BlockPosition pos; 6 | 7 | public BlockPositionSource(BlockPosition pos) { 8 | this.pos = pos; 9 | } 10 | 11 | @Override 12 | public boolean equals(Object obj) { 13 | if (!(obj instanceof BlockPositionSource)) return false; 14 | 15 | BlockPositionSource param = (BlockPositionSource) obj; 16 | 17 | return pos.equals(param.pos); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_17/BlockPosition.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17; 2 | 3 | public class BlockPosition { 4 | 5 | public int x, y, z; 6 | 7 | public BlockPosition(int x, int y, int z) { 8 | this.x = x; 9 | this.y = y; 10 | this.z = z; 11 | } 12 | 13 | @Override 14 | public boolean equals(Object obj) { 15 | if (!(obj instanceof BlockPosition)) { 16 | return false; 17 | } 18 | 19 | BlockPosition param = (BlockPosition) obj; 20 | 21 | return x == param.x && y == param.y && z == param.z; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_17/MinecraftKey.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17; 2 | 3 | public class MinecraftKey { 4 | 5 | public String namespace = "minecraft"; 6 | public String key; 7 | 8 | public MinecraftKey(String key) { 9 | this.key = key; 10 | } 11 | 12 | public String getNamespace_possiblyObfuscated() { 13 | return namespace; 14 | } 15 | 16 | public String getKey_possiblyObfuscated() { 17 | return key; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return namespace + ":" + key; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ParticleNativeAPI-plugin-benchmark/src/main/java/com/github/fierioziy/particlenativebenchmark/spawners/ParticleSpawnerSpigot.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativebenchmark.spawners; 2 | 3 | import com.github.fierioziy.particlenativebenchmark.command.CommandPNAB; 4 | import org.bukkit.Particle; 5 | import org.bukkit.entity.Player; 6 | 7 | public class ParticleSpawnerSpigot implements ParticleSpawner { 8 | 9 | public ParticleSpawnerSpigot(CommandPNAB.Context context) { 10 | 11 | } 12 | 13 | @Override 14 | public void spawnParticle(Player player, double x, double y, double z) { 15 | player.spawnParticle(Particle.FLAME, x, y, z, 1, 0D, 0D, 0D, 0D); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_17/EntityPositionSource_1_17.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17; 2 | 3 | public class EntityPositionSource_1_17 implements PositionSource { 4 | 5 | public int entityId; 6 | 7 | public EntityPositionSource_1_17(int entityId) { 8 | this.entityId = entityId; 9 | } 10 | 11 | @Override 12 | public boolean equals(Object obj) { 13 | if (!(obj instanceof EntityPositionSource_1_17)) return false; 14 | 15 | EntityPositionSource_1_17 param = (EntityPositionSource_1_17) obj; 16 | 17 | return entityId == param.entityId; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_19/ShriekParticleOption.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_19; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleParam; 4 | 5 | public class ShriekParticleOption implements ParticleParam { 6 | 7 | public int delay; 8 | 9 | public ShriekParticleOption(int delay) { 10 | this.delay = delay; 11 | } 12 | 13 | @Override 14 | public boolean equals(Object obj) { 15 | if (!(obj instanceof ShriekParticleOption)) return false; 16 | 17 | ShriekParticleOption param = (ShriekParticleOption) obj; 18 | 19 | return delay == param.delay; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/obc/v1_13/block/data/CraftBlockData.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.obc.v1_13.block.data; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.IBlockData; 4 | import org.bukkit.block.data.BlockData; 5 | 6 | public abstract class CraftBlockData implements BlockData { 7 | 8 | public IBlockData iBlockData; 9 | 10 | @Override 11 | public BlockData clone() { 12 | return forwardCloneSoMockitoWontComplain(); 13 | } 14 | 15 | public abstract BlockData forwardCloneSoMockitoWontComplain(); 16 | 17 | // required 18 | public IBlockData getState() { 19 | return iBlockData; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /ParticleNativeAPI-api/src/main/java/com/github/fierioziy/particlenativeapi/api/utils/Shared.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.api.utils; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | *

Indicates that returned object is one and the same instance with changed state 10 | * and is shared between method calls.

11 | * 12 | *

Generally, any element annotated with this annotation provides a detachCopy method 13 | * to create an independent copy of that element.

14 | */ 15 | @Target({ElementType.TYPE_USE}) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | public @interface Shared { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_13/IBlockDataMock.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13; 2 | 3 | import org.bukkit.Material; 4 | 5 | public class IBlockDataMock implements IBlockData { 6 | 7 | // non-existent, used for equality checks 8 | public final Material material; 9 | 10 | public IBlockDataMock(Material material) { 11 | this.material = material; 12 | } 13 | 14 | @Override 15 | public boolean equals(Object o) { 16 | if (this == o) return true; 17 | if (!(o instanceof IBlockDataMock)) return false; 18 | 19 | IBlockDataMock that = (IBlockDataMock) o; 20 | 21 | return material == that.material; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/packet/ParticlePacketProvider_1_7.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.packet; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 5 | import com.github.fierioziy.particlenativeapi.core.asm.packet.v1_7.ParticlePacketASM_1_7; 6 | 7 | public class ParticlePacketProvider_1_7 extends ParticlePacketProvider { 8 | 9 | public ParticlePacketProvider_1_7(ContextASM context) { 10 | super(context); 11 | } 12 | 13 | @Override 14 | public void registerClasses() { 15 | new ParticlePacketASM_1_7(context, ClassSkeleton.PARTICLE_PACKET).registerClass(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/ParticleNativeAPI_Impl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.ParticleNativeAPI; 4 | 5 | import java.lang.reflect.Constructor; 6 | import java.lang.reflect.InvocationTargetException; 7 | 8 | class ParticleNativeAPI_Impl extends ParticleNativeAPI { 9 | 10 | public ParticleNativeAPI_Impl(Constructor particleList_1_8_ctor, 11 | Constructor particleList_1_13_ctor, 12 | Constructor particleList_1_19_part_ctor) 13 | throws ReflectiveOperationException { 14 | 15 | super(particleList_1_8_ctor, particleList_1_13_ctor, particleList_1_19_part_ctor); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_17/VibrationPath.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17; 2 | 3 | public class VibrationPath { 4 | 5 | public BlockPosition pos; 6 | public PositionSource source; 7 | public int ticks; 8 | 9 | public VibrationPath(BlockPosition pos, PositionSource source, int ticks) { 10 | this.pos = pos; 11 | this.source = source; 12 | this.ticks = ticks; 13 | } 14 | 15 | @Override 16 | public boolean equals(Object obj) { 17 | if (!(obj instanceof VibrationPath)) return false; 18 | 19 | VibrationPath param = (VibrationPath) obj; 20 | 21 | return pos.equals(param.pos) && source.equals(param.source) && ticks == param.ticks; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeShriekImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleType; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeShriek; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | 7 | public class ParticleTypeShriekImpl implements ParticleTypeShriek { 8 | 9 | @Override 10 | public ParticleType delay(int delay) { 11 | throw new ParticleException( 12 | "Requested particle type is not supported by this server version!" 13 | ); 14 | } 15 | 16 | @Override 17 | public boolean isPresent() { 18 | return false; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_17/VibrationParticleOption_1_17.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleParam; 4 | 5 | public class VibrationParticleOption_1_17 implements ParticleParam { 6 | 7 | private VibrationPath path; 8 | 9 | public VibrationParticleOption_1_17(VibrationPath path) { 10 | this.path = path; 11 | } 12 | 13 | @Override 14 | public boolean equals(Object obj) { 15 | if (!(obj instanceof VibrationParticleOption_1_17)) { 16 | return false; 17 | } 18 | 19 | VibrationParticleOption_1_17 param = (VibrationParticleOption_1_17) obj; 20 | return path.equals(param.path); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_13/Particles_1_13.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13; 2 | 3 | public class Particles_1_13 { 4 | public static ParticleType LAVA = new ParticleType(); 5 | public static Particle FALLING_DUST = new ParticleType(); 6 | public static Particle BLOCK = new ParticleType(); 7 | public static ParticleType ENTITY_EFFECT = new ParticleType(); 8 | public static Particle DUST = new ParticleType(); 9 | public static Particle ITEM = new ParticleType(); 10 | public static ParticleType FLAME = new ParticleType(); 11 | public static ParticleType NOTE = new ParticleType(); 12 | public static ParticleType DRAGON_BREATH = new ParticleType(); 13 | public static ParticleType EFFECT = new ParticleType(); 14 | } 15 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeItemMotionImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeItemMotion; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeMotion; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | import org.bukkit.Material; 7 | 8 | public class ParticleTypeItemMotionImpl implements ParticleTypeItemMotion { 9 | 10 | public ParticleTypeMotion of(Material item) { 11 | throw new ParticleException( 12 | "Requested particle type is not supported by this server version!" 13 | ); 14 | } 15 | 16 | public boolean isPresent() { 17 | return false; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_19/SculkChargeParticleOptions.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_19; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleParam; 4 | 5 | // its a record tho, but we don't access it directly so it should be a problem 6 | public class SculkChargeParticleOptions implements ParticleParam { 7 | 8 | public float roll; 9 | 10 | public SculkChargeParticleOptions(float roll) { 11 | this.roll = roll; 12 | } 13 | 14 | @Override 15 | public boolean equals(Object obj) { 16 | if (!(obj instanceof SculkChargeParticleOptions)) return false; 17 | 18 | SculkChargeParticleOptions param = (SculkChargeParticleOptions) obj; 19 | 20 | return roll == param.roll; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypePowerMotionImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeMotion; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypePowerMotion; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | 7 | public class ParticleTypePowerMotionImpl implements ParticleTypePowerMotion { 8 | 9 | @Override 10 | public ParticleTypeMotion power(double power) { 11 | throw new ParticleException( 12 | "Requested particle type is not supported by this server version!" 13 | ); 14 | } 15 | 16 | @Override 17 | public boolean isPresent() { 18 | return false; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /ParticleNativeAPI-plugin-benchmark/src/main/java/com/github/fierioziy/particlenativebenchmark/spawners/ParticleSpawnerPNA.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativebenchmark.spawners; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.ParticleNativeAPI; 4 | import com.github.fierioziy.particlenativebenchmark.command.CommandPNAB; 5 | import org.bukkit.entity.Player; 6 | 7 | public class ParticleSpawnerPNA implements ParticleSpawner { 8 | 9 | private final ParticleNativeAPI particleApi; 10 | 11 | public ParticleSpawnerPNA(CommandPNAB.Context context) { 12 | this.particleApi = context.getParticleApi(); 13 | } 14 | 15 | @Override 16 | public void spawnParticle(Player player, double x, double y, double z) { 17 | particleApi.LIST_1_8.FLAME 18 | .packet(true, x, y, z) 19 | .sendTo(player); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_13/ParticleParamBlock.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13; 2 | 3 | public class ParticleParamBlock implements ParticleParam { 4 | 5 | public Particle particle; 6 | public IBlockData blockData; 7 | 8 | // required 9 | public ParticleParamBlock(Particle particle, IBlockData blockData) { 10 | this.particle = particle; 11 | this.blockData = blockData; 12 | } 13 | 14 | // simple reference compare 15 | @Override 16 | public boolean equals(Object obj) { 17 | if (!(obj instanceof ParticleParamBlock)) { 18 | return false; 19 | } 20 | 21 | ParticleParamBlock param = (ParticleParamBlock) obj; 22 | return particle == param.particle && blockData == param.blockData; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeSculkChargeMotionImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeMotion; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeSculkChargeMotion; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | 7 | public class ParticleTypeSculkChargeMotionImpl implements ParticleTypeSculkChargeMotion { 8 | 9 | @Override 10 | public ParticleTypeMotion roll(double roll) { 11 | throw new ParticleException( 12 | "Requested particle type is not supported by this server version!" 13 | ); 14 | } 15 | 16 | @Override 17 | public boolean isPresent() { 18 | return false; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/particle/type/CraftBlockDataMock.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.IBlockDataMock; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.obc.v1_13.block.data.CraftBlockData; 5 | import org.bukkit.Material; 6 | 7 | import static org.mockito.Mockito.mock; 8 | import static org.mockito.Mockito.when; 9 | 10 | public abstract class CraftBlockDataMock { 11 | 12 | private CraftBlockDataMock() {} 13 | 14 | public static CraftBlockData of(Material material) { 15 | CraftBlockData craftBlockDataMock = mock(CraftBlockData.class); 16 | craftBlockDataMock.iBlockData = new IBlockDataMock(material); 17 | when(craftBlockDataMock.getState()).thenCallRealMethod(); 18 | 19 | return craftBlockDataMock; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/utils/SpigotParticleVersion.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.utils; 2 | 3 | /** 4 | *

An enum used by {@link ParticleNode} class to store 5 | * particle version.

6 | * 7 | *

It is used to represent a change in particle names (for ex. in field, enum 8 | * or string) between Minecraft updates.

9 | * 10 | *

It also provides interface class associated with certain 11 | * particle version for easier generation.

12 | */ 13 | public enum SpigotParticleVersion { 14 | 15 | V1_7, V1_8, V1_13, V1_18, V1_20_5; 16 | 17 | public static final SpigotParticleVersion INITIAL_VERSION; 18 | public static final int VERSION_COUNT; 19 | 20 | static { 21 | SpigotParticleVersion[] values = SpigotParticleVersion.values(); 22 | 23 | INITIAL_VERSION = values[0]; 24 | VERSION_COUNT = values.length; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /ParticleNativeAPI-api/src/main/java/com/github/fierioziy/particlenativeapi/api/particle/ParticleSupplier_1_19_Part.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.api.particle; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.*; 4 | 5 | abstract class ParticleSupplier_1_19_Part { 6 | 7 | /* 8 | Methods below are overridden by dynamically generated subclasses. 9 | Their purpose is to be "factory" for fields with either particle type valid implementation 10 | or it's invalid dummy variant. 11 | */ 12 | 13 | // 1.19 14 | protected abstract ParticleTypeVibration VIBRATION(); 15 | 16 | // 1.20.5 17 | protected abstract ParticleTypeColor ENTITY_EFFECT(); 18 | 19 | // 1.21.10 20 | protected abstract ParticleTypeColor FLASH(); 21 | protected abstract ParticleTypePowerMotion DRAGON_BREATH(); 22 | protected abstract ParticleTypeSpell EFFECT(); 23 | protected abstract ParticleTypeSpell INSTANT_EFFECT(); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/utils/SpigotVersion.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.utils; 2 | 3 | public enum SpigotVersion { 4 | 5 | V1_7("_1_7"), 6 | V1_8("_1_8"), 7 | V1_13("_1_13"), 8 | V1_15("_1_15"), 9 | V1_17("_1_17"), 10 | V1_18("_1_18"), 11 | V1_19("_1_19"), 12 | V1_19_3("_1_19_3"), 13 | V1_20_2("_1_20_2"), 14 | V1_20_5("_1_20_5"), 15 | V1_21_3("_1_21_3"), 16 | V1_21_4("_1_21_4"), 17 | V1_21_10("_1_21_10"), 18 | V1_21_11("_1_21_11"), 19 | ; 20 | 21 | private final String suffix; 22 | 23 | SpigotVersion(String suffix) { 24 | this.suffix = suffix; 25 | } 26 | 27 | public String getSuffix() { 28 | return suffix; 29 | } 30 | 31 | public boolean between(SpigotVersion lower, SpigotVersion higher) { 32 | return ordinal() >= lower.ordinal() && ordinal() <= higher.ordinal(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_19/EntityPositionSource_1_19.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_19; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.common.Entity; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17.PositionSource; 5 | 6 | public class EntityPositionSource_1_19 implements PositionSource { 7 | 8 | public Entity entity; 9 | public float yOffset; 10 | 11 | public EntityPositionSource_1_19(Entity entity, float yOffset) { 12 | this.entity = entity; 13 | this.yOffset = yOffset; 14 | } 15 | 16 | @Override 17 | public boolean equals(Object obj) { 18 | if (!(obj instanceof EntityPositionSource_1_19)) return false; 19 | 20 | EntityPositionSource_1_19 param = (EntityPositionSource_1_19) obj; 21 | 22 | return entity == param.entity && yOffset == param.yOffset; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/obc/v1_7/entity/CraftPlayer_1_7.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.obc.v1_7.entity; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_7.EntityPlayer_1_7; 4 | import org.bukkit.Location; 5 | import org.bukkit.entity.Player; 6 | 7 | /* 8 | It has to be abstract, we don't want to implement tons of Player's methods. 9 | */ 10 | public abstract class CraftPlayer_1_7 implements Player { 11 | 12 | public String name; 13 | public EntityPlayer_1_7 ep; 14 | 15 | public CraftPlayer_1_7() {} 16 | 17 | // required 18 | public EntityPlayer_1_7 getHandle() { 19 | return ep; 20 | } 21 | 22 | // required 23 | @Override 24 | public Location getLocation() { 25 | return new Location(null, ep.x, ep.y, ep.z); 26 | } 27 | 28 | @Override 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_17/PlayerConnection_1_17.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.common.Packet; 4 | 5 | import java.util.Optional; 6 | 7 | public class PlayerConnection_1_17 { 8 | 9 | public PlayerConnection_1_17() {} 10 | 11 | /* 12 | * Some spigot/bukkit forks contains lambda method with matching types 13 | * same as send(Packet) method. 14 | * Here, this certain behavior is reproduced. 15 | * 16 | * Compiler will generate a synthetic method representing lambda 17 | * with same signature as sendPacket(Packet) method. 18 | */ 19 | 20 | public void doLambdaStuff() { 21 | Optional.empty().ifPresent(packet -> { 22 | String quack = "Moo"; 23 | }); 24 | } 25 | 26 | // required 27 | public void sendPacket(Packet packet) {} 28 | } 29 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/obc/v1_17/entity/CraftPlayer_1_17.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.obc.v1_17.entity; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17.EntityPlayer_1_17; 4 | import org.bukkit.Location; 5 | import org.bukkit.entity.Player; 6 | 7 | /* 8 | It has to be abstract, we don't want to implement tons of Player's methods. 9 | */ 10 | public abstract class CraftPlayer_1_17 implements Player { 11 | 12 | public String name; 13 | public EntityPlayer_1_17 ep; 14 | 15 | public CraftPlayer_1_17() {} 16 | 17 | // required 18 | public EntityPlayer_1_17 getHandle() { 19 | return ep; 20 | } 21 | 22 | // required 23 | @Override 24 | public Location getLocation() { 25 | return new Location(null, ep.x, ep.y, ep.z); 26 | } 27 | 28 | @Override 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/obc/v1_18/entity/CraftPlayer_1_18.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.obc.v1_18.entity; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_18.EntityPlayer_1_18; 4 | import org.bukkit.Location; 5 | import org.bukkit.entity.Player; 6 | 7 | /* 8 | It has to be abstract, we don't want to implement tons of Player's methods. 9 | */ 10 | public abstract class CraftPlayer_1_18 implements Player { 11 | 12 | public String name; 13 | public EntityPlayer_1_18 ep; 14 | 15 | public CraftPlayer_1_18() {} 16 | 17 | // required 18 | public EntityPlayer_1_18 getHandle() { 19 | return ep; 20 | } 21 | 22 | // required 23 | @Override 24 | public Location getLocation() { 25 | return new Location(null, ep.x, ep.y, ep.z); 26 | } 27 | 28 | @Override 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_18/PlayerConnection_1_18.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_18; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.common.Packet; 4 | 5 | import java.util.Optional; 6 | 7 | public class PlayerConnection_1_18 { 8 | 9 | public PlayerConnection_1_18() {} 10 | 11 | /* 12 | * Some spigot/bukkit forks contains lambda method with matching types 13 | * same as send(Packet) method. 14 | * Here, this certain behavior is reproduced. 15 | * 16 | * Compiler will generate a synthetic method representing lambda 17 | * with same signature as sendPacket_obf(Packet) method. 18 | */ 19 | 20 | public void doLambdaStuff() { 21 | Optional.empty().ifPresent(packet -> { 22 | String quack = "Moo"; 23 | }); 24 | } 25 | 26 | // required 27 | public void sendPacket_obf(Packet packet) {} 28 | } 29 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_20_2/ServerCommonPacketListenerImpl_1_20_2.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_20_2; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.common.Packet; 4 | 5 | import java.util.Optional; 6 | 7 | public abstract class ServerCommonPacketListenerImpl_1_20_2 { 8 | 9 | /* 10 | * Some spigot/bukkit forks contains lambda method with matching types 11 | * same as send(Packet) method. 12 | * Here, this certain behavior is reproduced. 13 | * 14 | * Compiler will generate a synthetic method representing lambda 15 | * with same signature as sendPacket_obf(Packet) method. 16 | */ 17 | 18 | public void doLambdaStuff() { 19 | Optional.empty().ifPresent(packet -> { 20 | String quack = "Moo"; 21 | }); 22 | } 23 | 24 | // required 25 | public void sendPacket_obf(Packet packet) {} 26 | 27 | } 28 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_19/VibrationParticleOption_1_19.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_19; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleParam; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17.PositionSource; 5 | 6 | public class VibrationParticleOption_1_19 implements ParticleParam { 7 | 8 | public PositionSource source; 9 | public int ticks; 10 | 11 | public VibrationParticleOption_1_19(PositionSource source, int ticks) { 12 | this.source = source; 13 | this.ticks = ticks; 14 | } 15 | 16 | @Override 17 | public boolean equals(Object obj) { 18 | if (!(obj instanceof VibrationParticleOption_1_19)) return false; 19 | 20 | VibrationParticleOption_1_19 param = (VibrationParticleOption_1_19) obj; 21 | 22 | return source.equals(param.source) && ticks == param.ticks; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/obc/v1_20_2/entity/CraftPlayer_1_20_2.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.obc.v1_20_2.entity; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_20_2.EntityPlayer_1_20_2; 4 | import org.bukkit.Location; 5 | import org.bukkit.entity.Player; 6 | 7 | /* 8 | It has to be abstract, we don't want to implement tons of Player's methods. 9 | */ 10 | public abstract class CraftPlayer_1_20_2 implements Player { 11 | 12 | public String name; 13 | public EntityPlayer_1_20_2 ep; 14 | 15 | public CraftPlayer_1_20_2() {} 16 | 17 | // required 18 | public EntityPlayer_1_20_2 getHandle() { 19 | return ep; 20 | } 21 | 22 | // required 23 | @Override 24 | public Location getLocation() { 25 | return new Location(null, ep.x, ep.y, ep.z); 26 | } 27 | 28 | @Override 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /ParticleNativeAPI-plugin-benchmark/src/main/java/com/github/fierioziy/particlenativebenchmark/spawners/ParticleSpawnerNMS.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativebenchmark.spawners; 2 | 3 | import com.github.fierioziy.particlenativebenchmark.command.CommandPNAB; 4 | import net.minecraft.core.particles.Particles; 5 | import net.minecraft.network.protocol.game.PacketPlayOutWorldParticles; 6 | import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; 7 | import org.bukkit.entity.Player; 8 | 9 | public class ParticleSpawnerNMS implements ParticleSpawner { 10 | 11 | public ParticleSpawnerNMS(CommandPNAB.Context context) { 12 | 13 | } 14 | 15 | @Override 16 | public void spawnParticle(Player player, double x, double y, double z) { 17 | ((CraftPlayer) player).getHandle().b.sendPacket( // b is player connection 18 | new PacketPlayOutWorldParticles(Particles.C, true, // C is flame particle type 19 | x, y, z, 20 | 0F, 0F, 0F, 0F, 1) 21 | ); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_13/ParticleParamRedstone_1_13.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13; 2 | 3 | public class ParticleParamRedstone_1_13 implements ParticleParam { 4 | 5 | public float r, g, b, size; 6 | 7 | // required 8 | public ParticleParamRedstone_1_13(float r, float g, float b, float size) { 9 | this.r = r; 10 | this.g = g; 11 | this.b = b; 12 | this.size = size; 13 | } 14 | 15 | // simple value compare 16 | @Override 17 | public boolean equals(Object obj) { 18 | if (!(obj instanceof ParticleParamRedstone_1_13)) { 19 | return false; 20 | } 21 | 22 | ParticleParamRedstone_1_13 param = (ParticleParamRedstone_1_13) obj; 23 | return eq(r, param.r) && eq(g, param.g) && eq(b, param.b) 24 | && eq(size, param.size); 25 | } 26 | 27 | private boolean eq(float value1, float value2) { 28 | return Math.abs(value1 - value2) <= 0.001F; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ParticleNativeAPI-plugin-test/src/main/java/com/github/fierioziy/particlenativetest/command/utils/SneakToggle.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativetest.command.utils; 2 | 3 | public class SneakToggle { 4 | 5 | private static final int SNEAK_WAIT_TICKS = 10; 6 | private static final int SNEAK_FINISH_COUNT = 3; 7 | 8 | private int sneakTicks = 0; 9 | private int sneakCount = 0; 10 | private boolean sneakLock = false; 11 | 12 | private boolean finished = false; 13 | 14 | public void tick(boolean isSneaking) { 15 | if (isSneaking && !sneakLock) { 16 | ++sneakCount; 17 | sneakTicks = SNEAK_WAIT_TICKS; 18 | sneakLock = true; 19 | if (sneakCount >= SNEAK_FINISH_COUNT) { 20 | finished = true; 21 | } 22 | } 23 | 24 | if (!isSneaking) { 25 | sneakLock = false; 26 | if (sneakTicks > 0) --sneakTicks; 27 | else sneakCount = 0; 28 | } 29 | } 30 | 31 | public boolean isFinished() { 32 | return finished; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_7/PacketPlayOutWorldParticles_1_7.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_7; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.common.Packet; 4 | 5 | public class PacketPlayOutWorldParticles_1_7 implements Packet { 6 | 7 | public String particle; 8 | public float x, y, z; 9 | public float offsetX, offsetY, offsetZ; 10 | public float speed; 11 | public int count; 12 | 13 | // required 14 | public PacketPlayOutWorldParticles_1_7(String particle, float x, float y, float z, 15 | float offsetX, float offsetY, float offsetZ, 16 | float speed, int count) { 17 | this.particle = particle; 18 | this.x = x; 19 | this.y = y; 20 | this.z = z; 21 | this.offsetX = offsetX; 22 | this.offsetY = offsetY; 23 | this.offsetZ = offsetZ; 24 | this.speed = speed; 25 | this.count = count; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_21_3/ParticleParamRedstone_1_21_3.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_21_3; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleParam; 4 | 5 | public class ParticleParamRedstone_1_21_3 implements ParticleParam { 6 | 7 | public int color; 8 | public float size; 9 | 10 | // required 11 | public ParticleParamRedstone_1_21_3(int color, float size) { 12 | this.color = color; 13 | this.size = size; 14 | } 15 | 16 | // simple value compare 17 | @Override 18 | public boolean equals(Object obj) { 19 | if (!(obj instanceof ParticleParamRedstone_1_21_3)) { 20 | return false; 21 | } 22 | 23 | // make delta check 24 | ParticleParamRedstone_1_21_3 param = (ParticleParamRedstone_1_21_3) obj; 25 | return color == param.color && eq(size, param.size); 26 | } 27 | 28 | private boolean eq(float value1, float value2) { 29 | return Math.abs(value1 - value2) <= 0.001F; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Fierioziy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeBlockImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleType; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeBlock; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | import org.bukkit.Material; 7 | 8 | public class ParticleTypeBlockImpl implements ParticleTypeBlock { 9 | 10 | @Override 11 | public ParticleType of(Material block) { 12 | return of(block, (byte) 0); 13 | } 14 | 15 | @Override 16 | public ParticleType of(Material block, int meta) { 17 | return of(block, (byte) meta); 18 | } 19 | 20 | @Override 21 | public ParticleType of(Material block, byte meta) { 22 | throw new ParticleException( 23 | "Requested particle type is not supported by this server version!" 24 | ); 25 | } 26 | 27 | @Override 28 | public boolean isPresent() { 29 | return false; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_13/ParticleParamItem.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.common.ItemStack; 4 | 5 | public class ParticleParamItem implements ParticleParam { 6 | 7 | public Particle particle; 8 | public ItemStack itemStack; 9 | 10 | // required 11 | public ParticleParamItem(Particle particle, ItemStack itemStack) { 12 | this.particle = particle; 13 | this.itemStack = itemStack; 14 | } 15 | 16 | // simple reference and value compare 17 | @Override 18 | public boolean equals(Object obj) { 19 | if (!(obj instanceof ParticleParamItem)) { 20 | return false; 21 | } 22 | 23 | ParticleParamItem param = (ParticleParamItem) obj; 24 | return particle == param.particle 25 | && itemStack.bukkitStack.getType() == param.itemStack.bukkitStack.getType() 26 | && itemStack.bukkitStack.getAmount() == param.itemStack.bukkitStack.getAmount(); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_20_5/ServerCommonPacketListenerImpl_1_20_5.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_20_5; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.common.Packet; 4 | 5 | import java.util.Optional; 6 | 7 | public abstract class ServerCommonPacketListenerImpl_1_20_5 { 8 | 9 | /* 10 | * Some spigot/bukkit forks contains lambda method with matching types 11 | * same as send(Packet) method. 12 | * Here, this certain behavior is reproduced. 13 | * 14 | * Compiler will generate a synthetic method representing lambda 15 | * with same signature as sendPacket_obf(Packet) method. 16 | */ 17 | 18 | public void doLambdaStuff() { 19 | Optional.empty().ifPresent(packet -> { 20 | String quack = "Moo"; 21 | }); 22 | } 23 | 24 | // required 25 | public void sendPacket_obf(Packet packet) {} 26 | 27 | // also required, spigot added copied method 28 | // any method is valid 29 | public void otherSendPacket_obf(Packet packet) {} 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeBlockMotionImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeBlockMotion; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeMotion; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | import org.bukkit.Material; 7 | 8 | public class ParticleTypeBlockMotionImpl implements ParticleTypeBlockMotion { 9 | 10 | @Override 11 | public ParticleTypeMotion of(Material block) { 12 | return of(block, (byte) 0); 13 | } 14 | 15 | @Override 16 | public ParticleTypeMotion of(Material block, int meta) { 17 | return of(block, (byte) meta); 18 | } 19 | 20 | @Override 21 | public ParticleTypeMotion of(Material block, byte meta) { 22 | throw new ParticleException( 23 | "Requested particle type is not supported by this server version!" 24 | ); 25 | } 26 | 27 | @Override 28 | public boolean isPresent() { 29 | return false; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/packet/ParticlePacketProvider_1_17.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.packet; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 5 | import com.github.fierioziy.particlenativeapi.core.asm.packet.v1_17.ParticlePacketASM_1_17; 6 | 7 | public class ParticlePacketProvider_1_17 extends ParticlePacketProvider { 8 | 9 | private final String playerConnectionFieldName; 10 | private final String sendPacketMethodName; 11 | 12 | public ParticlePacketProvider_1_17(ContextASM context) { 13 | super(context); 14 | 15 | playerConnectionFieldName = context.internal.getPlayerConnectionFieldName_1_17(); 16 | sendPacketMethodName = context.internal.getSendPacketMethodName_1_18(); 17 | } 18 | 19 | @Override 20 | public void registerClasses() { 21 | new ParticlePacketASM_1_17(context, 22 | ClassSkeleton.PARTICLE_PACKET, 23 | playerConnectionFieldName, sendPacketMethodName) 24 | .registerClass(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/packet/ParticlePacketProvider_1_20_2.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.packet; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.packet.v1_17.ParticlePacketASM_1_17; 5 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 6 | 7 | public class ParticlePacketProvider_1_20_2 extends ParticlePacketProvider { 8 | 9 | private final String playerConnectionFieldName; 10 | private final String sendPacketMethodName; 11 | 12 | public ParticlePacketProvider_1_20_2(ContextASM context) { 13 | super(context); 14 | 15 | playerConnectionFieldName = context.internal.getPlayerConnectionFieldName_1_17(); 16 | sendPacketMethodName = context.internal.getSendPacketMethodName_1_20_2(); 17 | } 18 | 19 | @Override 20 | public void registerClasses() { 21 | new ParticlePacketASM_1_17(context, 22 | ClassSkeleton.PARTICLE_PACKET, 23 | playerConnectionFieldName, sendPacketMethodName) 24 | .registerClass(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeSpellImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleType; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeSpell; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | import org.bukkit.Color; 7 | 8 | public class ParticleTypeSpellImpl implements ParticleTypeSpell { 9 | 10 | @Override 11 | public ParticleType spell(Color color, int alpha, double power) { 12 | return spell( 13 | color.getRed(), 14 | color.getGreen(), 15 | color.getBlue(), 16 | alpha, 17 | power 18 | ); 19 | } 20 | 21 | @Override 22 | public ParticleType spell(int r, int g, int b, int alpha, double power) { 23 | throw new ParticleException( 24 | "Requested particle type is not supported by this server version!" 25 | ); 26 | } 27 | 28 | @Override 29 | public boolean isPresent() { 30 | return false; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_13/PacketPlayOutWorldParticles_1_13.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.common.Packet; 4 | 5 | public class PacketPlayOutWorldParticles_1_13 implements Packet { 6 | 7 | public ParticleParam particle; 8 | public boolean far; 9 | public float x, y, z; 10 | public float offsetX, offsetY, offsetZ; 11 | public float speed; 12 | public int count; 13 | 14 | // required 15 | public PacketPlayOutWorldParticles_1_13(ParticleParam particle, boolean far, 16 | float x, float y, float z, 17 | float offsetX, float offsetY, float offsetZ, 18 | float speed, int count) { 19 | this.particle = particle; 20 | this.far = far; 21 | this.x = x; 22 | this.y = y; 23 | this.z = z; 24 | this.offsetX = offsetX; 25 | this.offsetY = offsetY; 26 | this.offsetZ = offsetZ; 27 | this.speed = speed; 28 | this.count = count; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/StaticMock.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.Server; 5 | 6 | import java.lang.reflect.Field; 7 | import java.util.function.Consumer; 8 | 9 | import static org.mockito.Mockito.mock; 10 | 11 | public abstract class StaticMock { 12 | 13 | private static final Field bukkitServerField; 14 | 15 | static { 16 | try { 17 | Field serverField = Bukkit.class.getDeclaredField("server"); 18 | serverField.setAccessible(true); 19 | bukkitServerField = serverField; 20 | } catch (NoSuchFieldException e) { 21 | throw new RuntimeException(e); 22 | } 23 | } 24 | 25 | private StaticMock() {} 26 | 27 | public static void ofServer(Consumer consumer) { 28 | try { 29 | Server mockServer = mock(Server.class); 30 | 31 | bukkitServerField.set(null, mockServer); 32 | consumer.accept(mockServer); 33 | bukkitServerField.set(null, null); 34 | } catch (IllegalAccessException e) { 35 | throw new RuntimeException(e); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_8/PacketPlayOutWorldParticles_1_8.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_8; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.common.Packet; 4 | 5 | public class PacketPlayOutWorldParticles_1_8 implements Packet { 6 | 7 | public EnumParticle particle; 8 | public boolean far; 9 | public float x, y, z; 10 | public float offsetX, offsetY, offsetZ; 11 | public float speed; 12 | public int count; 13 | public int[] data; 14 | 15 | // required 16 | public PacketPlayOutWorldParticles_1_8(EnumParticle particle, boolean far, 17 | float x, float y, float z, 18 | float offsetX, float offsetY, float offsetZ, 19 | float speed, int count, int... data) { 20 | this.particle = particle; 21 | this.far = far; 22 | this.x = x; 23 | this.y = y; 24 | this.z = z; 25 | this.offsetX = offsetX; 26 | this.offsetY = offsetY; 27 | this.offsetZ = offsetZ; 28 | this.speed = speed; 29 | this.count = count; 30 | this.data = data; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_21_3/DustColorTransitionOptions_1_21_3.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_21_3; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleParam; 4 | 5 | public class DustColorTransitionOptions_1_21_3 implements ParticleParam { 6 | 7 | public int color; 8 | public int targetColor; 9 | public float size; 10 | 11 | // required 12 | public DustColorTransitionOptions_1_21_3(int color, int targetColor, float size) { 13 | this.color = color; 14 | this.targetColor = targetColor; 15 | this.size = size; 16 | } 17 | 18 | // simple value compare 19 | @Override 20 | public boolean equals(Object obj) { 21 | if (!(obj instanceof DustColorTransitionOptions_1_21_3)) { 22 | return false; 23 | } 24 | 25 | DustColorTransitionOptions_1_21_3 param = (DustColorTransitionOptions_1_21_3) obj; 26 | return color == param.color 27 | && targetColor == param.targetColor 28 | && eq(size, param.size); 29 | } 30 | 31 | private boolean eq(float value1, float value2) { 32 | return Math.abs(value1 - value2) <= 0.001F; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_17/ParticleParamRedstone_1_17.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.mojang.common.Vector3fa; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleParam; 5 | 6 | public class ParticleParamRedstone_1_17 implements ParticleParam { 7 | 8 | public float r, g, b, size; 9 | 10 | // required 11 | public ParticleParamRedstone_1_17(Vector3fa vector, float size) { 12 | this.r = vector.x; 13 | this.g = vector.y; 14 | this.b = vector.z; 15 | this.size = size; 16 | } 17 | 18 | // simple value compare 19 | @Override 20 | public boolean equals(Object obj) { 21 | if (!(obj instanceof ParticleParamRedstone_1_17)) { 22 | return false; 23 | } 24 | 25 | // make delta check 26 | 27 | ParticleParamRedstone_1_17 param = (ParticleParamRedstone_1_17) obj; 28 | return eq(r, param.r) && eq(g, param.g) && eq(b, param.b) 29 | && eq(size, param.size); 30 | } 31 | 32 | private boolean eq(float value1, float value2) { 33 | return Math.abs(value1 - value2) <= 0.001F; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_17/Particles_1_17.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.Particle; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleType; 5 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.Particles_1_13; 6 | 7 | public class Particles_1_17 { 8 | 9 | public static ParticleType LAVA = Particles_1_13.LAVA; 10 | public static Particle FALLING_DUST = Particles_1_13.FALLING_DUST; 11 | public static Particle BLOCK = Particles_1_13.BLOCK; 12 | public static ParticleType ENTITY_EFFECT = Particles_1_13.ENTITY_EFFECT; 13 | public static Particle DUST = Particles_1_13.DUST; 14 | public static Particle DUST_COLOR_TRANSITION = new ParticleType(); 15 | public static Particle VIBRATION = new ParticleType(); 16 | public static Particle ITEM = Particles_1_13.ITEM; 17 | public static ParticleType FLAME = Particles_1_13.FLAME; 18 | public static ParticleType NOTE = Particles_1_13.NOTE; 19 | public static ParticleType DRAGON_BREATH = Particles_1_13.DRAGON_BREATH; 20 | public static ParticleType EFFECT = Particles_1_13.EFFECT; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_19_3/ParticleParamRedstone_1_19_3.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_19_3; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.mojang.common.Vector3f; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleParam; 5 | 6 | public class ParticleParamRedstone_1_19_3 implements ParticleParam { 7 | 8 | public float r, g, b, size; 9 | 10 | // required 11 | public ParticleParamRedstone_1_19_3(Vector3f vector, float size) { 12 | this.r = vector.x; 13 | this.g = vector.y; 14 | this.b = vector.z; 15 | this.size = size; 16 | } 17 | 18 | // simple value compare 19 | @Override 20 | public boolean equals(Object obj) { 21 | if (!(obj instanceof ParticleParamRedstone_1_19_3)) { 22 | return false; 23 | } 24 | 25 | // make delta check 26 | 27 | ParticleParamRedstone_1_19_3 param = (ParticleParamRedstone_1_19_3) obj; 28 | return eq(r, param.r) && eq(g, param.g) && eq(b, param.b) 29 | && eq(size, param.size); 30 | } 31 | 32 | private boolean eq(float value1, float value2) { 33 | return Math.abs(value1 - value2) <= 0.001F; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_15/PacketPlayOutWorldParticles_1_15.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_15; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleParam; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.common.Packet; 5 | 6 | public class PacketPlayOutWorldParticles_1_15 implements Packet { 7 | 8 | public ParticleParam particle; 9 | public boolean far; 10 | public double x, y, z; 11 | public float offsetX, offsetY, offsetZ; 12 | public float speed; 13 | public int count; 14 | 15 | // required 16 | public PacketPlayOutWorldParticles_1_15(ParticleParam particle, boolean far, 17 | double x, double y, double z, 18 | float offsetX, float offsetY, float offsetZ, 19 | float speed, int count) { 20 | this.particle = particle; 21 | this.far = far; 22 | this.x = x; 23 | this.y = y; 24 | this.z = z; 25 | this.offsetX = offsetX; 26 | this.offsetY = offsetY; 27 | this.offsetZ = offsetZ; 28 | this.speed = speed; 29 | this.count = count; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/asm/particle/type/ParticleTypesUtils.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.packet.ParticlePacket; 4 | import com.github.fierioziy.particlenativeapi.core.asm.BaseASM; 5 | 6 | import java.lang.reflect.Field; 7 | 8 | public class ParticleTypesUtils { 9 | 10 | public static Object unwrapPacket(ParticlePacket wrappedPacket) { 11 | String packetFieldName = BaseASM.PACKET_FIELD_NAME; 12 | try { 13 | // runtime class type that holds packet field depends on server version 14 | // so it cannot be reliably stored for continuous calls 15 | // it doesn't matter anyway, it is just an unit test 16 | Field declaredField = wrappedPacket.getClass().getDeclaredField(packetFieldName); 17 | declaredField.setAccessible(true); 18 | 19 | return declaredField.get(wrappedPacket); 20 | } catch (NoSuchFieldException | IllegalAccessException e) { 21 | throw new IllegalStateException(String.format( 22 | "Particle wrapper runtime class type probably does not contain \"%s\" field", 23 | packetFieldName 24 | ), e); 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_21_10/PowerParticleOption.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_21_10; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.Particle; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleParam; 5 | 6 | public class PowerParticleOption implements ParticleParam { 7 | 8 | public Particle particle; 9 | public float power; 10 | 11 | // required 12 | private PowerParticleOption(Particle particle, float power) { 13 | this.particle = particle; 14 | this.power = power; 15 | } 16 | 17 | public static PowerParticleOption newPowerInstance_obf(Particle particle, float power) { 18 | return new PowerParticleOption(particle, power); 19 | } 20 | 21 | // simple value compare 22 | @Override 23 | public boolean equals(Object obj) { 24 | if (!(obj instanceof PowerParticleOption)) { 25 | return false; 26 | } 27 | 28 | PowerParticleOption param = (PowerParticleOption) obj; 29 | return power == param.power; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "PowerParticleOption{" + 35 | "power=" + power + 36 | '}'; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_17/DustColorTransitionOptions_1_17.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.mojang.common.Vector3fa; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleParam; 5 | 6 | public class DustColorTransitionOptions_1_17 implements ParticleParam { 7 | 8 | public float r, g, b, size; 9 | public float tr, tg, tb; 10 | 11 | // required 12 | public DustColorTransitionOptions_1_17(Vector3fa vector, Vector3fa target, float size) { 13 | this.r = vector.x; 14 | this.g = vector.y; 15 | this.b = vector.z; 16 | this.size = size; 17 | 18 | this.tr = target.x; 19 | this.tg = target.y; 20 | this.tb = target.z; 21 | } 22 | 23 | // simple value compare 24 | @Override 25 | public boolean equals(Object obj) { 26 | if (!(obj instanceof DustColorTransitionOptions_1_17)) { 27 | return false; 28 | } 29 | 30 | DustColorTransitionOptions_1_17 param = (DustColorTransitionOptions_1_17) obj; 31 | return r == param.r && g == param.g && b == param.b 32 | && size == param.size 33 | && tr == param.tr && tg == param.tg && tb == param.tb; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_18/Particles_1_18.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_18; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.Particle; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleType; 5 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17.Particles_1_17; 6 | 7 | public class Particles_1_18 { 8 | 9 | public static ParticleType HEART = new ParticleType(); 10 | public static Particle FALLING_DUST = Particles_1_17.FALLING_DUST; 11 | public static Particle BLOCK = Particles_1_17.BLOCK; 12 | public static ParticleType ENTITY_EFFECT = Particles_1_17.ENTITY_EFFECT; 13 | public static Particle DUST = Particles_1_17.DUST; 14 | public static Particle DUST_COLOR_TRANSITION = Particles_1_17.DUST_COLOR_TRANSITION; 15 | public static Particle VIBRATION = Particles_1_17.VIBRATION; 16 | public static Particle ITEM = Particles_1_17.ITEM; 17 | public static ParticleType FLAME = Particles_1_17.FLAME; 18 | public static ParticleType NOTE = Particles_1_17.NOTE; 19 | public static Particle BLOCK_MARKER = new ParticleType(); 20 | public static ParticleType DRAGON_BREATH = Particles_1_17.DRAGON_BREATH; 21 | public static ParticleType EFFECT = Particles_1_17.EFFECT; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_19_3/DustColorTransitionOptions_1_19_3.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_19_3; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.mojang.common.Vector3f; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleParam; 5 | 6 | public class DustColorTransitionOptions_1_19_3 implements ParticleParam { 7 | 8 | public float r, g, b, size; 9 | public float tr, tg, tb; 10 | 11 | // required 12 | public DustColorTransitionOptions_1_19_3(Vector3f vector, Vector3f target, float size) { 13 | this.r = vector.x; 14 | this.g = vector.y; 15 | this.b = vector.z; 16 | this.size = size; 17 | 18 | this.tr = target.x; 19 | this.tg = target.y; 20 | this.tb = target.z; 21 | } 22 | 23 | // simple value compare 24 | @Override 25 | public boolean equals(Object obj) { 26 | if (!(obj instanceof DustColorTransitionOptions_1_19_3)) { 27 | return false; 28 | } 29 | 30 | DustColorTransitionOptions_1_19_3 param = (DustColorTransitionOptions_1_19_3) obj; 31 | return r == param.r && g == param.g && b == param.b 32 | && size == param.size 33 | && tr == param.tr && tg == param.tg && tb == param.tb; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_20_5/ColorParticleOption.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_20_5; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.Particle; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleParam; 5 | 6 | public class ColorParticleOption implements ParticleParam { 7 | 8 | public Particle particle; 9 | public int color; 10 | 11 | // required 12 | private ColorParticleOption(Particle particle, int color) { 13 | this.particle = particle; 14 | this.color = color; 15 | } 16 | 17 | public static ColorParticleOption newByInt_obf(Particle particle, int color) { 18 | return new ColorParticleOption(particle, color); 19 | } 20 | 21 | // simple value compare 22 | @Override 23 | public boolean equals(Object obj) { 24 | if (!(obj instanceof ColorParticleOption)) { 25 | return false; 26 | } 27 | 28 | ColorParticleOption param = (ColorParticleOption) obj; 29 | return particle == param.particle && color == param.color; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "ColorParticleOption{" + 35 | "particle=" + particle + 36 | ", color=" + color + 37 | '}'; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ParticleNativeAPI-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | ParticleNativeAPI-parent 8 | com.github.fierioziy.particlenativeapi 9 | 4.5.1 10 | 11 | 12 | ParticleNativeAPI-api 13 | 14 | ParticleNativeAPI-api 15 | 16 | 17 | ${project.artifactId} 18 | 19 | src/main/java 20 | src/test/java 21 | 22 | 23 | 24 | 25 | ${project.basedir}/.. 26 | 27 | LICENSE.txt 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.spigotmc 37 | spigot-api 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_21_4/PacketPlayOutWorldParticles_1_21_4.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_21_4; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.common.Packet; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleParam; 5 | 6 | public class PacketPlayOutWorldParticles_1_21_4 implements Packet { 7 | 8 | public ParticleParam particle; 9 | public boolean far; 10 | public boolean alwaysShow; 11 | public double x, y, z; 12 | public float offsetX, offsetY, offsetZ; 13 | public float speed; 14 | public int count; 15 | 16 | // required 17 | public PacketPlayOutWorldParticles_1_21_4(ParticleParam particle, 18 | boolean far, boolean alwaysShow, 19 | double x, double y, double z, 20 | float offsetX, float offsetY, float offsetZ, 21 | float speed, int count) { 22 | this.particle = particle; 23 | this.far = far; 24 | this.alwaysShow = alwaysShow; 25 | this.x = x; 26 | this.y = y; 27 | this.z = z; 28 | this.offsetX = offsetX; 29 | this.offsetY = offsetY; 30 | this.offsetZ = offsetZ; 31 | this.speed = speed; 32 | this.count = count; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_19/Particles_1_19.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_19; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.Particle; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleType; 5 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_18.Particles_1_18; 6 | 7 | public class Particles_1_19 { 8 | 9 | public static ParticleType HEART = Particles_1_18.HEART; 10 | public static Particle FALLING_DUST = Particles_1_18.FALLING_DUST; 11 | public static Particle BLOCK = Particles_1_18.BLOCK; 12 | public static ParticleType ENTITY_EFFECT = Particles_1_18.ENTITY_EFFECT; 13 | public static Particle DUST = Particles_1_18.DUST; 14 | public static Particle DUST_COLOR_TRANSITION = Particles_1_18.DUST_COLOR_TRANSITION; 15 | public static Particle VIBRATION = Particles_1_18.VIBRATION; 16 | public static Particle ITEM = Particles_1_18.ITEM; 17 | public static ParticleType FLAME = Particles_1_18.FLAME; 18 | public static ParticleType NOTE = Particles_1_18.NOTE; 19 | public static Particle BLOCK_MARKER = Particles_1_18.BLOCK_MARKER; 20 | public static Particle SCULK_CHARGE = new ParticleType(); 21 | public static Particle SHRIEK = new ParticleType(); 22 | public static ParticleType DRAGON_BREATH = Particles_1_18.DRAGON_BREATH; 23 | public static ParticleType EFFECT = Particles_1_18.EFFECT; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_20_5/Particles_1_20_5.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_20_5; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.Particle; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleType; 5 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_19.Particles_1_19; 6 | 7 | public class Particles_1_20_5 { 8 | 9 | public static ParticleType HEART = Particles_1_19.HEART; 10 | public static Particle FALLING_DUST = Particles_1_19.FALLING_DUST; 11 | public static Particle BLOCK = Particles_1_19.BLOCK; 12 | public static Particle ENTITY_EFFECT = new ParticleType(); 13 | public static Particle DUST = Particles_1_19.DUST; 14 | public static Particle DUST_COLOR_TRANSITION = Particles_1_19.DUST_COLOR_TRANSITION; 15 | public static Particle VIBRATION = Particles_1_19.VIBRATION; 16 | public static Particle ITEM = Particles_1_19.ITEM; 17 | public static ParticleType FLAME = Particles_1_19.FLAME; 18 | public static ParticleType NOTE = Particles_1_19.NOTE; 19 | public static Particle BLOCK_MARKER = Particles_1_19.BLOCK_MARKER; 20 | public static Particle SCULK_CHARGE = Particles_1_19.SCULK_CHARGE; 21 | public static Particle SHRIEK = Particles_1_19.SHRIEK; 22 | public static ParticleType DRAGON_BREATH = Particles_1_19.DRAGON_BREATH; 23 | public static ParticleType EFFECT = Particles_1_19.EFFECT; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeColorImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleType; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeColor; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | import org.bukkit.Color; 7 | 8 | public class ParticleTypeColorImpl implements ParticleTypeColor { 9 | 10 | @Override 11 | public ParticleType color(Color color) { 12 | return color( 13 | color.getRed(), 14 | color.getGreen(), 15 | color.getBlue(), 16 | 255 17 | ); 18 | } 19 | 20 | @Override 21 | public ParticleType color(Color color, int alpha) { 22 | return color( 23 | color.getRed(), 24 | color.getGreen(), 25 | color.getBlue(), 26 | alpha 27 | ); 28 | } 29 | 30 | @Override 31 | public ParticleType color(int r, int g, int b) { 32 | return color(r, g, b, 255); 33 | } 34 | 35 | @Override 36 | public ParticleType color(int r, int g, int b, int alpha) { 37 | throw new ParticleException( 38 | "Requested particle type is not supported by this server version!" 39 | ); 40 | } 41 | 42 | @Override 43 | public boolean isPresent() { 44 | return false; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /ParticleNativeAPI-plugin-benchmark/src/main/java/com/github/fierioziy/particlenativebenchmark/command/BenchmarkCase.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativebenchmark.command; 2 | 3 | import com.github.fierioziy.particlenativebenchmark.spawners.*; 4 | 5 | import java.util.function.Function; 6 | 7 | public enum BenchmarkCase { 8 | NMS("nms", ParticleSpawnerNMS::new), 9 | PARTICLE_NATIVE_API("pna", ParticleSpawnerPNA::new), 10 | SPIGOT_API("spigot", ParticleSpawnerSpigot::new), 11 | REFLECTION("ref", ParticleSpawnerReflection::new); 12 | 13 | private static final BenchmarkCase[] VALUES = values(); 14 | 15 | private final String shortName; 16 | private final Function particleSpawnerCtr; 17 | 18 | BenchmarkCase(String shortName, 19 | Function particleSpawnerCtr) { 20 | this.shortName = shortName; 21 | this.particleSpawnerCtr = particleSpawnerCtr; 22 | } 23 | 24 | public ParticleSpawner createParticleSpawner(CommandPNAB.Context context) { 25 | return particleSpawnerCtr.apply(context); 26 | } 27 | 28 | public static BenchmarkCase getByShortName(String shortName) { 29 | for (BenchmarkCase benchmarkCase : VALUES) { 30 | if (benchmarkCase.shortName.equalsIgnoreCase(shortName)) { 31 | return benchmarkCase; 32 | } 33 | } 34 | 35 | throw new IllegalArgumentException("No enum found for short name " + shortName); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_21_10/SpellParticleOption.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_21_10; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.Particle; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleParam; 5 | 6 | public class SpellParticleOption implements ParticleParam { 7 | 8 | public Particle particle; 9 | public int color; 10 | public float power; 11 | 12 | // required 13 | private SpellParticleOption(Particle particle, int color, float power) { 14 | this.particle = particle; 15 | this.color = color; 16 | this.power = power; 17 | } 18 | 19 | public static SpellParticleOption newSpellInstance_obf(Particle particle, int color, float power) { 20 | return new SpellParticleOption(particle, color, power); 21 | } 22 | 23 | // simple value compare 24 | @Override 25 | public boolean equals(Object obj) { 26 | if (!(obj instanceof SpellParticleOption)) { 27 | return false; 28 | } 29 | 30 | SpellParticleOption param = (SpellParticleOption) obj; 31 | return particle == param.particle && color == param.color && power == param.power; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return "SpellParticleOption{" + 37 | "particle=" + particle + 38 | ", color=" + color + 39 | ", power=" + power + 40 | '}'; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_21_10/Particles_1_21_10.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_21_10; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.Particle; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.ParticleType; 5 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_20_5.Particles_1_20_5; 6 | 7 | public class Particles_1_21_10 { 8 | 9 | public static ParticleType HEART = Particles_1_20_5.HEART; 10 | public static Particle FALLING_DUST = Particles_1_20_5.FALLING_DUST; 11 | public static Particle BLOCK = Particles_1_20_5.BLOCK; 12 | public static Particle ENTITY_EFFECT = Particles_1_20_5.ENTITY_EFFECT; 13 | public static Particle DUST = Particles_1_20_5.DUST; 14 | public static Particle DUST_COLOR_TRANSITION = Particles_1_20_5.DUST_COLOR_TRANSITION; 15 | public static Particle VIBRATION = Particles_1_20_5.VIBRATION; 16 | public static Particle ITEM = Particles_1_20_5.ITEM; 17 | public static ParticleType FLAME = Particles_1_20_5.FLAME; 18 | public static ParticleType NOTE = Particles_1_20_5.NOTE; 19 | public static Particle BLOCK_MARKER = Particles_1_20_5.BLOCK_MARKER; 20 | public static Particle SCULK_CHARGE = Particles_1_20_5.SCULK_CHARGE; 21 | public static Particle SHRIEK = Particles_1_20_5.SHRIEK; 22 | public static Particle DRAGON_BREATH = Particles_1_20_5.DRAGON_BREATH; 23 | public static Particle EFFECT = Particles_1_20_5.EFFECT; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ParticleNativeAPI-plugin-benchmark/src/main/java/com/github/fierioziy/particlenativebenchmark/ParticleNativeBenchmarkPlugin.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativebenchmark; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.ParticleNativeAPI; 4 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 5 | import com.github.fierioziy.particlenativeapi.core.ParticleNativeCore; 6 | import com.github.fierioziy.particlenativebenchmark.command.CommandPNAB; 7 | import org.bukkit.plugin.java.JavaPlugin; 8 | 9 | public class ParticleNativeBenchmarkPlugin extends JavaPlugin { 10 | 11 | private boolean isValid = false; 12 | 13 | private ParticleNativeAPI particleApi; 14 | 15 | @Override 16 | public void onLoad() { 17 | particleApi = null; 18 | isValid = false; 19 | 20 | try { 21 | particleApi = ParticleNativeCore.loadAPI(this); 22 | isValid = true; 23 | } 24 | catch (ParticleException e) { 25 | e.printStackTrace(); 26 | } 27 | } 28 | 29 | @Override 30 | public void onEnable() { 31 | this.getCommand("pnab").setExecutor(new CommandPNAB(this)); 32 | this.setEnabled(isValid); 33 | } 34 | 35 | @Override 36 | public void onDisable() { 37 | particleApi = null; 38 | isValid = false; 39 | } 40 | 41 | public ParticleNativeAPI getAPI() { 42 | if (particleApi == null) { 43 | throw new IllegalStateException("Error occurred while getting particle library."); 44 | } 45 | 46 | return particleApi; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/utils/ParticleNativeClassLoader.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.utils; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | *

A basic classloader with public method for class definition.

8 | */ 9 | public class ParticleNativeClassLoader extends ClassLoader { 10 | 11 | private Map classBytecodeMap = new HashMap<>(); 12 | 13 | /** 14 | *

Construct a new class loader linked to parameter class loader.

15 | * 16 | * @param parent a parent class loader to which this 17 | * class loader belongs. 18 | */ 19 | public ParticleNativeClassLoader(ClassLoader parent) { 20 | super(parent); 21 | } 22 | 23 | /** 24 | *

Defines a class with parameter name and bytecode 25 | * stored in {@code byte[]} array.

26 | * 27 | * @param name name of the class to define. 28 | * @param bytecode a {@code byte[]} array containing bytecode of class 29 | * to define. 30 | */ 31 | public void registerClass(String name, byte[] bytecode) { 32 | classBytecodeMap.put(name, bytecode); 33 | } 34 | 35 | @Override 36 | protected Class findClass(String name) throws ClassNotFoundException { 37 | if (classBytecodeMap.containsKey(name)) { 38 | byte[] bytecode = classBytecodeMap.remove(name); 39 | return super.defineClass(name, bytecode, 0, bytecode.length); 40 | } 41 | return super.findClass(name); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /License-ASM.txt: -------------------------------------------------------------------------------- 1 | ASM: a very small and fast Java bytecode manipulation framework 2 | Copyright (c) 2000-2011 INRIA, France Telecom 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the copyright holders nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /ParticleNativeAPI-plugin/src/assembly/dist.xml: -------------------------------------------------------------------------------- 1 | 4 | dist 5 | 6 | zip 7 | 8 | 9 | false 10 | 11 | 12 | 13 | 14 | ../How to use-template.txt 15 | How to use.txt 16 | true 17 | ./ 18 | 19 | 20 | 21 | 22 | 23 | 24 | target 25 | 26 | ParticleNativeAPI.jar 27 | ParticleNativeAPI-sources.jar 28 | 29 | ./ 30 | 31 | 32 | 33 | 34 | ../ParticleNativeAPI-core/target 35 | 36 | ParticleNativeAPI-core.jar 37 | ParticleNativeAPI-core-sources.jar 38 | 39 | core 40 | 41 | 42 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/particle/type/ParticleTypesProvider.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.BaseASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 5 | import com.github.fierioziy.particlenativeapi.core.asm.mapping.ClassMapping; 6 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 7 | import com.github.fierioziy.particlenativeapi.core.asm.utils.ParticleRegistry; 8 | import com.github.fierioziy.particlenativeapi.core.asm.utils.SpigotParticleVersion; 9 | import org.objectweb.asm.ClassWriter; 10 | import org.objectweb.asm.MethodVisitor; 11 | 12 | public abstract class ParticleTypesProvider extends BaseASM { 13 | 14 | protected ParticleRegistry particleRegistry = new ParticleRegistry(); 15 | 16 | public ParticleTypesProvider(ContextASM context) { 17 | super(context); 18 | } 19 | 20 | public abstract void registerClasses(); 21 | public abstract void generateParticleFactoryMethods(ClassWriter cw, SpigotParticleVersion interfaceVersion, 22 | ClassSkeleton particleListSkeleton); 23 | 24 | protected void visitInvalidType(MethodVisitor mv, ClassSkeleton particleTypeSkeleton) { 25 | ClassMapping superType = particleTypeSkeleton.getSuperType(); 26 | 27 | mv.visitTypeInsn(NEW, superType.internalName()); 28 | mv.visitInsn(DUP); 29 | 30 | mv.visitMethodInsn(INVOKESPECIAL, 31 | superType.internalName(), 32 | "", 33 | "()V", false); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ParticleNativeAPI-plugin-test/src/main/java/com/github/fierioziy/particlenativetest/ParticleNativeTestPlugin.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativetest; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.ParticleNativeAPI; 4 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 5 | import com.github.fierioziy.particlenativeapi.core.ParticleNativeCore; 6 | import com.github.fierioziy.particlenativetest.command.CommandPNAL; 7 | import com.github.fierioziy.particlenativetest.command.CommandPNAT; 8 | import org.bukkit.plugin.java.JavaPlugin; 9 | 10 | public class ParticleNativeTestPlugin extends JavaPlugin { 11 | 12 | private boolean isValid = false; 13 | 14 | private ParticleNativeAPI particleApi; 15 | 16 | @Override 17 | public void onLoad() { 18 | particleApi = null; 19 | isValid = false; 20 | 21 | try { 22 | particleApi = ParticleNativeCore.loadAPI(this); 23 | isValid = true; 24 | } 25 | catch (ParticleException e) { 26 | e.printStackTrace(); 27 | } 28 | } 29 | 30 | @Override 31 | public void onEnable() { 32 | this.getCommand("pnat").setExecutor(new CommandPNAT(this)); 33 | this.getCommand("pnal").setExecutor(new CommandPNAL(this)); 34 | this.setEnabled(isValid); 35 | } 36 | 37 | @Override 38 | public void onDisable() { 39 | particleApi = null; 40 | isValid = false; 41 | } 42 | 43 | public ParticleNativeAPI getAPI() { 44 | if (particleApi == null) { 45 | throw new IllegalStateException("Error occurred while getting particle library."); 46 | } 47 | 48 | return particleApi; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeVibrationImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.packet.ParticlePacket; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleType; 5 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeVibration; 6 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 7 | import com.github.fierioziy.particlenativeapi.api.utils.Shared; 8 | import org.bukkit.Location; 9 | import org.bukkit.entity.Entity; 10 | import org.bukkit.util.Vector; 11 | 12 | public class ParticleTypeVibrationImpl implements ParticleTypeVibration { 13 | 14 | @Override 15 | public @Shared ParticleType flyingTo(Location target, int ticks) { 16 | return flyingTo(target.getX(), target.getY(), target.getZ(), ticks); 17 | } 18 | 19 | @Override 20 | public @Shared ParticleType flyingTo(Vector target, int ticks) { 21 | return flyingTo(target.getX(), target.getY(), target.getZ(), ticks); 22 | } 23 | 24 | @Override 25 | public @Shared ParticleType flyingTo(double targetX, double targetY, double targetZ, int ticks) { 26 | throw new ParticleException( 27 | "Requested particle type is not supported by this server version!" 28 | ); 29 | } 30 | 31 | @Override 32 | public @Shared ParticleType flyingTo(Entity targetEntity, int ticks) { 33 | throw new ParticleException( 34 | "Requested particle type is not supported by this server version!" 35 | ); 36 | } 37 | 38 | @Override 39 | public boolean isPresent() { 40 | return false; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/mapping/RegisteredClassMapping.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.mapping; 2 | 3 | import org.objectweb.asm.Type; 4 | 5 | public class RegisteredClassMapping implements ClassMapping { 6 | 7 | private final String internalName; 8 | private final String className; 9 | private final String desc; 10 | 11 | public RegisteredClassMapping(String internalName) { 12 | this.internalName = internalName; 13 | 14 | Type type = Type.getObjectType(internalName); 15 | this.className = type.getClassName(); 16 | this.desc = type.getDescriptor(); 17 | } 18 | 19 | public RegisteredClassMapping(Class clazz) { 20 | Type type = Type.getType(clazz); 21 | this.internalName = type.getInternalName(); 22 | this.className = type.getClassName(); 23 | this.desc = type.getDescriptor(); 24 | } 25 | 26 | @Override 27 | public String internalName() { 28 | return internalName; 29 | } 30 | 31 | @Override 32 | public String className() { 33 | return className; 34 | } 35 | 36 | @Override 37 | public String desc() { 38 | return desc; 39 | } 40 | 41 | @Override 42 | public boolean equals(Object o) { 43 | if (this == o) 44 | return true; 45 | if (!(o instanceof RegisteredClassMapping)) 46 | return false; 47 | 48 | RegisteredClassMapping that = (RegisteredClassMapping) o; 49 | 50 | return internalName.equals(that.internalName); 51 | } 52 | 53 | @Override 54 | public int hashCode() { 55 | return internalName.hashCode(); 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return className; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeDustFloatImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleType; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeDust; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | import org.bukkit.Color; 7 | 8 | public class ParticleTypeDustFloatImpl implements ParticleTypeDust { 9 | 10 | @Override 11 | public ParticleType color(Color color, double size) { 12 | return color( 13 | color.getRed() / 255F, 14 | color.getGreen() / 255F, 15 | color.getBlue() / 255F, 16 | (float) size 17 | ); 18 | } 19 | 20 | @Override 21 | public ParticleType color(Color color, float size) { 22 | return color( 23 | color.getRed() / 255F, 24 | color.getGreen() / 255F, 25 | color.getBlue() / 255F, 26 | size 27 | ); 28 | } 29 | 30 | @Override 31 | public ParticleType color(int r, int g, int b, double size) { 32 | return color(r / 255F, g / 255F, b / 255F, (float) size); 33 | } 34 | 35 | @Override 36 | public ParticleType color(int r, int g, int b, float size) { 37 | return color(r / 255F, g / 255F, b / 255F, size); 38 | } 39 | 40 | @Override 41 | public ParticleType color(float r, float g, float b, float size) { 42 | throw new ParticleException( 43 | "Requested particle type is not supported by this server version!" 44 | ); 45 | } 46 | 47 | @Override 48 | public boolean isPresent() { 49 | return false; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /ParticleNativeAPI-api/src/main/java/com/github/fierioziy/particlenativeapi/api/particle/type/ParticleTypeShriek.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.api.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.utils.Shared; 4 | 5 | /** 6 | *

Class used to represent shriek particle type that takes a delay in ticks.

7 | * 8 | *

It provides a non-reflective of method overloads 9 | * to construct ParticleType with selected delay.

10 | * 11 | *

All of methods does not validate parameters in any way.

12 | * 13 | *

IMPORTANT NOTE: All methods annotated with {@link Shared} annotation 14 | * caches and returns exactly one and the same instance with changed state between method calls. 15 | * For an independent copy of returned instances, check detachCopy methods on them.

16 | * 17 | * @see ParticleType 18 | */ 19 | public interface ParticleTypeShriek { 20 | 21 | /** 22 | *

Selects a delay in ticks after which this particle should be displayed.

23 | * 24 | *

Parameters are not validated in any way.

25 | * 26 | *

This method is overridden by dynamically generated 27 | * subclasses.

28 | * 29 | * @param delay a delay in ticks of this particle's display. 30 | * @return a valid {@link ParticleType} object with selected delay. 31 | */ 32 | @Shared ParticleType delay(int delay); 33 | 34 | /** 35 | *

Checks if this particle is supported by this Spigot version.

36 | * 37 | *

This method is overridden by dynamically generated 38 | * subclasses.

39 | * 40 | * @return true if this particle is supported by 41 | * this Spigot version, false otherwise. 42 | */ 43 | boolean isPresent(); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /ParticleNativeAPI-api/src/main/java/com/github/fierioziy/particlenativeapi/api/particle/type/ParticleTypePowerMotion.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.api.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.utils.Shared; 4 | 5 | /** 6 | *

Class used to represent particle type that takes a power parameter.

7 | * 8 | *

It provides a non-reflective of method overloads 9 | * to construct ParticleTypeMotion with selected power.

10 | * 11 | *

All of methods does not validate parameters in any way.

12 | * 13 | *

IMPORTANT NOTE: All methods annotated with {@link Shared} annotation 14 | * caches and returns exactly one and the same instance with changed state between method calls. 15 | * For an independent copy of returned instances, check detachCopy methods on them.

16 | * 17 | * @see ParticleTypeMotion 18 | */ 19 | public interface ParticleTypePowerMotion { 20 | 21 | /** 22 | *

Selects power this particle should have.

23 | * 24 | *

Parameters are not validated in any way.

25 | * 26 | *

This method is overridden by dynamically generated 27 | * subclasses.

28 | * 29 | * @param power a power which this particle should have. 30 | * @return a valid {@link ParticleTypeMotion} object with selected 31 | * roll angle. 32 | */ 33 | @Shared ParticleTypeMotion power(double power); 34 | 35 | /** 36 | *

Checks if this particle is supported by this Spigot version.

37 | * 38 | *

This method is overridden by dynamically generated 39 | * subclasses.

40 | * 41 | * @return true if this particle is supported by 42 | * this Spigot version, false otherwise. 43 | */ 44 | boolean isPresent(); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeDustIntImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleType; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeDust; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | import org.bukkit.Color; 7 | 8 | public class ParticleTypeDustIntImpl implements ParticleTypeDust { 9 | 10 | @Override 11 | public ParticleType color(Color color, double size) { 12 | return color( 13 | color.getRed(), 14 | color.getGreen(), 15 | color.getBlue(), 16 | (float) size 17 | ); 18 | } 19 | 20 | @Override 21 | public ParticleType color(Color color, float size) { 22 | return color( 23 | color.getRed(), 24 | color.getGreen(), 25 | color.getBlue(), 26 | size 27 | ); 28 | } 29 | 30 | @Override 31 | public ParticleType color(int r, int g, int b, double size) { 32 | return color(r, g, b, (float) size); 33 | } 34 | 35 | @Override 36 | public ParticleType color(int r, int g, int b, float size) { 37 | throw new ParticleException( 38 | "Requested particle type is not supported by this server version!" 39 | ); 40 | } 41 | 42 | @Override 43 | public ParticleType color(float r, float g, float b, float size) { 44 | // this is awful, but we have to live with that 45 | return color((int) (r * 255F), (int) (g * 255F), (int) (b * 255F), size); 46 | } 47 | 48 | @Override 49 | public boolean isPresent() { 50 | return false; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeDustColorTransitionFloatImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleType; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeDustColorTransition; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | import org.bukkit.Color; 7 | 8 | public class ParticleTypeDustColorTransitionFloatImpl implements ParticleTypeDustColorTransition { 9 | 10 | @Override 11 | public ParticleType color(Color color, Color transition, double size) { 12 | return color( 13 | color.getRed() / 255F, 14 | color.getGreen() / 255F, 15 | color.getBlue() / 255F, 16 | transition.getRed() / 255F, 17 | transition.getGreen() / 255F, 18 | transition.getBlue() / 255F, 19 | (float) size 20 | ); 21 | } 22 | 23 | @Override 24 | public ParticleType color(int r, int g, int b, 25 | int tr, int tg, int tb, 26 | double size) { 27 | return color( 28 | r / 255F, g / 255F, b / 255F, 29 | tr / 255F, tg / 255F, tb / 255F, 30 | (float) size 31 | ); 32 | } 33 | 34 | @Override 35 | public ParticleType color(float r, float g, float b, 36 | float tr, float tg, float tb, 37 | float size) { 38 | throw new ParticleException( 39 | "Requested particle type is not supported by this server version!" 40 | ); 41 | } 42 | 43 | @Override 44 | public boolean isPresent() { 45 | return false; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /ParticleNativeAPI-plugin-test/src/main/java/com/github/fierioziy/particlenativetest/command/utils/ParticleListFields_1_8.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativetest.command.utils; 2 | 3 | public class ParticleListFields_1_8 { 4 | 5 | public static final String[] FIELDS = { 6 | "EXPLOSION_NORMAL", 7 | "EXPLOSION_LARGE", 8 | //"EXPLOSION_HUGE", // this is commented out because it hurts eyes, lol 9 | "FIREWORKS_SPARK", 10 | "WATER_BUBBLE", 11 | "WATER_SPLASH", 12 | "WATER_WAKE", 13 | "SUSPENDED", 14 | "SUSPENDED_DEPTH", 15 | "CRIT", 16 | "CRIT_MAGIC", 17 | "SMOKE_NORMAL", 18 | "SMOKE_LARGE", 19 | "SPELL", 20 | "SPELL_INSTANT", 21 | "SPELL_MOB", 22 | "SPELL_MOB_AMBIENT", 23 | "SPELL_WITCH", 24 | "DRIP_WATER", 25 | "DRIP_LAVA", 26 | "VILLAGER_ANGRY", 27 | "VILLAGER_HAPPY", 28 | "TOWN_AURA", 29 | "NOTE", 30 | "PORTAL", 31 | "ENCHANTMENT_TABLE", 32 | "FLAME", 33 | "LAVA", 34 | "FOOTSTEP", 35 | "CLOUD", 36 | "REDSTONE", 37 | "SNOWBALL", 38 | "SNOW_SHOVEL", 39 | "SLIME", 40 | "HEART", 41 | 42 | "BARRIER", 43 | "ITEM_CRACK", 44 | "BLOCK_CRACK", 45 | "BLOCK_DUST", 46 | 47 | "WATER_DROP", 48 | "ITEM_TAKE", 49 | //"MOB_APPEARANCE", // this is commented out because it hurts eyes, lol 50 | 51 | "DRAGON_BREATH", 52 | "END_ROD", 53 | "DAMAGE_INDICATOR", 54 | "SWEEP_ATTACK", 55 | 56 | "FALLING_DUST", 57 | 58 | "TOTEM", 59 | "SPIT" 60 | }; 61 | 62 | } 63 | -------------------------------------------------------------------------------- /ParticleNativeAPI-api/src/main/java/com/github/fierioziy/particlenativeapi/api/particle/ParticleList_1_19_Part.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.api.particle; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.ParticleNativeAPI; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.*; 5 | 6 | /** 7 | *

A class declaring fields for particle types. 8 | * It contains only those particle types that changed since MC 1.19.

9 | * 10 | *

All particle lists attempt to provide same particle types between 11 | * renames or merges. They also attempt to provide cross-version 12 | * compatibility (for ex. usage of ENCHANTED_HIT effect name 13 | * from {@link ParticleList_1_13} should work on MC 1.8), however this is 14 | * not always possible.

15 | * 16 | *

Use isPresent method on particle type to handle such cases.

17 | * 18 | *

Before accessing any particle type, you should check if it exists on server by 19 | * an isPresent defined by all particle types in this interface.

20 | */ 21 | @SuppressWarnings("unused") 22 | public abstract class ParticleList_1_19_Part extends ParticleSupplier_1_19_Part { 23 | 24 | private final ParticleNativeAPI api; 25 | 26 | // 1.19 27 | public final ParticleTypeVibration VIBRATION = VIBRATION(); 28 | 29 | // 1.20.5 30 | public final ParticleTypeColor ENTITY_EFFECT = ENTITY_EFFECT(); 31 | 32 | // 1.21.10 33 | public final ParticleTypeColor FLASH = FLASH(); 34 | public final ParticleTypePowerMotion DRAGON_BREATH = DRAGON_BREATH(); 35 | public final ParticleTypeSpell EFFECT = EFFECT(); 36 | public final ParticleTypeSpell INSTANT_EFFECT = INSTANT_EFFECT(); 37 | 38 | protected ParticleList_1_19_Part(ParticleNativeAPI api) { 39 | this.api = api; 40 | } 41 | 42 | public ParticleNativeAPI getAPI() { 43 | return api; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /ParticleNativeAPI-api/src/main/java/com/github/fierioziy/particlenativeapi/api/particle/type/ParticleTypeItemMotion.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.api.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.utils.Shared; 4 | import org.bukkit.Material; 5 | 6 | /** 7 | *

Class used to represent item particle type that needs an item type.

8 | * 9 | *

It provides a non-reflective of method overloads 10 | * to construct ParticleTypeMotion with selected item type.

11 | * 12 | *

All of methods does not validate parameters in any way.

13 | * 14 | *

IMPORTANT NOTE: All methods annotated with {@link Shared} annotation 15 | * caches and returns exactly one and the same instance with changed state between method calls. 16 | * For an independent copy of returned instances, check detachCopy methods on them.

17 | * 18 | * @see ParticleTypeMotion 19 | */ 20 | public interface ParticleTypeItemMotion { 21 | 22 | /** 23 | *

Selects an item this particle should represents.

24 | * 25 | *

Parameters are not validated in any way.

26 | * 27 | *

This method is overridden by dynamically generated 28 | * subclasses.

29 | * 30 | * @param item a {@link Material} object representing 31 | * desired item type. 32 | * @return a valid {@link ParticleTypeMotion} object with selected 33 | * item type. 34 | */ 35 | @Shared ParticleTypeMotion of(Material item); 36 | 37 | /** 38 | *

Checks if this particle is supported by this Spigot version.

39 | * 40 | *

This method is overridden by dynamically generated 41 | * subclasses.

42 | * 43 | * @return true if this particle is supported by 44 | * this Spigot version, false otherwise. 45 | */ 46 | boolean isPresent(); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeDustColorTransitionIntImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleType; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeDustColorTransition; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | import org.bukkit.Color; 7 | 8 | public class ParticleTypeDustColorTransitionIntImpl 9 | implements ParticleTypeDustColorTransition { 10 | 11 | @Override 12 | public ParticleType color(Color color, Color transition, double size) { 13 | return color( 14 | color.getRed(), 15 | color.getGreen(), 16 | color.getBlue(), 17 | transition.getRed(), 18 | transition.getGreen(), 19 | transition.getBlue(), 20 | size 21 | ); 22 | } 23 | 24 | @Override 25 | public ParticleType color(int r, int g, int b, 26 | int tr, int tg, int tb, 27 | double size) { 28 | throw new ParticleException( 29 | "Requested particle type is not supported by this server version!" 30 | ); 31 | } 32 | 33 | @Override 34 | public ParticleType color(float r, float g, float b, 35 | float tr, float tg, float tb, 36 | float size) { 37 | // this is awful, but we have to live with that 38 | return color( 39 | (int) (r * 255F), (int) (g * 255F), (int) (b * 255F), 40 | (int) (tr * 255F), (int) (tg * 255F), (int) (tb * 255F), 41 | (double) size 42 | ); 43 | } 44 | 45 | @Override 46 | public boolean isPresent() { 47 | return false; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /ParticleNativeAPI-api/src/main/java/com/github/fierioziy/particlenativeapi/api/particle/type/ParticleTypeSculkChargeMotion.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.api.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.utils.Shared; 4 | 5 | /** 6 | *

Class used to represent sculk charge particle type that takes a roll parameter.

7 | * 8 | *

It provides a non-reflective of method overloads 9 | * to construct ParticleTypeMotion with selected roll.

10 | * 11 | *

All of methods does not validate parameters in any way.

12 | * 13 | *

IMPORTANT NOTE: All methods annotated with {@link Shared} annotation 14 | * caches and returns exactly one and the same instance with changed state between method calls. 15 | * For an independent copy of returned instances, check detachCopy methods on them.

16 | * 17 | * @see ParticleTypeMotion 18 | */ 19 | public interface ParticleTypeSculkChargeMotion { 20 | 21 | /** 22 | *

Selects roll angle this particle should be rotated. 23 | * An angle is in radians and will rotate particle clockwise

24 | * 25 | *

Parameters are not validated in any way.

26 | * 27 | *

This method is overridden by dynamically generated 28 | * subclasses.

29 | * 30 | * @param roll angle in radians by which to rotate particle clockwise. 31 | * @return a valid {@link ParticleTypeMotion} object with selected 32 | * roll angle. 33 | */ 34 | @Shared ParticleTypeMotion roll(double roll); 35 | 36 | /** 37 | *

Checks if this particle is supported by this Spigot version.

38 | * 39 | *

This method is overridden by dynamically generated 40 | * subclasses.

41 | * 42 | * @return true if this particle is supported by 43 | * this Spigot version, false otherwise. 44 | */ 45 | boolean isPresent(); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/BaseASM.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.mapping.SpigotClassRegistry; 4 | import org.objectweb.asm.Opcodes; 5 | 6 | public class BaseASM implements Opcodes { 7 | 8 | /* 9 | Constant names to ease possibly future refactoring 10 | */ 11 | 12 | // API 13 | public static final String DETACH_COPY_METHOD_NAME = "detachCopy"; 14 | public static final String SEND_TO_METHOD_NAME = "sendTo"; 15 | public static final String IS_PRESENT_METHOD_NAME = "isPresent"; 16 | 17 | public static final String PACKET_METHOD_NAME = "packet"; 18 | 19 | public static final String OF_METHOD_NAME = "of"; 20 | public static final String COLOR_METHOD_NAME = "color"; 21 | public static final String ROLL_METHOD_NAME = "roll"; 22 | public static final String DELAY_METHOD_NAME = "delay"; 23 | public static final String FLYING_TO_METHOD_NAME = "flyingTo"; 24 | public static final String SPELL_METHOD_NAME = "spell"; 25 | public static final String POWER_METHOD_NAME = "power"; 26 | 27 | // ASM 28 | public static final String PACKET_FIELD_NAME = "packet"; 29 | public static final String PACKET_WRAPPER_FIELD_NAME = "packetWrapper"; 30 | 31 | public static final String PARTICLE_FIELD_NAME = "particle"; 32 | public static final String PARTICLE_DATA_FIELD_NAME = "data";// for 1.8 33 | public static final String PARTICLE_WRAPPER_FIELD_NAME = "particleWrapper"; 34 | 35 | public static final String SET_PARTICLE_METHOD_NAME = "setParticle"; 36 | public static final String SET_PACKET_METHOD_NAME = "setPacket"; 37 | 38 | protected final ContextASM context; 39 | protected final SpigotClassRegistry refs; 40 | 41 | public BaseASM(ContextASM context) { 42 | this.context = context; 43 | this.refs = context.refs; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/StaticMockServerExtension.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.Server; 5 | import org.junit.jupiter.api.extension.*; 6 | 7 | import java.lang.reflect.Field; 8 | 9 | import static org.mockito.Mockito.mock; 10 | 11 | public class StaticMockServerExtension 12 | implements BeforeTestExecutionCallback, AfterTestExecutionCallback, ParameterResolver { 13 | 14 | private static final Field bukkitServerField; 15 | 16 | static { 17 | try { 18 | Field serverField = Bukkit.class.getDeclaredField("server"); 19 | serverField.setAccessible(true); 20 | bukkitServerField = serverField; 21 | } catch (NoSuchFieldException e) { 22 | throw new RuntimeException(e); 23 | } 24 | } 25 | 26 | @Override 27 | public void beforeTestExecution(ExtensionContext context) throws Exception { 28 | Server mockServer = mock(Server.class); 29 | bukkitServerField.set(null, mockServer); 30 | } 31 | 32 | @Override 33 | public void afterTestExecution(ExtensionContext context) throws Exception { 34 | bukkitServerField.set(null, null); 35 | } 36 | 37 | @Override 38 | public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) 39 | throws ParameterResolutionException { 40 | return parameterContext.getParameter().getType().equals(Server.class); 41 | } 42 | 43 | @Override 44 | public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) 45 | throws ParameterResolutionException { 46 | try { 47 | return bukkitServerField.get(null); 48 | } catch (IllegalAccessException e) { 49 | throw new ParameterResolutionException("Could not inject bukkit server mock", e); 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/particle/type/v1_17/skeleton/ParticleTypeSimpleSkeletonASM_1_17.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_17.skeleton; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.particle.type.skeleton.ParticleTypeSimpleSkeletonASM; 5 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 6 | import org.objectweb.asm.ClassWriter; 7 | import org.objectweb.asm.MethodVisitor; 8 | 9 | public abstract class ParticleTypeSimpleSkeletonASM_1_17 extends ParticleTypeSimpleSkeletonASM { 10 | 11 | public ParticleTypeSimpleSkeletonASM_1_17(ContextASM context, ClassSkeleton superType) { 12 | super(context, superType); 13 | } 14 | 15 | @Override 16 | protected void writeFields(ClassWriter cw) { 17 | cw.visitField(ACC_PRIVATE, PARTICLE_FIELD_NAME, refs.particle_1_17.desc(), null, null).visitEnd(); 18 | 19 | writePacketField(cw); 20 | } 21 | 22 | @Override 23 | protected void writeConstructors(ClassWriter cw) { 24 | MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "", 25 | "(" + refs.particle_1_17.desc() + ")V", null, null); 26 | mv.visitCode(); 27 | 28 | int local_this = 0; 29 | int local_particle = 1; 30 | 31 | mv.visitVarInsn(ALOAD, local_this); 32 | mv.visitMethodInsn(INVOKESPECIAL, 33 | superType.internalName(), 34 | "", 35 | "()V", false); 36 | 37 | // this.particle = particle; 38 | mv.visitVarInsn(ALOAD, local_this); 39 | mv.visitVarInsn(ALOAD, local_particle); 40 | mv.visitFieldInsn(PUTFIELD, implType.internalName(), 41 | PARTICLE_FIELD_NAME, refs.particle_1_17.desc()); 42 | 43 | // this.packet = new ParticlePacketImpl_X(); 44 | writePacketAssignment(mv); 45 | 46 | mv.visitInsn(RETURN); 47 | 48 | mv.visitMaxs(0, 0); 49 | mv.visitEnd(); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/SpigotClassRegistryProvider_1_7.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.mapping.SpigotClassRegistry; 4 | import com.github.fierioziy.particlenativeapi.core.asm.mapping.SpigotClassRegistryProvider; 5 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.common.Packet; 6 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_7.EntityPlayer_1_7; 7 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_7.PacketPlayOutWorldParticles_1_7; 8 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_7.PlayerConnection_1_7; 9 | import com.github.fierioziy.particlenativeapi.core.mocks.obc.v1_7.entity.CraftPlayer_1_7; 10 | import org.bukkit.Material; 11 | import org.bukkit.inventory.ItemStack; 12 | 13 | public class SpigotClassRegistryProvider_1_7 implements SpigotClassRegistryProvider { 14 | 15 | public SpigotClassRegistry provideRegistry() { 16 | SpigotClassRegistry classRegistry = new SpigotClassRegistry(); 17 | 18 | // Spigot 19 | classRegistry.material = classRegistry.of(Material.class); 20 | classRegistry.blockData = classRegistry.EMPTY_MAPPING; 21 | classRegistry.itemStackBukkit = classRegistry.of(ItemStack.class); 22 | 23 | // OBC 24 | classRegistry.craftPlayer = classRegistry.of(CraftPlayer_1_7.class); 25 | 26 | // NMS 27 | 28 | /* 29 | pre 1.17 30 | */ 31 | classRegistry.entityPlayer_1_7 = classRegistry.of(EntityPlayer_1_7.class); 32 | classRegistry.packet_1_7 = classRegistry.of(Packet.class); 33 | classRegistry.playerConnection_1_7 = classRegistry.of(PlayerConnection_1_7.class); 34 | 35 | classRegistry.packetPlayOutWorldParticles_1_7 = classRegistry.of(PacketPlayOutWorldParticles_1_7.class); 36 | 37 | return classRegistry; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/particle/type/v1_7/skeleton/ParticleTypeComplexSkeletonASM_1_7.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_7.skeleton; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.particle.type.skeleton.ParticleTypeComplexSkeletonASM; 5 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 6 | import org.objectweb.asm.ClassWriter; 7 | import org.objectweb.asm.MethodVisitor; 8 | 9 | public abstract class ParticleTypeComplexSkeletonASM_1_7 extends ParticleTypeComplexSkeletonASM { 10 | 11 | public ParticleTypeComplexSkeletonASM_1_7(ContextASM context, 12 | ClassSkeleton superType, ClassSkeleton returnType) { 13 | super(context, superType, returnType); 14 | } 15 | 16 | @Override 17 | protected void writeFields(ClassWriter cw) { 18 | cw.visitField(ACC_PRIVATE, PARTICLE_FIELD_NAME, "Ljava/lang/String;", null, null).visitEnd(); 19 | 20 | writeParticleTypeField(cw); 21 | } 22 | 23 | @Override 24 | protected void writeConstructors(ClassWriter cw) { 25 | MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "", "(Ljava/lang/String;)V", null, null); 26 | mv.visitCode(); 27 | 28 | int local_this = 0; 29 | int local_particle = 1; 30 | 31 | mv.visitVarInsn(ALOAD, local_this); 32 | mv.visitMethodInsn(INVOKESPECIAL, 33 | superType.internalName(), 34 | "", 35 | "()V", false); 36 | 37 | // this.particle = particle; 38 | mv.visitVarInsn(ALOAD, local_this); 39 | mv.visitVarInsn(ALOAD, local_particle); 40 | mv.visitFieldInsn(PUTFIELD, 41 | implType.internalName(), 42 | PARTICLE_FIELD_NAME, 43 | "Ljava/lang/String;"); 44 | 45 | // this.particleWrapper = new ParticleTypeImpl_X(); 46 | writeParticleTypeAssignment(mv); 47 | 48 | mv.visitInsn(RETURN); 49 | 50 | mv.visitMaxs(0, 0); 51 | mv.visitEnd(); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/particle/type/v1_13/skeleton/ParticleTypeComplexSkeletonASM_1_13.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_13.skeleton; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.particle.type.skeleton.ParticleTypeComplexSkeletonASM; 5 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 6 | import org.objectweb.asm.ClassWriter; 7 | import org.objectweb.asm.MethodVisitor; 8 | 9 | public abstract class ParticleTypeComplexSkeletonASM_1_13 extends ParticleTypeComplexSkeletonASM { 10 | 11 | public ParticleTypeComplexSkeletonASM_1_13(ContextASM context, 12 | ClassSkeleton superType, ClassSkeleton returnType) { 13 | super(context, superType, returnType); 14 | } 15 | 16 | @Override 17 | protected void writeFields(ClassWriter cw) { 18 | cw.visitField(ACC_PRIVATE, PARTICLE_FIELD_NAME, refs.particle_1_7.desc(), null, null).visitEnd(); 19 | 20 | writeParticleTypeField(cw); 21 | } 22 | 23 | @Override 24 | protected void writeConstructors(ClassWriter cw) { 25 | MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "", 26 | "(" + refs.particle_1_7.desc() + ")V", null, null); 27 | mv.visitCode(); 28 | 29 | int local_this = 0; 30 | int local_particle = 1; 31 | 32 | mv.visitVarInsn(ALOAD, local_this); 33 | mv.visitMethodInsn(INVOKESPECIAL, 34 | superType.internalName(), 35 | "", 36 | "()V", false); 37 | 38 | // this.particle = particle; 39 | mv.visitVarInsn(ALOAD, local_this); 40 | mv.visitVarInsn(ALOAD, local_particle); 41 | mv.visitFieldInsn(PUTFIELD, 42 | implType.internalName(), 43 | PARTICLE_FIELD_NAME, 44 | refs.particle_1_7.desc()); 45 | 46 | // this.particleWrapper = new ParticleTypeImpl_X(); 47 | writeParticleTypeAssignment(mv); 48 | 49 | mv.visitInsn(RETURN); 50 | 51 | mv.visitMaxs(0, 0); 52 | mv.visitEnd(); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/particle/type/v1_17/skeleton/ParticleTypeComplexSkeletonASM_1_17.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_17.skeleton; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.particle.type.skeleton.ParticleTypeComplexSkeletonASM; 5 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 6 | import org.objectweb.asm.ClassWriter; 7 | import org.objectweb.asm.MethodVisitor; 8 | 9 | public abstract class ParticleTypeComplexSkeletonASM_1_17 extends ParticleTypeComplexSkeletonASM { 10 | 11 | public ParticleTypeComplexSkeletonASM_1_17(ContextASM context, 12 | ClassSkeleton superType, ClassSkeleton returnType) { 13 | super(context, superType, returnType); 14 | } 15 | 16 | @Override 17 | protected void writeFields(ClassWriter cw) { 18 | cw.visitField(ACC_PRIVATE, PARTICLE_FIELD_NAME, refs.particle_1_17.desc(), null, null).visitEnd(); 19 | 20 | writeParticleTypeField(cw); 21 | } 22 | 23 | @Override 24 | protected void writeConstructors(ClassWriter cw) { 25 | MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "", 26 | "(" + refs.particle_1_17.desc() + ")V", null, null); 27 | mv.visitCode(); 28 | 29 | int local_this = 0; 30 | int local_particle = 1; 31 | 32 | mv.visitVarInsn(ALOAD, local_this); 33 | mv.visitMethodInsn(INVOKESPECIAL, 34 | superType.internalName(), 35 | "", 36 | "()V", false); 37 | 38 | // this.particle = particle; 39 | mv.visitVarInsn(ALOAD, local_this); 40 | mv.visitVarInsn(ALOAD, local_particle); 41 | mv.visitFieldInsn(PUTFIELD, implType.internalName(), 42 | PARTICLE_FIELD_NAME, refs.particle_1_17.desc()); 43 | 44 | // this.particleWrapper = new ParticleTypeImpl_X(); 45 | writeParticleTypeAssignment(mv); 46 | 47 | mv.visitInsn(RETURN); 48 | 49 | mv.visitMaxs(0, 0); 50 | mv.visitEnd(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/particle/ParticleListASM.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 5 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeletonASM; 6 | import com.github.fierioziy.particlenativeapi.core.asm.particle.type.ParticleTypesProvider; 7 | import com.github.fierioziy.particlenativeapi.core.asm.utils.SpigotParticleVersion; 8 | import org.objectweb.asm.ClassWriter; 9 | import org.objectweb.asm.MethodVisitor; 10 | 11 | public class ParticleListASM extends ClassSkeletonASM { 12 | 13 | private final SpigotParticleVersion particleVersion; 14 | private final ParticleTypesProvider particleTypesProvider; 15 | 16 | private final ClassSkeleton skeleton; 17 | 18 | public ParticleListASM(ContextASM context, 19 | SpigotParticleVersion particleVersion, 20 | ClassSkeleton skeleton) { 21 | super(context, skeleton); 22 | this.particleVersion = particleVersion; 23 | this.skeleton = skeleton; 24 | this.particleTypesProvider = context.particleTypesProvider; 25 | } 26 | 27 | @Override 28 | public void writeFields(ClassWriter cw) { 29 | 30 | } 31 | 32 | @Override 33 | public void writeConstructors(ClassWriter cw) { 34 | MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, 35 | "", "(" + refs.particleNativeAPI.desc() + ")V", null, null); 36 | mv.visitCode(); 37 | 38 | int local_this = 0; 39 | int local_api = 1; 40 | 41 | mv.visitVarInsn(ALOAD, local_this); 42 | mv.visitVarInsn(ALOAD, local_api); 43 | mv.visitMethodInsn(INVOKESPECIAL, 44 | superType.internalName(), 45 | "", 46 | "(" + refs.particleNativeAPI.desc() + ")V", false); 47 | 48 | mv.visitInsn(RETURN); 49 | 50 | mv.visitMaxs(0, 0); 51 | mv.visitEnd(); 52 | } 53 | 54 | @Override 55 | public void writeMethods(ClassWriter cw) { 56 | particleTypesProvider.generateParticleFactoryMethods(cw, particleVersion, skeleton); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/particle/type/skeleton/ParticleTypeSimpleSkeletonASM.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle.type.skeleton; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.mapping.ClassMapping; 5 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 6 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeletonASM; 7 | import org.objectweb.asm.ClassWriter; 8 | import org.objectweb.asm.MethodVisitor; 9 | 10 | public abstract class ParticleTypeSimpleSkeletonASM extends ClassSkeletonASM { 11 | 12 | protected final ClassMapping particlePacketImpl_X; 13 | 14 | public ParticleTypeSimpleSkeletonASM(ContextASM context, ClassSkeleton superType) { 15 | super(context, superType); 16 | 17 | this.particlePacketImpl_X = context.particlePacketImpl_X; 18 | } 19 | 20 | protected void writePacketField(ClassWriter cw) { 21 | cw.visitField(0, PACKET_WRAPPER_FIELD_NAME, particlePacketImpl_X.desc(), null, null).visitEnd(); 22 | } 23 | 24 | protected void writePacketAssignment(MethodVisitor mv) { 25 | int local_this = 0; 26 | 27 | // this.packet = new ParticlePacketImpl_X(); 28 | mv.visitVarInsn(ALOAD, local_this); 29 | 30 | mv.visitTypeInsn(NEW, particlePacketImpl_X.internalName()); 31 | mv.visitInsn(DUP); 32 | mv.visitMethodInsn(INVOKESPECIAL, 33 | particlePacketImpl_X.internalName(), 34 | "", 35 | "()V", false); 36 | 37 | mv.visitFieldInsn(PUTFIELD, 38 | implType.internalName(), 39 | PACKET_WRAPPER_FIELD_NAME, 40 | particlePacketImpl_X.desc()); 41 | } 42 | 43 | protected void writeCommonMethods(ClassWriter cw) { 44 | writeMethod_isPresent(cw); 45 | } 46 | 47 | protected void writeMethod_isPresent(ClassWriter cw) { 48 | MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, IS_PRESENT_METHOD_NAME, "()Z", null, null); 49 | mv.visitCode(); 50 | 51 | mv.visitInsn(ICONST_1); 52 | mv.visitInsn(IRETURN); 53 | 54 | mv.visitMaxs(0, 0); 55 | mv.visitEnd(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/SpigotClassRegistryProvider_1_8.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.mapping.SpigotClassRegistry; 4 | import com.github.fierioziy.particlenativeapi.core.asm.mapping.SpigotClassRegistryProvider; 5 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.common.Packet; 6 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_7.EntityPlayer_1_7; 7 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_7.PlayerConnection_1_7; 8 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_8.EnumParticle; 9 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_8.PacketPlayOutWorldParticles_1_8; 10 | import com.github.fierioziy.particlenativeapi.core.mocks.obc.v1_7.entity.CraftPlayer_1_7; 11 | import org.bukkit.Material; 12 | import org.bukkit.inventory.ItemStack; 13 | 14 | public class SpigotClassRegistryProvider_1_8 implements SpigotClassRegistryProvider { 15 | 16 | public SpigotClassRegistry provideRegistry() { 17 | SpigotClassRegistry classRegistry = new SpigotClassRegistry(); 18 | 19 | // Spigot 20 | classRegistry.material = classRegistry.of(Material.class); 21 | classRegistry.blockData = classRegistry.EMPTY_MAPPING; 22 | classRegistry.itemStackBukkit = classRegistry.of(ItemStack.class); 23 | 24 | // OBC 25 | classRegistry.craftPlayer = classRegistry.of(CraftPlayer_1_7.class); 26 | 27 | // NMS 28 | classRegistry.enumParticle = classRegistry.of(EnumParticle.class); 29 | 30 | /* 31 | pre 1.17 32 | */ 33 | classRegistry.entityPlayer_1_7 = classRegistry.of(EntityPlayer_1_7.class); 34 | classRegistry.packet_1_7 = classRegistry.of(Packet.class); 35 | classRegistry.playerConnection_1_7 = classRegistry.of(PlayerConnection_1_7.class); 36 | 37 | classRegistry.packetPlayOutWorldParticles_1_7 = classRegistry.of(PacketPlayOutWorldParticles_1_8.class); 38 | 39 | return classRegistry; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/particle/ParticleListProvider.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.BaseASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 5 | import com.github.fierioziy.particlenativeapi.core.asm.packet.ParticlePacketProvider; 6 | import com.github.fierioziy.particlenativeapi.core.asm.particle.type.*; 7 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 8 | import com.github.fierioziy.particlenativeapi.core.asm.utils.SpigotParticleVersion; 9 | 10 | public class ParticleListProvider extends BaseASM { 11 | 12 | private final ParticlePacketProvider particlePacketProvider; 13 | private final ParticleTypesProvider particleTypesProvider; 14 | 15 | private ParticleListASM particleListASM_1_8; 16 | private ParticleListASM particleListASM_1_13; 17 | private ParticleListASM particleListASM_1_19_part; 18 | 19 | public ParticleListProvider(ContextASM context) { 20 | super(context); 21 | particlePacketProvider = context.particlePacketProvider; 22 | particleTypesProvider = context.particleTypesProvider; 23 | } 24 | 25 | public void registerClasses() { 26 | particlePacketProvider.registerClasses(); 27 | particleTypesProvider.registerClasses(); 28 | 29 | particleListASM_1_8 = new ParticleListASM(context, 30 | SpigotParticleVersion.V1_8, 31 | ClassSkeleton.PARTICLE_LIST_1_8 32 | ); 33 | particleListASM_1_8.registerClass(); 34 | 35 | particleListASM_1_13 = new ParticleListASM(context, 36 | SpigotParticleVersion.V1_13, 37 | ClassSkeleton.PARTICLE_LIST_1_13 38 | ); 39 | particleListASM_1_13.registerClass(); 40 | 41 | particleListASM_1_19_part = new ParticleListASM(context, 42 | SpigotParticleVersion.V1_18, 43 | ClassSkeleton.PARTICLE_LIST_1_19_PART 44 | ); 45 | particleListASM_1_19_part.registerClass(); 46 | } 47 | 48 | public ParticleListASM getParticleListASM_1_8() { 49 | return particleListASM_1_8; 50 | } 51 | 52 | public ParticleListASM getParticleListASM_1_13() { 53 | return particleListASM_1_13; 54 | } 55 | 56 | public ParticleListASM getParticleListASM_1_19_part() { 57 | return particleListASM_1_19_part; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/skeleton/ClassSkeletonASM.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.skeleton; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.BaseASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 5 | import com.github.fierioziy.particlenativeapi.core.asm.mapping.ClassMapping; 6 | import org.objectweb.asm.ClassWriter; 7 | 8 | import java.util.Arrays; 9 | 10 | public abstract class ClassSkeletonASM extends BaseASM { 11 | 12 | protected ClassMapping superType; 13 | protected ClassMapping interfaceType; 14 | protected ClassMapping implType; 15 | 16 | protected ClassMapping[] interfaceTypes; 17 | 18 | public ClassSkeletonASM(ContextASM context, ClassSkeleton skeleton, 19 | ClassMapping... interfaceTypes) { 20 | super(context); 21 | superType = skeleton.getSuperType(); 22 | interfaceType = skeleton.getInterfaceType(); 23 | implType = skeleton.getImpl(context.suffix); 24 | this.interfaceTypes = interfaceTypes; 25 | } 26 | 27 | public void registerClass() { 28 | context.internal.getParticleNativeClassLoader() 29 | .registerClass(implType.className(), generateBytecode()); 30 | } 31 | 32 | public Class loadClass() throws ClassNotFoundException { 33 | return context.internal.getParticleNativeClassLoader() 34 | .loadClass(implType.className()); 35 | } 36 | 37 | private byte[] generateBytecode() { 38 | ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); 39 | 40 | String[] interfaceInternalNames = Arrays.stream(interfaceTypes) 41 | .map(ClassMapping::internalName) 42 | .toArray(String[]::new); 43 | 44 | cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, 45 | implType.internalName(), null, 46 | superType.internalName(), interfaceInternalNames); 47 | 48 | writeFields(cw); 49 | writeConstructors(cw); 50 | 51 | writeMethods(cw); 52 | 53 | cw.visitEnd(); 54 | return cw.toByteArray(); 55 | } 56 | 57 | protected abstract void writeFields(ClassWriter cw); 58 | protected abstract void writeConstructors(ClassWriter cw); 59 | protected abstract void writeMethods(ClassWriter cw); 60 | 61 | public ClassMapping getImplType() { 62 | return implType; 63 | } 64 | 65 | public ClassMapping getSuperType() { 66 | return superType; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/particle/type/v1_8/skeleton/ParticleTypeComplexSkeletonASM_1_8.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_8.skeleton; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.particle.type.skeleton.ParticleTypeComplexSkeletonASM; 5 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 6 | import org.objectweb.asm.ClassWriter; 7 | import org.objectweb.asm.MethodVisitor; 8 | 9 | public abstract class ParticleTypeComplexSkeletonASM_1_8 extends ParticleTypeComplexSkeletonASM { 10 | 11 | public ParticleTypeComplexSkeletonASM_1_8(ContextASM context, 12 | ClassSkeleton superType, ClassSkeleton returnType) { 13 | super(context, superType, returnType); 14 | } 15 | 16 | @Override 17 | protected void writeFields(ClassWriter cw) { 18 | cw.visitField(ACC_PRIVATE, PARTICLE_FIELD_NAME, refs.enumParticle.desc(), null, null).visitEnd(); 19 | cw.visitField(ACC_PRIVATE, PARTICLE_DATA_FIELD_NAME, "[I", null, null).visitEnd(); 20 | 21 | writeParticleTypeField(cw); 22 | } 23 | 24 | @Override 25 | protected void writeConstructors(ClassWriter cw) { 26 | MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "", 27 | "(" + refs.enumParticle.desc() + "[I)V", null, null); 28 | mv.visitCode(); 29 | 30 | int local_this = 0; 31 | int local_particle = 1; 32 | int local_arr = 2; 33 | 34 | mv.visitVarInsn(ALOAD, local_this); 35 | mv.visitMethodInsn(INVOKESPECIAL, 36 | superType.internalName(), 37 | "", 38 | "()V", false); 39 | 40 | // this.particle = particle; 41 | mv.visitVarInsn(ALOAD, local_this); 42 | mv.visitVarInsn(ALOAD, local_particle); 43 | mv.visitFieldInsn(PUTFIELD, 44 | implType.internalName(), 45 | PARTICLE_FIELD_NAME, 46 | refs.enumParticle.desc()); 47 | 48 | // this.data = arr; 49 | mv.visitVarInsn(ALOAD, local_this); 50 | mv.visitVarInsn(ALOAD, local_arr); 51 | mv.visitFieldInsn(PUTFIELD, 52 | implType.internalName(), 53 | PARTICLE_DATA_FIELD_NAME, 54 | "[I"); 55 | 56 | // this.particleWrapper = new ParticleTypeImpl_X(); 57 | writeParticleTypeAssignment(mv); 58 | 59 | mv.visitInsn(RETURN); 60 | 61 | mv.visitMaxs(0, 0); 62 | mv.visitEnd(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeBlockTest.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleType; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeBlock; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | import org.bukkit.Material; 7 | import org.junit.jupiter.api.BeforeEach; 8 | import org.junit.jupiter.api.Test; 9 | import org.junit.jupiter.api.extension.ExtendWith; 10 | import org.mockito.Spy; 11 | import org.mockito.junit.jupiter.MockitoExtension; 12 | 13 | import static org.junit.jupiter.api.Assertions.*; 14 | import static org.mockito.Mockito.*; 15 | 16 | @ExtendWith(MockitoExtension.class) 17 | public class ParticleTypeBlockTest { 18 | 19 | @Spy 20 | private ParticleTypeBlock invalidParticleType = new ParticleTypeBlockImpl(); 21 | 22 | @Spy 23 | private ParticleTypeBlock particleType = new ParticleTypeBlockImpl(); 24 | 25 | @BeforeEach 26 | public void prepareParticleType() { 27 | // make it look like valid 28 | doReturn(true).when(particleType).isPresent(); 29 | 30 | // make it return dummy particle type on 'of' method 31 | // to avoid ParticleException 32 | lenient() 33 | .doReturn(mock(ParticleType.class)) 34 | .when(particleType) 35 | .of(any(Material.class), anyByte()); 36 | 37 | assertFalse(invalidParticleType.isPresent(), 38 | "Invalid ParticleType is for some reason valid"); 39 | 40 | assertTrue(particleType.isPresent(), 41 | "ParticleType is for some reason invalid"); 42 | } 43 | 44 | /* 45 | Verify invalid particle type 46 | */ 47 | 48 | @Test 49 | public void testExceptionOnInvalidType() { 50 | assertThrows(ParticleException.class, () -> invalidParticleType.of(Material.DIAMOND_BLOCK, (byte) 0)); 51 | } 52 | 53 | /* 54 | Verify method argument expansion 55 | */ 56 | 57 | @Test 58 | public void test_of_Material() { 59 | Material targetMat = Material.DIAMOND_BLOCK; 60 | byte targetByte = 0; 61 | 62 | particleType.of(targetMat); 63 | 64 | verify(particleType).of(targetMat, targetByte); 65 | } 66 | 67 | @Test 68 | public void test_of_Material_Int() { 69 | Material targetMat = Material.DIAMOND_BLOCK; 70 | byte targetByte = 2; 71 | 72 | particleType.of(targetMat, (int) targetByte); 73 | 74 | verify(particleType).of(targetMat, targetByte); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/particle/type/skeleton/ParticleTypeComplexSkeletonASM.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle.type.skeleton; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.mapping.ClassMapping; 5 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 6 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeletonASM; 7 | import org.objectweb.asm.ClassWriter; 8 | import org.objectweb.asm.MethodVisitor; 9 | 10 | public abstract class ParticleTypeComplexSkeletonASM extends ClassSkeletonASM { 11 | 12 | protected final ClassMapping superReturnType; 13 | protected final ClassMapping interfaceReturnType; 14 | protected final ClassMapping implReturnType; 15 | 16 | public ParticleTypeComplexSkeletonASM(ContextASM context, 17 | ClassSkeleton superType, ClassSkeleton returnType) { 18 | super(context, superType); 19 | 20 | this.superReturnType = returnType.getSuperType(); 21 | this.interfaceReturnType = returnType.getInterfaceType(); 22 | this.implReturnType = returnType.getImpl(context.suffix); 23 | } 24 | 25 | protected void writeParticleTypeField(ClassWriter cw) { 26 | cw.visitField(0, PARTICLE_WRAPPER_FIELD_NAME, implReturnType.desc(), null, null).visitEnd(); 27 | } 28 | 29 | protected void writeParticleTypeAssignment(MethodVisitor mv) { 30 | // this will be constant in all constructors 31 | int local_this = 0; 32 | 33 | // this.particleType = new ParticleTypeImpl_X(); 34 | mv.visitVarInsn(ALOAD, local_this); 35 | 36 | mv.visitTypeInsn(NEW, implReturnType.internalName()); 37 | mv.visitInsn(DUP); 38 | mv.visitMethodInsn(INVOKESPECIAL, 39 | implReturnType.internalName(), 40 | "", 41 | "()V", false); 42 | 43 | mv.visitFieldInsn(PUTFIELD, 44 | implType.internalName(), 45 | PARTICLE_WRAPPER_FIELD_NAME, 46 | implReturnType.desc()); 47 | } 48 | 49 | protected void writeCommonMethods(ClassWriter cw) { 50 | writeMethod_isPresent(cw); 51 | } 52 | 53 | private void writeMethod_isPresent(ClassWriter cw) { 54 | MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, IS_PRESENT_METHOD_NAME, "()Z", null, null); 55 | mv.visitCode(); 56 | 57 | mv.visitInsn(ICONST_1); 58 | mv.visitInsn(IRETURN); 59 | 60 | mv.visitMaxs(0, 0); 61 | mv.visitEnd(); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_17/IRegistry_1_17.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.Particle; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.Particles_1_13; 5 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_18.Particles_1_18; 6 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_19.Particles_1_19; 7 | 8 | public abstract class IRegistry_1_17 { 9 | 10 | public static final IRegistry_1_17> ab = new IRegistry_1_17>() { 11 | @Override 12 | public MinecraftKey getKey_possiblyObfuscated(Particle paramT) { 13 | if (paramT == Particles_1_13.LAVA) return new MinecraftKey("barrier"); 14 | else if (paramT == Particles_1_18.HEART) return new MinecraftKey("heart"); 15 | else if (paramT == Particles_1_13.FALLING_DUST) return new MinecraftKey("falling_dust"); 16 | else if (paramT == Particles_1_13.BLOCK) return new MinecraftKey("block"); 17 | else if (paramT == Particles_1_13.ENTITY_EFFECT) return new MinecraftKey("entity_effect"); 18 | else if (paramT == Particles_1_13.DUST) return new MinecraftKey("dust"); 19 | else if (paramT == Particles_1_17.DUST_COLOR_TRANSITION) return new MinecraftKey("dust_color_transition"); 20 | else if (paramT == Particles_1_17.VIBRATION) return new MinecraftKey("vibration"); 21 | else if (paramT == Particles_1_13.ITEM) return new MinecraftKey("item"); 22 | else if (paramT == Particles_1_13.FLAME) return new MinecraftKey("flame"); 23 | else if (paramT == Particles_1_13.NOTE) return new MinecraftKey("note"); 24 | else if (paramT == Particles_1_18.BLOCK_MARKER) return new MinecraftKey("block_marker"); 25 | else if (paramT == Particles_1_19.SCULK_CHARGE) return new MinecraftKey("sculk_charge"); 26 | else if (paramT == Particles_1_19.SHRIEK) return new MinecraftKey("shriek"); 27 | else if (paramT == Particles_1_19.DRAGON_BREATH) return new MinecraftKey("dragon_breath"); 28 | else if (paramT == Particles_1_19.EFFECT) return new MinecraftKey("effect"); 29 | 30 | throw new RuntimeException("Unknown particle in Particles"); 31 | } 32 | }; 33 | 34 | public abstract MinecraftKey getKey_possiblyObfuscated(T paramT); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeSpellTest.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleType; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeSpell; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | import org.bukkit.Color; 7 | import org.junit.jupiter.api.BeforeEach; 8 | import org.junit.jupiter.api.Test; 9 | import org.junit.jupiter.api.extension.ExtendWith; 10 | import org.mockito.Spy; 11 | import org.mockito.junit.jupiter.MockitoExtension; 12 | 13 | import static org.junit.jupiter.api.Assertions.*; 14 | import static org.mockito.Mockito.*; 15 | 16 | @ExtendWith(MockitoExtension.class) 17 | public class ParticleTypeSpellTest { 18 | 19 | @Spy 20 | private ParticleTypeSpell invalidParticleType = new ParticleTypeSpellImpl(); 21 | 22 | @Spy 23 | private ParticleTypeSpell particleType = new ParticleTypeSpellImpl(); 24 | 25 | @BeforeEach 26 | public void prepareParticleType() { 27 | // make it look like valid 28 | doReturn(true).when(particleType).isPresent(); 29 | 30 | // make it return dummy particle type on 'spell' method 31 | // to avoid ParticleException 32 | lenient() 33 | .doReturn(mock(ParticleType.class)) 34 | .when(particleType) 35 | .spell(anyInt(), anyInt(), anyInt(), anyInt(), anyDouble()); 36 | 37 | assertFalse(invalidParticleType.isPresent(), 38 | "Invalid ParticleType is for some reason valid"); 39 | 40 | assertTrue(particleType.isPresent(), 41 | "ParticleType is for some reason invalid"); 42 | } 43 | 44 | private void verifyArgumentPass(int r, int g, int b, int alpha, double power) { 45 | verify(particleType).spell(r, g, b, alpha, power); 46 | } 47 | 48 | /* 49 | Verify invalid particle type 50 | */ 51 | 52 | @Test 53 | public void testExceptionOnInvalidType() { 54 | assertThrows(ParticleException.class, () -> invalidParticleType.spell(255, 255, 255, 255, 2D)); 55 | } 56 | 57 | /* 58 | Verify method argument expansion 59 | */ 60 | 61 | @Test 62 | public void test_spell_Color_alpha_power() { 63 | int red = 255; 64 | int green = 120; 65 | int blue = 60; 66 | int alpha = 125; 67 | double power = 2D; 68 | Color color = Color.fromRGB(red, green, blue); 69 | 70 | particleType.spell(color, alpha, power); 71 | 72 | verifyArgumentPass(red, green, blue, alpha, power); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/particle/type/FakePacket.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.util.Vector; 5 | 6 | public class FakePacket { 7 | 8 | private boolean far; 9 | private double x, y, z; 10 | private double offsetX, offsetY, offsetZ; 11 | private double speed; 12 | private int count; 13 | 14 | public FakePacket(boolean far, double x, double y, double z, 15 | double offsetX, double offsetY, double offsetZ, 16 | double speed, int count) { 17 | this.far = far; 18 | this.x = x; 19 | this.y = y; 20 | this.z = z; 21 | this.offsetX = offsetX; 22 | this.offsetY = offsetY; 23 | this.offsetZ = offsetZ; 24 | this.speed = speed; 25 | this.count = count; 26 | } 27 | 28 | public Location getLocation() { 29 | return new Location(null, x, y, z); 30 | } 31 | 32 | public Vector getVector() { 33 | return new Vector(x, y, z); 34 | } 35 | 36 | public boolean isFar() { 37 | return far; 38 | } 39 | 40 | public void setFar(boolean far) { 41 | this.far = far; 42 | } 43 | 44 | public double getX() { 45 | return x; 46 | } 47 | 48 | public void setX(double x) { 49 | this.x = x; 50 | } 51 | 52 | public double getY() { 53 | return y; 54 | } 55 | 56 | public void setY(double y) { 57 | this.y = y; 58 | } 59 | 60 | public double getZ() { 61 | return z; 62 | } 63 | 64 | public void setZ(double z) { 65 | this.z = z; 66 | } 67 | 68 | public double getOffsetX() { 69 | return offsetX; 70 | } 71 | 72 | public void setOffsetX(double offsetX) { 73 | this.offsetX = offsetX; 74 | } 75 | 76 | public double getOffsetY() { 77 | return offsetY; 78 | } 79 | 80 | public void setOffsetY(double offsetY) { 81 | this.offsetY = offsetY; 82 | } 83 | 84 | public double getOffsetZ() { 85 | return offsetZ; 86 | } 87 | 88 | public void setOffsetZ(double offsetZ) { 89 | this.offsetZ = offsetZ; 90 | } 91 | 92 | public double getSpeed() { 93 | return speed; 94 | } 95 | 96 | public void setSpeed(double speed) { 97 | this.speed = speed; 98 | } 99 | 100 | public int getCount() { 101 | return count; 102 | } 103 | 104 | public void setCount(int count) { 105 | this.count = count; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeBlockMotionTest.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeBlockMotion; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeMotion; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | import org.bukkit.Material; 7 | import org.junit.jupiter.api.BeforeEach; 8 | import org.junit.jupiter.api.Test; 9 | import org.junit.jupiter.api.extension.ExtendWith; 10 | import org.mockito.Spy; 11 | import org.mockito.junit.jupiter.MockitoExtension; 12 | 13 | import static org.junit.jupiter.api.Assertions.*; 14 | import static org.mockito.Mockito.*; 15 | 16 | @ExtendWith(MockitoExtension.class) 17 | public class ParticleTypeBlockMotionTest { 18 | 19 | @Spy 20 | private ParticleTypeBlockMotion invalidParticleType = new ParticleTypeBlockMotionImpl(); 21 | 22 | @Spy 23 | private ParticleTypeBlockMotion particleType = new ParticleTypeBlockMotionImpl(); 24 | 25 | @BeforeEach 26 | public void prepareParticleType() { 27 | // make it look like valid 28 | doReturn(true).when(particleType).isPresent(); 29 | 30 | // make it return dummy particle type on 'of' method 31 | // to avoid ParticleException 32 | lenient() 33 | .doReturn(mock(ParticleTypeMotion.class)) 34 | .when(particleType) 35 | .of(any(Material.class), anyByte()); 36 | 37 | 38 | assertFalse(invalidParticleType.isPresent(), 39 | "Invalid ParticleType is for some reason valid"); 40 | 41 | assertTrue(particleType.isPresent(), 42 | "ParticleType is for some reason invalid"); 43 | } 44 | 45 | /* 46 | Verify invalid particle type 47 | */ 48 | 49 | @Test 50 | public void testExceptionOnInvalidType() { 51 | assertThrows(ParticleException.class, () -> invalidParticleType.of(Material.DIAMOND_BLOCK, (byte) 0)); 52 | } 53 | 54 | /* 55 | Verify method argument expansion 56 | */ 57 | 58 | @Test 59 | public void test_of_Material() { 60 | Material targetMat = Material.DIAMOND_BLOCK; 61 | byte targetByte = 0; 62 | 63 | particleType.of(targetMat); 64 | 65 | verify(particleType).of(targetMat, targetByte); 66 | } 67 | 68 | @Test 69 | public void test_of_Material_Int() { 70 | Material targetMat = Material.DIAMOND_BLOCK; 71 | byte targetByte = 2; 72 | 73 | particleType.of(targetMat, (int) targetByte); 74 | 75 | verify(particleType).of(targetMat, targetByte); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/particle/type/v1_19/ParticleTypeShriekASM_1_19.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_19; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_17.skeleton.ParticleTypeComplexSkeletonASM_1_17; 5 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 6 | import org.objectweb.asm.ClassWriter; 7 | import org.objectweb.asm.MethodVisitor; 8 | 9 | public class ParticleTypeShriekASM_1_19 extends ParticleTypeComplexSkeletonASM_1_17 { 10 | 11 | public ParticleTypeShriekASM_1_19(ContextASM context, 12 | ClassSkeleton superType, ClassSkeleton returnType) { 13 | super(context, superType, returnType); 14 | } 15 | 16 | @Override 17 | protected void writeMethods(ClassWriter cw) { 18 | writeMethod_delay(cw); 19 | 20 | writeCommonMethods(cw); 21 | } 22 | 23 | private void writeMethod_delay(ClassWriter cw) { 24 | MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, 25 | DELAY_METHOD_NAME, 26 | "(I)" + interfaceReturnType.desc(), null, null); 27 | mv.visitCode(); 28 | 29 | int local_this = 0; 30 | int local_delay = 1; 31 | int local_particleType = 2; 32 | 33 | /* 34 | ParticleTypeImpl_X particleType = this.particleWrapper; 35 | */ 36 | mv.visitVarInsn(ALOAD, local_this); 37 | mv.visitFieldInsn(GETFIELD, 38 | implType.internalName(), 39 | PARTICLE_WRAPPER_FIELD_NAME, 40 | implReturnType.desc()); 41 | mv.visitVarInsn(ASTORE, local_particleType); 42 | 43 | /* 44 | particleType.setParticle( 45 | new ShriekParticleOption(delay) 46 | ); 47 | */ 48 | mv.visitVarInsn(ALOAD, local_particleType); 49 | 50 | // ShriekParticleOption start 51 | mv.visitTypeInsn(NEW, refs.shriekParticleOption.internalName()); 52 | mv.visitInsn(DUP); 53 | 54 | mv.visitVarInsn(ILOAD, local_delay); 55 | 56 | mv.visitMethodInsn(INVOKESPECIAL, 57 | refs.shriekParticleOption.internalName(), 58 | "", "(I)V", false); 59 | // ShriekParticleOption end 60 | 61 | mv.visitMethodInsn(INVOKEVIRTUAL, 62 | implReturnType.internalName(), 63 | SET_PARTICLE_METHOD_NAME, 64 | "(" + refs.particleParam_1_17.desc() + ")V", false); 65 | 66 | // return particleType; 67 | mv.visitVarInsn(ALOAD, local_particleType); 68 | mv.visitInsn(ARETURN); 69 | 70 | mv.visitMaxs(0, 0); 71 | mv.visitEnd(); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/particle/type/v1_19/ParticleTypeSculkChargeASM_1_19.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_19; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_17.skeleton.ParticleTypeComplexSkeletonASM_1_17; 5 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 6 | import org.objectweb.asm.ClassWriter; 7 | import org.objectweb.asm.MethodVisitor; 8 | 9 | public class ParticleTypeSculkChargeASM_1_19 extends ParticleTypeComplexSkeletonASM_1_17 { 10 | 11 | public ParticleTypeSculkChargeASM_1_19(ContextASM context, 12 | ClassSkeleton superType, ClassSkeleton returnType) { 13 | super(context, superType, returnType); 14 | } 15 | 16 | @Override 17 | protected void writeMethods(ClassWriter cw) { 18 | writeMethod_roll(cw); 19 | 20 | writeCommonMethods(cw); 21 | } 22 | 23 | private void writeMethod_roll(ClassWriter cw) { 24 | MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, 25 | ROLL_METHOD_NAME, 26 | "(D)" + interfaceReturnType.desc(), null, null); 27 | mv.visitCode(); 28 | 29 | int local_this = 0; 30 | int local_roll = 1; 31 | int local_particleType = 3; 32 | 33 | /* 34 | ParticleTypeImpl_X particleType = this.particleWrapper; 35 | */ 36 | mv.visitVarInsn(ALOAD, local_this); 37 | mv.visitFieldInsn(GETFIELD, 38 | implType.internalName(), 39 | PARTICLE_WRAPPER_FIELD_NAME, 40 | implReturnType.desc()); 41 | mv.visitVarInsn(ASTORE, local_particleType); 42 | 43 | /* 44 | particleType.setParticle( 45 | new SculkChargeParticleOptions((float) roll) 46 | ); 47 | */ 48 | mv.visitVarInsn(ALOAD, local_particleType); 49 | 50 | // SculkChargeParticleOptions start 51 | mv.visitTypeInsn(NEW, refs.sculkChargeParticleOptions.internalName()); 52 | mv.visitInsn(DUP); 53 | 54 | mv.visitVarInsn(DLOAD, local_roll);mv.visitInsn(D2F); 55 | 56 | mv.visitMethodInsn(INVOKESPECIAL, 57 | refs.sculkChargeParticleOptions.internalName(), 58 | "", "(F)V", false); 59 | // SculkChargeParticleOptions end 60 | 61 | mv.visitMethodInsn(INVOKEVIRTUAL, 62 | implReturnType.internalName(), 63 | SET_PARTICLE_METHOD_NAME, 64 | "(" + refs.particleParam_1_17.desc() + ")V", false); 65 | 66 | // return particleType; 67 | mv.visitVarInsn(ALOAD, local_particleType); 68 | mv.visitInsn(ARETURN); 69 | 70 | mv.visitMaxs(0, 0); 71 | mv.visitEnd(); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /ParticleNativeAPI-api/src/main/java/com/github/fierioziy/particlenativeapi/api/particle/type/ParticleTypeSpell.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.api.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.utils.Shared; 4 | import org.bukkit.Color; 5 | 6 | /** 7 | *

Class used to represent particle type that needs a color, transparency settings and power.

8 | * 9 | *

It provides a non-reflective color method overloads 10 | * to construct ParticleType with selected color.

11 | * 12 | *

All color methods does not validate parameters in any way.

13 | * 14 | *

IMPORTANT NOTE: All methods annotated with {@link Shared} annotation 15 | * caches and returns exactly one and the same instance with changed state between method calls. 16 | * For an independent copy of returned instances, check detachCopy methods on them.

17 | * 18 | * @see ParticleType 19 | */ 20 | public interface ParticleTypeSpell { 21 | 22 | /** 23 | *

Selects a color, transparency and power this particle should get.

24 | * 25 | *

Parameters are not validated in any way.

26 | * 27 | * @param color a {@link Color} object representing 28 | * desired particle color. 29 | * @param alpha alpha value that should be between 0 and 255; 30 | * controls transparency of the particle. 31 | * @param power a power which this particle should have. 32 | * @return a valid shared {@link ParticleType} object with selected 33 | * color. 34 | */ 35 | @Shared ParticleType spell(Color color, int alpha, double power); 36 | 37 | /** 38 | *

Selects a color, transparency and power this particle should get.

39 | * 40 | *

Parameters are not validated in any way.

41 | * 42 | *

This method is overridden by dynamically generated 43 | * subclasses.

44 | * 45 | * @param r red color value that should be between 0 and 255. 46 | * @param g green color value that should be between 0 and 255. 47 | * @param b blue color value that should be between 0 and 255. 48 | * @param alpha alpha value that should be between 0 and 255; 49 | * controls transparency of the particle. 50 | * @param power a power which this particle should have. 51 | * @return a valid shared {@link ParticleType} object with selected 52 | * color. 53 | */ 54 | @Shared ParticleType spell(int r, int g, int b, int alpha, double power); 55 | 56 | /** 57 | *

Checks if this particle is supported by this Spigot version.

58 | * 59 | *

This method is overridden by dynamically generated 60 | * subclasses.

61 | * 62 | * @return true if this particle is supported by 63 | * this Spigot version, false otherwise. 64 | */ 65 | boolean isPresent(); 66 | 67 | } 68 | -------------------------------------------------------------------------------- /ParticleNativeAPI-api/src/main/java/com/github/fierioziy/particlenativeapi/api/particle/type/ParticleTypeBlock.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.api.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.utils.Shared; 4 | import org.bukkit.Material; 5 | 6 | /** 7 | *

Class used to represent block particle type that needs a block type.

8 | * 9 | *

It provides a non-reflective of method overloads 10 | * to construct {@link ParticleType} with selected block type.

11 | * 12 | *

All of methods does not validate parameters in any way.

13 | * 14 | *

IMPORTANT NOTE: All methods annotated with {@link Shared} annotation 15 | * caches and returns exactly one and the same instance with changed state between method calls. 16 | * For an independent copy of returned instances, check detachCopy methods on them.

17 | * 18 | * @see ParticleType 19 | */ 20 | public interface ParticleTypeBlock { 21 | 22 | /** 23 | *

Selects a block this particle should represents.

24 | * 25 | *

Parameters are not validated in any way.

26 | * 27 | * @param block a {@link Material} object representing 28 | * desired block type. 29 | * @return a valid shared {@link ParticleType} object with selected 30 | * block type. 31 | */ 32 | @Shared ParticleType of(Material block); 33 | 34 | /** 35 | *

Selects a block this particle should represents.

36 | * 37 | *

Parameters are not validated in any way.

38 | * 39 | * @param block a {@link Material} object representing 40 | * desired block type. 41 | * @param meta a metadata used by certain blocks (it is 42 | * ignored since 1.13). 43 | * @return a valid shared {@link ParticleType} object with selected 44 | * block type. 45 | */ 46 | @Shared ParticleType of(Material block, int meta); 47 | 48 | /** 49 | *

Selects a block this particle should represents.

50 | * 51 | *

Parameters are not validated in any way.

52 | * 53 | *

This method is overridden by dynamically generated 54 | * subclasses.

55 | * 56 | * @param block a {@link Material} object representing 57 | * desired block type. 58 | * @param meta a metadata used by certain blocks (it is 59 | * ignored since 1.13). 60 | * @return a valid shared {@link ParticleType} object with selected 61 | * block type. 62 | */ 63 | @Shared ParticleType of(Material block, byte meta); 64 | 65 | /** 66 | *

Checks if this particle is supported by this Spigot version.

67 | * 68 | *

This method is overridden by dynamically generated 69 | * subclasses.

70 | * 71 | * @return true if this particle is supported by 72 | * this Spigot version, false otherwise. 73 | */ 74 | boolean isPresent(); 75 | 76 | } 77 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/particle/type/v1_13/ParticleTypeDustASM_1_13.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_13; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_13.skeleton.ParticleTypeComplexSkeletonASM_1_13; 5 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 6 | import org.objectweb.asm.ClassWriter; 7 | import org.objectweb.asm.MethodVisitor; 8 | 9 | public class ParticleTypeDustASM_1_13 extends ParticleTypeComplexSkeletonASM_1_13 { 10 | 11 | 12 | public ParticleTypeDustASM_1_13(ContextASM context, 13 | ClassSkeleton superType, ClassSkeleton returnType) { 14 | super(context, superType, returnType); 15 | } 16 | 17 | @Override 18 | protected void writeMethods(ClassWriter cw) { 19 | writeMethod_color(cw); 20 | 21 | writeCommonMethods(cw); 22 | } 23 | 24 | private void writeMethod_color(ClassWriter cw) { 25 | MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, 26 | COLOR_METHOD_NAME, 27 | "(FFFF)" + interfaceReturnType.desc(), null, null); 28 | mv.visitCode(); 29 | 30 | int local_this = 0; 31 | int local_red = 1; 32 | int local_green = 2; 33 | int local_blue = 3; 34 | int local_size = 4; 35 | int local_particleType = 5; 36 | 37 | /* 38 | ParticleTypeImpl_X particleType = this.particleWrapper; 39 | */ 40 | mv.visitVarInsn(ALOAD, local_this); 41 | mv.visitFieldInsn(GETFIELD, 42 | implType.internalName(), 43 | PARTICLE_WRAPPER_FIELD_NAME, 44 | implReturnType.desc()); 45 | mv.visitVarInsn(ASTORE, local_particleType); 46 | 47 | /* 48 | particleType.setParticle( 49 | new ParticleParamRedstone(red, green, blue, size) 50 | ); 51 | */ 52 | mv.visitVarInsn(ALOAD, local_particleType); 53 | 54 | mv.visitTypeInsn(NEW, refs.particleParamRedstone_1_7.internalName()); 55 | mv.visitInsn(DUP); 56 | 57 | mv.visitVarInsn(FLOAD, local_red); 58 | mv.visitVarInsn(FLOAD, local_green); 59 | mv.visitVarInsn(FLOAD, local_blue); 60 | mv.visitVarInsn(FLOAD, local_size); 61 | 62 | mv.visitMethodInsn(INVOKESPECIAL, 63 | refs.particleParamRedstone_1_7.internalName(), 64 | "", 65 | "(FFFF)V", false); 66 | 67 | mv.visitMethodInsn(INVOKEVIRTUAL, 68 | implReturnType.internalName(), 69 | SET_PARTICLE_METHOD_NAME, 70 | "(" + refs.particleParam_1_7.desc() + ")V", false); 71 | 72 | // return particleType; 73 | mv.visitVarInsn(ALOAD, local_particleType); 74 | mv.visitInsn(ARETURN); 75 | 76 | mv.visitMaxs(0, 0); 77 | mv.visitEnd(); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /ParticleNativeAPI-api/src/main/java/com/github/fierioziy/particlenativeapi/api/particle/type/ParticleTypeBlockMotion.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.api.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.utils.Shared; 4 | import org.bukkit.Material; 5 | 6 | /** 7 | *

Class used to represent block particle type that needs a block type.

8 | * 9 | *

It provides a non-reflective of method overloads 10 | * to construct {@link ParticleTypeMotion} with selected block type.

11 | * 12 | *

All of methods does not validate parameters in any way.

13 | * 14 | *

IMPORTANT NOTE: All methods annotated with {@link Shared} annotation 15 | * caches and returns exactly one and the same instance with changed state between method calls. 16 | * For an independent copy of returned instances, check detachCopy methods on them.

17 | * 18 | * @see ParticleTypeMotion 19 | */ 20 | public interface ParticleTypeBlockMotion { 21 | 22 | /** 23 | *

Selects a block this particle should represents.

24 | * 25 | *

Parameters are not validated in any way.

26 | * 27 | * @param block a {@link Material} object representing 28 | * desired block type. 29 | * @return a valid shared {@link ParticleTypeMotion} object with selected 30 | * block type. 31 | */ 32 | @Shared ParticleTypeMotion of(Material block); 33 | 34 | /** 35 | *

Selects a block this particle should represents.

36 | * 37 | *

Parameters are not validated in any way.

38 | * 39 | * @param block a {@link Material} object representing 40 | * desired block type. 41 | * @param meta a metadata used by certain blocks (it is 42 | * ignored since 1.13). 43 | * @return a valid shared {@link ParticleTypeMotion} object with selected 44 | * block type. 45 | */ 46 | @Shared ParticleTypeMotion of(Material block, int meta); 47 | 48 | /** 49 | *

Selects a block this particle should represents.

50 | * 51 | *

Parameters are not validated in any way.

52 | * 53 | *

This method is overridden by dynamically generated 54 | * subclasses.

55 | * 56 | * @param block a {@link Material} object representing 57 | * desired block type. 58 | * @param meta a metadata used by certain blocks (it is 59 | * ignored since 1.13). 60 | * @return a valid shared {@link ParticleTypeMotion} object with selected 61 | * block type. 62 | */ 63 | @Shared ParticleTypeMotion of(Material block, byte meta); 64 | 65 | /** 66 | *

Checks if this particle is supported by this Spigot version.

67 | * 68 | *

This method is overridden by dynamically generated 69 | * subclasses.

70 | * 71 | * @return true if this particle is supported by 72 | * this Spigot version, false otherwise. 73 | */ 74 | boolean isPresent(); 75 | 76 | } 77 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/mocks/nms/v1_19_3/BuiltInRegistries.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_19_3; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.Particle; 4 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_13.Particles_1_13; 5 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17.MinecraftKey; 6 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_17.Particles_1_17; 7 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_18.Particles_1_18; 8 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_19.Particles_1_19; 9 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_20_5.Particles_1_20_5; 10 | import com.github.fierioziy.particlenativeapi.core.mocks.nms.v1_21_10.Particles_1_21_10; 11 | 12 | public class BuiltInRegistries { 13 | 14 | public static final IRegistry_1_19_3> ab = paramT -> { 15 | if (paramT == Particles_1_13.LAVA) return new MinecraftKey("barrier"); 16 | else if (paramT == Particles_1_18.HEART) return new MinecraftKey("heart"); 17 | else if (paramT == Particles_1_13.FALLING_DUST) return new MinecraftKey("falling_dust"); 18 | else if (paramT == Particles_1_13.BLOCK) return new MinecraftKey("block"); 19 | else if (paramT == Particles_1_13.ENTITY_EFFECT) return new MinecraftKey("entity_effect"); 20 | else if (paramT == Particles_1_20_5.ENTITY_EFFECT) return new MinecraftKey("entity_effect"); 21 | else if (paramT == Particles_1_13.DUST) return new MinecraftKey("dust"); 22 | else if (paramT == Particles_1_17.DUST_COLOR_TRANSITION) return new MinecraftKey("dust_color_transition"); 23 | else if (paramT == Particles_1_17.VIBRATION) return new MinecraftKey("vibration"); 24 | else if (paramT == Particles_1_13.ITEM) return new MinecraftKey("item"); 25 | else if (paramT == Particles_1_13.FLAME) return new MinecraftKey("flame"); 26 | else if (paramT == Particles_1_13.NOTE) return new MinecraftKey("note"); 27 | else if (paramT == Particles_1_18.BLOCK_MARKER) return new MinecraftKey("block_marker"); 28 | else if (paramT == Particles_1_19.SCULK_CHARGE) return new MinecraftKey("sculk_charge"); 29 | else if (paramT == Particles_1_19.SHRIEK) return new MinecraftKey("shriek"); 30 | else if (paramT == Particles_1_19.DRAGON_BREATH) return new MinecraftKey("dragon_breath"); 31 | else if (paramT == Particles_1_21_10.DRAGON_BREATH) return new MinecraftKey("dragon_breath"); 32 | else if (paramT == Particles_1_20_5.EFFECT) return new MinecraftKey("effect"); 33 | else if (paramT == Particles_1_21_10.EFFECT) return new MinecraftKey("effect"); 34 | 35 | throw new RuntimeException("Unknown particle in Particles"); 36 | }; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeMotionImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.packet.ParticlePacket; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeMotion; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | import org.bukkit.Location; 7 | import org.bukkit.util.Vector; 8 | 9 | public class ParticleTypeMotionImpl extends ParticleTypeImpl implements ParticleTypeMotion { 10 | 11 | @Override 12 | public ParticleTypeMotion detachCopy() { 13 | try { 14 | // this will also copy any fields created via ASM 15 | // so, it will copy cached NMS particle type related object 16 | return (ParticleTypeMotion) super.clone(); 17 | } catch (CloneNotSupportedException e) { 18 | throw new ParticleException( 19 | "Tried to copy ParticleTypeMotion, but for some reason it is not possible", e 20 | ); 21 | } 22 | } 23 | 24 | @Override 25 | public ParticlePacket packetMotion(boolean far, Location loc, Vector dir) { 26 | return packet(far, 27 | loc.getX(), loc.getY(), loc.getZ(), 28 | dir.getX(), dir.getY(), dir.getZ(), 29 | 1D, 0); 30 | } 31 | 32 | @Override 33 | public ParticlePacket packetMotion(boolean far, Vector loc, Vector dir) { 34 | return packet(far, 35 | loc.getX(), loc.getY(), loc.getZ(), 36 | dir.getX(), dir.getY(), dir.getZ(), 37 | 1D, 0); 38 | } 39 | 40 | @Override 41 | public ParticlePacket packetMotion(boolean far, double x, double y, double z, 42 | Vector dir) { 43 | return packet(far, 44 | x, y, z, 45 | dir.getX(), dir.getY(), dir.getZ(), 46 | 1D, 0); 47 | } 48 | 49 | @Override 50 | public ParticlePacket packetMotion(boolean far, Location loc, 51 | double dirX, double dirY, double dirZ) { 52 | return packet(far, 53 | loc.getX(), loc.getY(), loc.getZ(), 54 | dirX, dirY, dirZ, 55 | 1D, 0); 56 | } 57 | 58 | @Override 59 | public ParticlePacket packetMotion(boolean far, Vector loc, 60 | double dirX, double dirY, double dirZ) { 61 | return packet(far, 62 | loc.getX(), loc.getY(), loc.getZ(), 63 | dirX, dirY, dirZ, 64 | 1D, 0); 65 | } 66 | 67 | @Override 68 | public ParticlePacket packetMotion(boolean far, double x, double y, double z, 69 | double dirX, double dirY, double dirZ) { 70 | return packet(far, 71 | x, y, z, 72 | dirX, dirY, dirZ, 73 | 1D, 0); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /ParticleNativeAPI-plugin-benchmark/src/main/java/com/github/fierioziy/particlenativebenchmark/spawners/ParticleSpawnerReflection.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativebenchmark.spawners; 2 | 3 | import com.github.fierioziy.particlenativebenchmark.command.CommandPNAB; 4 | import net.minecraft.core.particles.ParticleParam; 5 | import net.minecraft.core.particles.Particles; 6 | import net.minecraft.network.protocol.Packet; 7 | import net.minecraft.network.protocol.game.PacketPlayOutWorldParticles; 8 | import net.minecraft.server.level.EntityPlayer; 9 | import net.minecraft.server.network.PlayerConnection; 10 | import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; 11 | import org.bukkit.entity.Player; 12 | 13 | import java.lang.reflect.Constructor; 14 | import java.lang.reflect.Field; 15 | import java.lang.reflect.Method; 16 | 17 | public class ParticleSpawnerReflection implements ParticleSpawner { 18 | 19 | private Object flameParticleTypeObj; 20 | 21 | private Method getHandleMethod; 22 | private Field playerConnectionField; 23 | private Method sendPacketMethod; 24 | 25 | private Constructor particlePacketCtr; 26 | 27 | public ParticleSpawnerReflection(CommandPNAB.Context context) { 28 | try { 29 | // assume those class elements have to be dynamically resolved 30 | // by version in package path 31 | flameParticleTypeObj = Particles.C; // C is flame particle type 32 | 33 | Class craftPlayerClass = CraftPlayer.class; 34 | 35 | getHandleMethod = craftPlayerClass.getMethod("getHandle"); 36 | getHandleMethod.setAccessible(true); 37 | 38 | playerConnectionField = EntityPlayer.class.getField("b"); // b is player connection 39 | playerConnectionField.setAccessible(true); 40 | 41 | sendPacketMethod = PlayerConnection.class.getMethod("sendPacket", Packet.class); 42 | sendPacketMethod.setAccessible(true); 43 | 44 | particlePacketCtr = PacketPlayOutWorldParticles.class 45 | .getConstructor( 46 | ParticleParam.class, 47 | boolean.class, 48 | double.class, double.class, double.class, 49 | float.class, float.class, float.class, 50 | float.class, int.class 51 | ); 52 | particlePacketCtr.setAccessible(true); 53 | } catch (Exception e) { 54 | e.printStackTrace(); 55 | } 56 | } 57 | 58 | 59 | @Override 60 | public void spawnParticle(Player player, double x, double y, double z) { 61 | try { 62 | sendPacketMethod.invoke( 63 | playerConnectionField.get(getHandleMethod.invoke(player)), 64 | particlePacketCtr.newInstance(flameParticleTypeObj, true, 65 | x, y, z, 66 | 0F, 0F, 0F, 0F, 1 67 | ) 68 | ); 69 | } catch (Exception e) { 70 | player.sendMessage("Error occurred while sending"); 71 | e.printStackTrace(); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/test/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeColorTest.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleType; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeColor; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | import org.bukkit.Color; 7 | import org.junit.jupiter.api.BeforeEach; 8 | import org.junit.jupiter.api.Test; 9 | import org.junit.jupiter.api.extension.ExtendWith; 10 | import org.mockito.AdditionalMatchers; 11 | import org.mockito.Spy; 12 | import org.mockito.junit.jupiter.MockitoExtension; 13 | 14 | import static org.junit.jupiter.api.Assertions.*; 15 | import static org.mockito.Mockito.*; 16 | 17 | @ExtendWith(MockitoExtension.class) 18 | public class ParticleTypeColorTest { 19 | 20 | @Spy 21 | private ParticleTypeColor invalidParticleType = new ParticleTypeColorImpl(); 22 | 23 | @Spy 24 | private ParticleTypeColor particleType = new ParticleTypeColorImpl(); 25 | 26 | @BeforeEach 27 | public void prepareParticleType() { 28 | // make it look like valid 29 | doReturn(true).when(particleType).isPresent(); 30 | 31 | // make it return dummy particle type on 'color' method 32 | // to avoid ParticleException 33 | lenient() 34 | .doReturn(mock(ParticleType.class)) 35 | .when(particleType) 36 | .color(anyInt(), anyInt(), anyInt(), anyInt()); 37 | 38 | assertFalse(invalidParticleType.isPresent(), 39 | "Invalid ParticleType is for some reason valid"); 40 | 41 | assertTrue(particleType.isPresent(), 42 | "ParticleType is for some reason invalid"); 43 | } 44 | 45 | private void verifyArgumentPass(int r, int g, int b, int alpha) { 46 | verify(particleType).color(r, g, b, alpha); 47 | } 48 | 49 | /* 50 | Verify invalid particle type 51 | */ 52 | 53 | @Test 54 | public void testExceptionOnInvalidType() { 55 | assertThrows(ParticleException.class, () -> invalidParticleType.color(255, 255, 255)); 56 | } 57 | 58 | /* 59 | Verify method argument expansion 60 | */ 61 | 62 | @Test 63 | public void test_color_Color() { 64 | int red = 255; 65 | int green = 120; 66 | int blue = 60; 67 | Color color = Color.fromRGB(red, green, blue); 68 | 69 | particleType.color(color); 70 | 71 | verifyArgumentPass(red, green, blue, 255); 72 | } 73 | 74 | @Test 75 | public void test_color_Color_alpha() { 76 | int red = 255; 77 | int green = 120; 78 | int blue = 60; 79 | int alpha = 125; 80 | Color color = Color.fromRGB(red, green, blue); 81 | 82 | particleType.color(color, alpha); 83 | 84 | verifyArgumentPass(red, green, blue, alpha); 85 | } 86 | 87 | @Test 88 | public void test_color_rgb() { 89 | int red = 255; 90 | int green = 120; 91 | int blue = 60; 92 | particleType.color(red, green, blue); 93 | 94 | verifyArgumentPass(red, green, blue, 255); 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeColorableImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.packet.ParticlePacket; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeColorable; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | import org.bukkit.Color; 7 | import org.bukkit.Location; 8 | import org.bukkit.util.Vector; 9 | 10 | public class ParticleTypeColorableImpl extends ParticleTypeImpl implements ParticleTypeColorable { 11 | 12 | @Override 13 | public ParticleTypeColorable detachCopy() { 14 | try { 15 | // this will also copy any fields created via ASM 16 | // so, it will copy cached NMS particle type related object 17 | return (ParticleTypeColorable) super.clone(); 18 | } catch (CloneNotSupportedException e) { 19 | throw new ParticleException( 20 | "Tried to copy ParticleTypeColorable, but for some reason it is not possible", e 21 | ); 22 | } 23 | } 24 | 25 | @Override 26 | public ParticlePacket packetColored(boolean far, Location loc, 27 | Color color) { 28 | return packet(far, 29 | loc.getX(), loc.getY(), loc.getZ(), 30 | color.getRed() / 255D, color.getGreen() / 255D, color.getBlue() / 255D, 31 | 1D, 0); 32 | } 33 | 34 | @Override 35 | public ParticlePacket packetColored(boolean far, Vector loc, 36 | Color color) { 37 | return packet(far, 38 | loc.getX(), loc.getY(), loc.getZ(), 39 | color.getRed() / 255D, color.getGreen() / 255D, color.getBlue() / 255D, 40 | 1D, 0); 41 | } 42 | 43 | @Override 44 | public ParticlePacket packetColored(boolean far, double x, double y, double z, 45 | Color color) { 46 | return packet(far, 47 | x, y, z, 48 | color.getRed() / 255D, color.getGreen() / 255D, color.getBlue() / 255D, 49 | 1D, 0); 50 | } 51 | 52 | @Override 53 | public ParticlePacket packetColored(boolean far, Location loc, 54 | int r, int g, int b) { 55 | return packet(far, 56 | loc.getX(), loc.getY(), loc.getZ(), 57 | r / 255D, g / 255D, b / 255D, 58 | 1D, 0); 59 | } 60 | 61 | @Override 62 | public ParticlePacket packetColored(boolean far, Vector loc, 63 | int r, int g, int b) { 64 | return packet(far, 65 | loc.getX(), loc.getY(), loc.getZ(), 66 | r / 255D, g / 255D, b / 255D, 67 | 1D, 0); 68 | } 69 | 70 | @Override 71 | public ParticlePacket packetColored(boolean far, double x, double y, double z, 72 | int r, int g, int b) { 73 | return packet(far, 74 | x, y, z, 75 | r / 255D, g / 255D, b / 255D, 76 | 1D, 0); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/particle/type/ParticleTypeVibrationSingleImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.particle.type; 2 | 3 | import com.github.fierioziy.particlenativeapi.api.packet.ParticlePacket; 4 | import com.github.fierioziy.particlenativeapi.api.particle.type.ParticleTypeVibrationSingle; 5 | import com.github.fierioziy.particlenativeapi.api.utils.ParticleException; 6 | import com.github.fierioziy.particlenativeapi.api.utils.Shared; 7 | import org.bukkit.Location; 8 | import org.bukkit.entity.Entity; 9 | import org.bukkit.util.Vector; 10 | 11 | public class ParticleTypeVibrationSingleImpl implements ParticleTypeVibrationSingle { 12 | 13 | @Override 14 | public ParticlePacket packet(boolean far, Location loc, Location target, int ticks) { 15 | return packet(far, 16 | loc.getX(), loc.getY(), loc.getZ(), 17 | target.getX(), target.getY(), target.getZ(), 18 | ticks); 19 | } 20 | 21 | @Override 22 | public ParticlePacket packet(boolean far, Location loc, Vector target, int ticks) { 23 | return packet(far, 24 | loc.getX(), loc.getY(), loc.getZ(), 25 | target.getX(), target.getY(), target.getZ(), 26 | ticks); 27 | } 28 | 29 | @Override 30 | public @Shared ParticlePacket packet(boolean far, Location loc, Entity targetEntity, int ticks) { 31 | return packet(far, 32 | loc.getX(), loc.getY(), loc.getZ(), 33 | targetEntity, ticks); 34 | } 35 | 36 | @Override 37 | public ParticlePacket packet(boolean far, Vector loc, Location target, int ticks) { 38 | return packet(far, 39 | loc.getX(), loc.getY(), loc.getZ(), 40 | target.getX(), target.getY(), target.getZ(), 41 | ticks); 42 | } 43 | 44 | @Override 45 | public ParticlePacket packet(boolean far, Vector loc, Vector target, int ticks) { 46 | return packet(far, 47 | loc.getX(), loc.getY(), loc.getZ(), 48 | target.getX(), target.getY(), target.getZ(), 49 | ticks); 50 | } 51 | 52 | @Override 53 | public @Shared ParticlePacket packet(boolean far, Vector loc, Entity targetEntity, int ticks) { 54 | return packet(far, 55 | loc.getX(), loc.getY(), loc.getZ(), 56 | targetEntity, ticks); 57 | } 58 | 59 | @Override 60 | public ParticlePacket packet(boolean far, double x, double y, double z, 61 | double targetX, double targetY, double targetZ, 62 | int ticks) { 63 | throw new ParticleException( 64 | "Requested particle type is not supported by this server version!" 65 | ); 66 | } 67 | 68 | @Override 69 | public @Shared ParticlePacket packet(boolean far, double x, double y, double z, 70 | Entity targetEntity, int ticks) { 71 | throw new ParticleException( 72 | "Requested particle type is not supported by this server version!" 73 | ); 74 | } 75 | 76 | @Override 77 | public boolean isPresent() { 78 | return false; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/particle/type/v1_17/ParticleTypeDustASM_1_17.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_17; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_17.skeleton.ParticleTypeComplexSkeletonASM_1_17; 5 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 6 | import org.objectweb.asm.ClassWriter; 7 | import org.objectweb.asm.MethodVisitor; 8 | 9 | public class ParticleTypeDustASM_1_17 extends ParticleTypeComplexSkeletonASM_1_17 { 10 | 11 | public ParticleTypeDustASM_1_17(ContextASM context, 12 | ClassSkeleton superType, ClassSkeleton returnType) { 13 | super(context, superType, returnType); 14 | } 15 | 16 | @Override 17 | protected void writeMethods(ClassWriter cw) { 18 | writeMethod_color(cw); 19 | 20 | writeCommonMethods(cw); 21 | } 22 | 23 | private void writeMethod_color(ClassWriter cw) { 24 | MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, 25 | COLOR_METHOD_NAME, 26 | "(FFFF)" + interfaceReturnType.desc(), null, null); 27 | mv.visitCode(); 28 | 29 | int local_this = 0; 30 | int local_red = 1; 31 | int local_green = 2; 32 | int local_blue = 3; 33 | int local_size = 4; 34 | int local_particleType = 5; 35 | 36 | /* 37 | ParticleTypeImpl_X particleType = this.particleWrapper; 38 | */ 39 | mv.visitVarInsn(ALOAD, local_this); 40 | mv.visitFieldInsn(GETFIELD, 41 | implType.internalName(), 42 | PARTICLE_WRAPPER_FIELD_NAME, 43 | implReturnType.desc()); 44 | mv.visitVarInsn(ASTORE, local_particleType); 45 | 46 | /* 47 | particleType.setParticle( 48 | new ParticleParamRedstone(new Vector3fa(red, green, blue), size) 49 | ); 50 | */ 51 | mv.visitVarInsn(ALOAD, local_particleType); 52 | 53 | mv.visitTypeInsn(NEW, refs.particleParamRedstone_1_17.internalName()); 54 | mv.visitInsn(DUP); 55 | 56 | mv.visitTypeInsn(NEW, refs.vector3fa.internalName()); 57 | mv.visitInsn(DUP); 58 | 59 | mv.visitVarInsn(FLOAD, local_red); 60 | mv.visitVarInsn(FLOAD, local_green); 61 | mv.visitVarInsn(FLOAD, local_blue); 62 | 63 | mv.visitMethodInsn(INVOKESPECIAL, 64 | refs.vector3fa.internalName(), 65 | "", 66 | "(FFF)V", false); 67 | 68 | mv.visitVarInsn(FLOAD, local_size); 69 | 70 | mv.visitMethodInsn(INVOKESPECIAL, 71 | refs.particleParamRedstone_1_17.internalName(), 72 | "", 73 | "(" + refs.vector3fa.desc() + "F)V", false); 74 | 75 | mv.visitMethodInsn(INVOKEVIRTUAL, 76 | implReturnType.internalName(), 77 | SET_PARTICLE_METHOD_NAME, 78 | "(" + refs.particleParam_1_17.desc() + ")V", false); 79 | 80 | // return particleType; 81 | mv.visitVarInsn(ALOAD, local_particleType); 82 | mv.visitInsn(ARETURN); 83 | 84 | mv.visitMaxs(0, 0); 85 | mv.visitEnd(); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/particle/type/v1_19_3/ParticleTypeDustASM_1_19_3.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_19_3; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_17.skeleton.ParticleTypeComplexSkeletonASM_1_17; 5 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 6 | import org.objectweb.asm.ClassWriter; 7 | import org.objectweb.asm.MethodVisitor; 8 | 9 | public class ParticleTypeDustASM_1_19_3 extends ParticleTypeComplexSkeletonASM_1_17 { 10 | 11 | public ParticleTypeDustASM_1_19_3(ContextASM context, 12 | ClassSkeleton superType, ClassSkeleton returnType) { 13 | super(context, superType, returnType); 14 | } 15 | 16 | @Override 17 | protected void writeMethods(ClassWriter cw) { 18 | writeMethod_color(cw); 19 | 20 | writeCommonMethods(cw); 21 | } 22 | 23 | private void writeMethod_color(ClassWriter cw) { 24 | MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, 25 | COLOR_METHOD_NAME, 26 | "(FFFF)" + interfaceReturnType.desc(), null, null); 27 | mv.visitCode(); 28 | 29 | int local_this = 0; 30 | int local_red = 1; 31 | int local_green = 2; 32 | int local_blue = 3; 33 | int local_size = 4; 34 | int local_particleType = 5; 35 | 36 | /* 37 | ParticleTypeImpl_X particleType = this.particleWrapper; 38 | */ 39 | mv.visitVarInsn(ALOAD, local_this); 40 | mv.visitFieldInsn(GETFIELD, 41 | implType.internalName(), 42 | PARTICLE_WRAPPER_FIELD_NAME, 43 | implReturnType.desc()); 44 | mv.visitVarInsn(ASTORE, local_particleType); 45 | 46 | /* 47 | particleType.setParticle( 48 | new ParticleParamRedstone(new Vector3f(red, green, blue), size) 49 | ); 50 | */ 51 | mv.visitVarInsn(ALOAD, local_particleType); 52 | 53 | mv.visitTypeInsn(NEW, refs.particleParamRedstone_1_17.internalName()); 54 | mv.visitInsn(DUP); 55 | 56 | mv.visitTypeInsn(NEW, refs.vector3f.internalName()); 57 | mv.visitInsn(DUP); 58 | 59 | mv.visitVarInsn(FLOAD, local_red); 60 | mv.visitVarInsn(FLOAD, local_green); 61 | mv.visitVarInsn(FLOAD, local_blue); 62 | 63 | mv.visitMethodInsn(INVOKESPECIAL, 64 | refs.vector3f.internalName(), 65 | "", 66 | "(FFF)V", false); 67 | 68 | mv.visitVarInsn(FLOAD, local_size); 69 | 70 | mv.visitMethodInsn(INVOKESPECIAL, 71 | refs.particleParamRedstone_1_17.internalName(), 72 | "", 73 | "(" + refs.vector3f.desc() + "F)V", false); 74 | 75 | mv.visitMethodInsn(INVOKEVIRTUAL, 76 | implReturnType.internalName(), 77 | SET_PARTICLE_METHOD_NAME, 78 | "(" + refs.particleParam_1_17.desc() + ")V", false); 79 | 80 | // return particleType; 81 | mv.visitVarInsn(ALOAD, local_particleType); 82 | mv.visitInsn(ARETURN); 83 | 84 | mv.visitMaxs(0, 0); 85 | mv.visitEnd(); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /ParticleNativeAPI-core/src/main/java/com/github/fierioziy/particlenativeapi/core/asm/particle/type/v1_8/ParticleTypeItemASM_1_8.java: -------------------------------------------------------------------------------- 1 | package com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_8; 2 | 3 | import com.github.fierioziy.particlenativeapi.core.asm.ContextASM; 4 | import com.github.fierioziy.particlenativeapi.core.asm.particle.type.v1_8.skeleton.ParticleTypeComplexSkeletonASM_1_8; 5 | import com.github.fierioziy.particlenativeapi.core.asm.skeleton.ClassSkeleton; 6 | import org.objectweb.asm.ClassWriter; 7 | import org.objectweb.asm.MethodVisitor; 8 | 9 | public class ParticleTypeItemASM_1_8 extends ParticleTypeComplexSkeletonASM_1_8 { 10 | 11 | public ParticleTypeItemASM_1_8(ContextASM context, 12 | ClassSkeleton superType, ClassSkeleton returnType) { 13 | super(context, superType, returnType); 14 | } 15 | 16 | @Override 17 | protected void writeMethods(ClassWriter cw) { 18 | writeMethod_of(cw); 19 | 20 | writeCommonMethods(cw); 21 | } 22 | 23 | private void writeMethod_of(ClassWriter cw) { 24 | MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, 25 | OF_METHOD_NAME, 26 | "(" + refs.material.desc() + ")" + interfaceReturnType.desc(), null, null); 27 | mv.visitCode(); 28 | 29 | int local_this = 0; 30 | int local_material = 1; 31 | int local_particleType = 2; 32 | 33 | /* 34 | ParticleTypeImpl_X particleType = this.particleWrapper; 35 | */ 36 | mv.visitVarInsn(ALOAD, local_this); 37 | mv.visitFieldInsn(GETFIELD, 38 | implType.internalName(), 39 | PARTICLE_WRAPPER_FIELD_NAME, 40 | implReturnType.desc()); 41 | mv.visitVarInsn(ASTORE, local_particleType); 42 | 43 | /* 44 | particleType.setParticle( 45 | this.particle, 46 | new int[] { 47 | material.getId() 48 | } 49 | ); 50 | */ 51 | mv.visitVarInsn(ALOAD, local_particleType); 52 | 53 | // get particle from field 54 | mv.visitVarInsn(ALOAD, local_this); 55 | mv.visitFieldInsn(GETFIELD, 56 | implType.internalName(), 57 | PARTICLE_FIELD_NAME, 58 | refs.enumParticle.desc()); 59 | 60 | // new int[2] 61 | mv.visitInsn(ICONST_2); 62 | mv.visitIntInsn(NEWARRAY, T_INT); 63 | 64 | mv.visitInsn(DUP); 65 | mv.visitInsn(ICONST_0); 66 | 67 | // operating on above array 68 | // dataArr[0] = material.getId(); 69 | mv.visitVarInsn(ALOAD, local_material); 70 | mv.visitMethodInsn(INVOKEVIRTUAL, refs.material.internalName(), "getId", "()I", false); 71 | mv.visitInsn(IASTORE); 72 | 73 | mv.visitInsn(DUP); 74 | mv.visitInsn(ICONST_1); 75 | 76 | // dataArr[1] = 0; 77 | mv.visitInsn(ICONST_0); 78 | mv.visitInsn(IASTORE); 79 | 80 | mv.visitMethodInsn(INVOKEVIRTUAL, 81 | implReturnType.internalName(), 82 | SET_PARTICLE_METHOD_NAME, "(" + refs.enumParticle.desc() + "[I)V", false); 83 | 84 | // return particleType; 85 | mv.visitVarInsn(ALOAD, local_particleType); 86 | mv.visitInsn(ARETURN); 87 | 88 | mv.visitMaxs(0, 0); 89 | mv.visitEnd(); 90 | } 91 | 92 | } 93 | --------------------------------------------------------------------------------