From 17fd1d8c0d8252490f0f7abf61f42c1fbf09c6e8 Mon Sep 17 00:00:00 2001 From: Techcable Date: Sat, 13 Oct 2018 18:36:23 -0700 Subject: [PATCH 1/8] Update to 1.13: First attempt (it compiles) This is a massive update, chaning a ton of internals. It broke a ton of obfuscated names, the entity registry system, and ruined my nice API for spawn eggs. It's been a while since , so I'm already jumping Now that , I have to have a class . I call but it's horribly broken because Material.valueOf doesn't work. I fear this is some sort of bizarre classpath issue, which I do **not** want to deal with right now. I've put over 4.5 hours into this single commit and I'm ready to call it a day. --- .../net/techcable/sonarpet/item/ItemData.java | 18 +- .../sonarpet/item/SpawnEggItemData.java | 7 +- .../java/net/techcable/sonarpet/nms/INMS.java | 19 +- .../sonarpet/utils/ModernSpawnEggs.java | 70 +++++++ .../techcable/sonarpet/utils/NmsVersion.java | 3 +- .../sonarpet/particles/ParticleBuilder.kt | 2 +- .../src/main/resources/versions/v1_12_R1.json | 4 +- .../src/main/resources/versions/v1_13_R2.json | 23 +++ .../nms/versions/v1_10_R1/NMSImpl.java | 7 - .../v1_10_R1/data/NMSSpawnEggItemData.java | 2 +- .../nms/versions/v1_11_R1/NMSImpl.java | 6 - .../v1_11_R1/data/NMSSpawnEggItemData.java | 2 +- .../nms/versions/v1_12_R1/NMSImpl.java | 7 - .../v1_12_R1/data/NMSSpawnEggItemData.java | 2 +- nms/v1_13_R2/build.gradle.kts | 5 + .../versions/v1_13_R2/BlockSoundDataImpl.java | 39 ++++ .../versions/v1_13_R2/DamageSourceImpl.java | 11 ++ .../versions/v1_13_R2/DataWatcherImpl.java | 37 ++++ .../versions/v1_13_R2/NMSEntityHorseImpl.java | 75 ++++++++ .../nms/versions/v1_13_R2/NMSEntityImpl.java | 67 +++++++ .../v1_13_R2/NMSEntityInsentientImpl.java | 123 ++++++++++++ .../versions/v1_13_R2/NMSEntityRegistry.java | 120 ++++++++++++ .../nms/versions/v1_13_R2/NMSImpl.java | 119 ++++++++++++ .../v1_13_R2/NMSLivingEntityImpl.java | 180 ++++++++++++++++++ .../nms/versions/v1_13_R2/NMSPlayerImpl.java | 27 +++ .../nms/versions/v1_13_R2/NavigationImpl.java | 55 ++++++ .../v1_13_R2/data/NMSSpawnEggItemData.java | 46 +++++ .../nms/versions/v1_13_R2/NMSSoundImpl.kt | 21 ++ .../nms/versions/v1_9_R1/NMSImpl.java | 7 - .../v1_9_R1/data/NMSSpawnEggItemData.java | 2 +- .../nms/versions/v1_9_R2/NMSImpl.java | 7 - .../v1_9_R2/data/NMSSpawnEggItemData.java | 2 +- settings.gradle | 2 +- 33 files changed, 1064 insertions(+), 53 deletions(-) create mode 100644 api/src/main/java/net/techcable/sonarpet/utils/ModernSpawnEggs.java create mode 100644 core/src/main/resources/versions/v1_13_R2.json create mode 100644 nms/v1_13_R2/build.gradle.kts create mode 100644 nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/BlockSoundDataImpl.java create mode 100644 nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/DamageSourceImpl.java create mode 100644 nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/DataWatcherImpl.java create mode 100644 nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSEntityHorseImpl.java create mode 100644 nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSEntityImpl.java create mode 100644 nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSEntityInsentientImpl.java create mode 100644 nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSEntityRegistry.java create mode 100644 nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSImpl.java create mode 100644 nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSLivingEntityImpl.java create mode 100644 nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSPlayerImpl.java create mode 100644 nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NavigationImpl.java create mode 100644 nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/data/NMSSpawnEggItemData.java create mode 100644 nms/v1_13_R2/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSSoundImpl.kt diff --git a/api/src/main/java/net/techcable/sonarpet/item/ItemData.java b/api/src/main/java/net/techcable/sonarpet/item/ItemData.java index 98898ada..7c36573c 100644 --- a/api/src/main/java/net/techcable/sonarpet/item/ItemData.java +++ b/api/src/main/java/net/techcable/sonarpet/item/ItemData.java @@ -9,11 +9,13 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import net.techcable.sonarpet.utils.ModernSpawnEggs; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.material.MaterialData; +import org.bukkit.material.MonsterEggs; @Getter public class ItemData { @@ -58,13 +60,27 @@ public static ItemData create(Material type, int rawData, ItemMeta meta) { Preconditions.checkNotNull(type, "Null type"); Preconditions.checkArgument((byte) rawData == rawData, "Raw data doesn't fit in byte: %s", rawData); Preconditions.checkNotNull(meta, "Null item meta"); + if (ModernSpawnEggs.isSupported()) { + if (ModernSpawnEggs.isSpawnEgg(type)) { + return INMS.getInstance().createSpawnEggData(type, (byte) rawData, meta); + } + } else { + // We're on an older version, where there is only one type of monster egg + if (type == Material.MONSTER_EGG) { + return INMS.getInstance().createSpawnEggData(type, (byte) rawData, meta); + } + } + /* + * NOTE: I'm keeping Material.MONSTER_EGG out of the switch + * since it's deprecated on 1.13. + * It'll now be conditional on whether we have 'modern' monster egg support + */ switch (type) { case INK_SACK: return new DyeItemData((byte) rawData, meta); case SKULL_ITEM: return new SkullItemData((byte) rawData, meta); case MONSTER_EGG: - return INMS.getInstance().createSpawnEggData((byte) rawData, meta); case STAINED_CLAY: return new StainedClayItemData((byte) rawData, meta); case WOOL: diff --git a/api/src/main/java/net/techcable/sonarpet/item/SpawnEggItemData.java b/api/src/main/java/net/techcable/sonarpet/item/SpawnEggItemData.java index 76ea0744..bbf6fe7c 100644 --- a/api/src/main/java/net/techcable/sonarpet/item/SpawnEggItemData.java +++ b/api/src/main/java/net/techcable/sonarpet/item/SpawnEggItemData.java @@ -1,8 +1,7 @@ package net.techcable.sonarpet.item; -import net.techcable.sonarpet.nms.INMS; import com.google.common.base.Preconditions; - +import net.techcable.sonarpet.nms.INMS; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.EntityType; @@ -12,8 +11,8 @@ public abstract class SpawnEggItemData extends ItemData { public static final EntityType DEFAULT_TYPE = EntityType.PIG; - protected SpawnEggItemData(byte rawData, ItemMeta meta) { - super(Material.MONSTER_EGG, rawData, meta); + protected SpawnEggItemData(Material m, byte rawData, ItemMeta meta) { + super(m, rawData, meta); } public SpawnEggItemData withSpawnedType(EntityType entityType) { diff --git a/api/src/main/java/net/techcable/sonarpet/nms/INMS.java b/api/src/main/java/net/techcable/sonarpet/nms/INMS.java index 352f1f75..e958c2e8 100644 --- a/api/src/main/java/net/techcable/sonarpet/nms/INMS.java +++ b/api/src/main/java/net/techcable/sonarpet/nms/INMS.java @@ -27,6 +27,8 @@ import net.techcable.pineapple.reflection.PineappleField; import net.techcable.pineapple.reflection.Reflection; import net.techcable.sonarpet.item.SpawnEggItemData; +import net.techcable.sonarpet.utils.ModernSpawnEggs; +import net.techcable.sonarpet.utils.NmsVersion; import net.techcable.sonarpet.utils.Versioning; import org.bukkit.Location; @@ -43,17 +45,24 @@ @SuppressWarnings("deprecation") public interface INMS { - default SpawnEggItemData createSpawnEggData(byte rawData, ItemMeta meta) { - EntityType entityType = new SpawnEgg(rawData).getSpawnedType(); - if (entityType == null) entityType = SpawnEggItemData.DEFAULT_TYPE; + default SpawnEggItemData createSpawnEggData(Material material, byte rawData, ItemMeta meta) { + EntityType entityType; + if (ModernSpawnEggs.isSupported()) { + entityType = ModernSpawnEggs.getSpawnEggType(material); + } else { + entityType = new SpawnEgg(rawData).getSpawnedType(); + if (entityType == null) entityType = SpawnEggItemData.DEFAULT_TYPE; + } return createSpawnEggData(entityType, meta); // Convert raw data to entity type } default SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta) { - if (Versioning.NMS_VERSION.getMajorVersion() >= 9) throw new UnsupportedOperationException("Can't use bukkit API on versions newer than 1.9"); + if (Versioning.NMS_VERSION.getMajorVersion() >= 9) { + throw new UnsupportedOperationException("Can't use bukkit API on versions newer than 1.9"); + } Preconditions.checkNotNull(meta, "Null meta"); Preconditions.checkNotNull(entityType, "Null entity type"); - return new SpawnEggItemData(new SpawnEgg(entityType).getData(), meta) { + return new SpawnEggItemData(Material.MONSTER_EGG, new SpawnEgg(entityType).getData(), meta) { @Override @SuppressWarnings("depreciation") // Bukkit is okay on versions less than 1.9, and we've already checked above public EntityType getSpawnedType() { diff --git a/api/src/main/java/net/techcable/sonarpet/utils/ModernSpawnEggs.java b/api/src/main/java/net/techcable/sonarpet/utils/ModernSpawnEggs.java new file mode 100644 index 00000000..89c8ca8c --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/utils/ModernSpawnEggs.java @@ -0,0 +1,70 @@ +package net.techcable.sonarpet.utils; + +import org.bukkit.Material; +import org.bukkit.entity.EntityType; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class ModernSpawnEggs { + private ModernSpawnEggs() {} + + @Nonnull + private static void ensureSupported() { + if (!ModernSpawnEggs.isSupported()) { + throw new IllegalStateException( + "Can't use modern spawn eggs on " + NmsVersion.current() + ); + } + } + public static boolean isSpawnEgg(Material m) { + return tryGetSpawnEggType(m) != null; + } + public static boolean isSupported() { + return NmsVersion.current().compareTo(NmsVersion.v1_13_R2) >= 0; + } + public static boolean hasSpawnEgg(EntityType e) { + return tryGetEggMaterial(e) != null; + } + @Nonnull + public static Material getEggMaterial(EntityType t) { + Material m = tryGetEggMaterial(t); + if (m == null) { + throw new IllegalArgumentException("Entity doesn't have spawn egg: " + t); + } + return m; + } + @Nonnull + public static EntityType getSpawnEggType(Material m) { + EntityType entityType = tryGetSpawnEggType(m); + if (entityType == null) { + throw new IllegalArgumentException("Material isn't a spawn egg: " + m); + } + return entityType; + } + private static final String SUFFIX = "_SPAWN_EGG"; + @Nullable + private static Material tryGetEggMaterial(EntityType entityType) { + ModernSpawnEggs.ensureSupported(); + try { + return Material.valueOf(entityType.name() + SUFFIX); + } catch (IllegalArgumentException ignored) { + return null; + } + } + + @Nullable + private static EntityType tryGetSpawnEggType(Material m) { + ModernSpawnEggs.ensureSupported(); + if (m.name().endsWith(SUFFIX)) { + String entityName = m.name().substring( + 0, + m.name().length() - SUFFIX.length() + ); + try { + return EntityType.valueOf(entityName); + } catch (IllegalArgumentException ignored) {} + } + return null; + } +} diff --git a/api/src/main/java/net/techcable/sonarpet/utils/NmsVersion.java b/api/src/main/java/net/techcable/sonarpet/utils/NmsVersion.java index 6dd77c5e..734e6f95 100644 --- a/api/src/main/java/net/techcable/sonarpet/utils/NmsVersion.java +++ b/api/src/main/java/net/techcable/sonarpet/utils/NmsVersion.java @@ -29,7 +29,8 @@ public enum NmsVersion { v1_9_R2, v1_10_R1, v1_11_R1, - v1_12_R1; + v1_12_R1, + v1_13_R2; public static final NmsVersion LATEST, EARLIEST; private ImmutableMap metadata; diff --git a/api/src/main/kotlin/net/techcable/sonarpet/particles/ParticleBuilder.kt b/api/src/main/kotlin/net/techcable/sonarpet/particles/ParticleBuilder.kt index 87d0e0db..aaae6639 100644 --- a/api/src/main/kotlin/net/techcable/sonarpet/particles/ParticleBuilder.kt +++ b/api/src/main/kotlin/net/techcable/sonarpet/particles/ParticleBuilder.kt @@ -70,7 +70,7 @@ abstract class ParticleBuilder protected constructor( @JvmStatic fun create(type: Particle, speed: Float, amount: Int): ParticleBuilder { return when (Versioning.NMS_VERSION!!) { - v1_12_R1, v1_11_R1, v1_10_R1, v1_9_R1, v1_9_R2 -> { + v1_12_R1, v1_11_R1, v1_10_R1, v1_9_R1, v1_9_R2, v1_13_R2 -> { BukkitParticleBuilder(type, speed, amount) } v1_8_R3 -> v18ParticleBuilder(type, speed, amount) diff --git a/core/src/main/resources/versions/v1_12_R1.json b/core/src/main/resources/versions/v1_12_R1.json index fe185449..ea380793 100644 --- a/core/src/main/resources/versions/v1_12_R1.json +++ b/core/src/main/resources/versions/v1_12_R1.json @@ -15,6 +15,8 @@ "obfuscated_fields": { "ENTITY_SIDEWAYS_MOTION_FIELD": "be", // EntityLivingBase.moveStrafing "ENTITY_FORWARD_MOTION_FIELD": "bf", // EntityLivingBase.moveForward - "ENTITY_UPWARDS_MOTION_FIELD": "bg" // New third parameter to move() as of 1.12 + // NOTE: New third parameter to move() as of 1.12 + // TODO: Obfuscated names seems to be swapped with moveForward + "ENTITY_UPWARDS_MOTION_FIELD": "bg" // EntityLivingBase.moveVertical } } \ No newline at end of file diff --git a/core/src/main/resources/versions/v1_13_R2.json b/core/src/main/resources/versions/v1_13_R2.json new file mode 100644 index 00000000..ab711cdb --- /dev/null +++ b/core/src/main/resources/versions/v1_13_R2.json @@ -0,0 +1,23 @@ +{ + "metadata": { + "ENDERMAN_SCREAMING_METADATA_ID": 13, + "WITHER_SHIELDED_METADATA_ID": 15 + }, + "obfuscated_methods": { + "ENTITY_TICK_METHOD": "tick", // MCP: Entity.tick + // NOTE: As of 1.12, signature is (FFF) instead of (FF) + "ENTITY_MOVE_METHOD": "a", // MCP: EntityLivingBase.travel + "ON_STEP_METHOD": "a", // MCP: EntityLivingBase.travel + "ON_INTERACT_METHOD": "a", // MCP: EntityLiving.canBeLeashedTo + "ENTITY_PROCEDURAL_AI_METHOD": "J", // EntityLiving.updateAITasks + // NOTE: MCP renamed it in 1.13, it seems to have undergone some sort of change + "LIVING_UPDATE_METHOD": "n", // EntityLivingBase.livingTick + "RABBIT_SET_MOVEMENT_SPEED": "c" // EntityRabbit.setMovementSpeed + }, + "obfuscated_fields": { + "ENTITY_SIDEWAYS_MOTION_FIELD": "bh", // EntityLivingBase.moveStrafing + "ENTITY_FORWARD_MOTION_FIELD": "bj", // EntityLivingBase.moveForward + // NOTE: New third parameter to move() as of 1.12 + "ENTITY_UPWARDS_MOTION_FIELD": "bi" // EntityLivingBase.moveVertical + } +} \ No newline at end of file diff --git a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSImpl.java b/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSImpl.java index 095d02cc..cfa43b1c 100644 --- a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSImpl.java +++ b/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSImpl.java @@ -41,13 +41,6 @@ import static com.google.common.base.Preconditions.*; public class NMSImpl implements INMS { - @Override - public SpawnEggItemData createSpawnEggData(byte rawData, ItemMeta meta) { - EntityType entityType = NMSSpawnEggItemData.getSpawnEggEntityTypeIfPresent(meta).orElse(EntityType.fromId(rawData)); - if (entityType == null) entityType = SpawnEggItemData.DEFAULT_TYPE; // 'Fix' broken configs - return new NMSSpawnEggItemData(rawData, meta, entityType); - } - @Override public SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta) { checkNotNull(entityType, "Null entity type"); diff --git a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/data/NMSSpawnEggItemData.java b/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/data/NMSSpawnEggItemData.java index 45200acf..1ca0fece 100644 --- a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/data/NMSSpawnEggItemData.java +++ b/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/data/NMSSpawnEggItemData.java @@ -23,7 +23,7 @@ public NMSSpawnEggItemData(byte rawData, ItemMeta meta) { } public NMSSpawnEggItemData(byte rawData, ItemMeta meta, EntityType type) { - super(rawData, createMetaWithEntityType(meta, type)); + super(Material.MONSTER_EGG, rawData, createMetaWithEntityType(meta, type)); } @Override diff --git a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSImpl.java b/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSImpl.java index 15a9fcfa..7c4cdd34 100644 --- a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSImpl.java +++ b/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSImpl.java @@ -41,12 +41,6 @@ import static com.google.common.base.Preconditions.*; public class NMSImpl implements INMS { - @Override - public SpawnEggItemData createSpawnEggData(byte rawData, ItemMeta meta) { - EntityType entityType = NMSSpawnEggItemData.getSpawnEggEntityTypeIfPresent(meta).orElse(EntityType.fromId(rawData)); - if (entityType == null) entityType = SpawnEggItemData.DEFAULT_TYPE; // 'Fix' broken configs - return new NMSSpawnEggItemData(rawData, meta, entityType); - } @Override public SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta) { diff --git a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/data/NMSSpawnEggItemData.java b/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/data/NMSSpawnEggItemData.java index 19831c87..b172e25f 100644 --- a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/data/NMSSpawnEggItemData.java +++ b/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/data/NMSSpawnEggItemData.java @@ -24,7 +24,7 @@ public NMSSpawnEggItemData(byte rawData, ItemMeta meta) { } public NMSSpawnEggItemData(byte rawData, ItemMeta meta, EntityType type) { - super(rawData, createMetaWithEntityType(meta, type)); + super(Material.MONSTER_EGG, rawData, createMetaWithEntityType(meta, type)); } @Override diff --git a/nms/v1_12_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_12_R1/NMSImpl.java b/nms/v1_12_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_12_R1/NMSImpl.java index 3a841b64..9f6d9601 100644 --- a/nms/v1_12_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_12_R1/NMSImpl.java +++ b/nms/v1_12_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_12_R1/NMSImpl.java @@ -42,13 +42,6 @@ import static com.google.common.base.Preconditions.*; public class NMSImpl implements INMS { - @Override - public SpawnEggItemData createSpawnEggData(byte rawData, ItemMeta meta) { - EntityType entityType = NMSSpawnEggItemData.getSpawnEggEntityTypeIfPresent(meta).orElse(EntityType.fromId(rawData)); - if (entityType == null) entityType = SpawnEggItemData.DEFAULT_TYPE; // 'Fix' broken configs - return new NMSSpawnEggItemData(rawData, meta, entityType); - } - @Override public SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta) { checkNotNull(entityType, "Null entity type"); diff --git a/nms/v1_12_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_12_R1/data/NMSSpawnEggItemData.java b/nms/v1_12_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_12_R1/data/NMSSpawnEggItemData.java index 5b0d9c03..389b2eae 100644 --- a/nms/v1_12_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_12_R1/data/NMSSpawnEggItemData.java +++ b/nms/v1_12_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_12_R1/data/NMSSpawnEggItemData.java @@ -24,7 +24,7 @@ public NMSSpawnEggItemData(byte rawData, ItemMeta meta) { } public NMSSpawnEggItemData(byte rawData, ItemMeta meta, EntityType type) { - super(rawData, createMetaWithEntityType(meta, type)); + super(Material.MONSTER_EGG, rawData, createMetaWithEntityType(meta, type)); } @Override diff --git a/nms/v1_13_R2/build.gradle.kts b/nms/v1_13_R2/build.gradle.kts new file mode 100644 index 00000000..297b0f27 --- /dev/null +++ b/nms/v1_13_R2/build.gradle.kts @@ -0,0 +1,5 @@ +dependencies { + // NOTE: We're compiling against paper now, too much hassle to compile Craftbukkit + compileOnly("com.destroystokyo.paper:paper:1.13.1-R0.1-SNAPSHOT") + compileOnly(project(":api")) +} diff --git a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/BlockSoundDataImpl.java b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/BlockSoundDataImpl.java new file mode 100644 index 00000000..9370161b --- /dev/null +++ b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/BlockSoundDataImpl.java @@ -0,0 +1,39 @@ +package net.techcable.sonarpet.nms.versions.v1_13_R2; + +import lombok.*; + +import net.minecraft.server.v1_13_R2.SoundEffectType; +import net.techcable.sonarpet.nms.BlockSoundData; + +@RequiredArgsConstructor +public class BlockSoundDataImpl implements BlockSoundData { + private final SoundEffectType handle; + + @Override + public float getVolume() { + // MCP: SoundType.getVolume + return handle.a(); + } + + @Override + public float getPitch() { + // MCP: SoundType.getPitch + return handle.b(); + } + + @Override + public boolean equals(Object o) { // We need this!! + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + BlockSoundDataImpl that = (BlockSoundDataImpl) o; + + return handle.equals(that.handle); + } + + @Override + public int hashCode() { + return handle.hashCode(); + } +} + diff --git a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/DamageSourceImpl.java b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/DamageSourceImpl.java new file mode 100644 index 00000000..ef59f6ed --- /dev/null +++ b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/DamageSourceImpl.java @@ -0,0 +1,11 @@ +package net.techcable.sonarpet.nms.versions.v1_13_R2; + +import lombok.*; + +import net.minecraft.server.v1_13_R2.DamageSource; + +@RequiredArgsConstructor +public class DamageSourceImpl implements net.techcable.sonarpet.nms.DamageSource { + @Getter + private final DamageSource handle; +} diff --git a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/DataWatcherImpl.java b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/DataWatcherImpl.java new file mode 100644 index 00000000..52075b9b --- /dev/null +++ b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/DataWatcherImpl.java @@ -0,0 +1,37 @@ +package net.techcable.sonarpet.nms.versions.v1_13_R2; + +import lombok.*; + +import net.minecraft.server.v1_13_R2.DataWatcher; +import net.minecraft.server.v1_13_R2.DataWatcherObject; +import net.minecraft.server.v1_13_R2.DataWatcherRegistry; +import net.minecraft.server.v1_13_R2.DataWatcherSerializer; + +@RequiredArgsConstructor +public class DataWatcherImpl implements net.techcable.sonarpet.nms.DataWatcher { + private final DataWatcher dataWatcher; + + // + // Unlikely to break, even across major versions + // IE: never broken yet ^_^ + // + + // MCP: DataSerializers.BOOLEAN + private static final DataWatcherSerializer BOOLEAN_SERIALIZER = DataWatcherRegistry.i; + // MCP: DataSerializers.VARINT + private static final DataWatcherSerializer INTEGER_SERIALIZER = DataWatcherRegistry.b; + + // + // Deobfuscated methods + // + + @Override + public void setBoolean(int id, boolean value) { + dataWatcher.set(new DataWatcherObject<>(id, BOOLEAN_SERIALIZER), value); + } + + @Override + public void setInteger(int id, int value) { + dataWatcher.set(new DataWatcherObject<>(id, INTEGER_SERIALIZER), value); + } +} diff --git a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSEntityHorseImpl.java b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSEntityHorseImpl.java new file mode 100644 index 00000000..81feb5f4 --- /dev/null +++ b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSEntityHorseImpl.java @@ -0,0 +1,75 @@ +package net.techcable.sonarpet.nms.versions.v1_13_R2; + +import com.dsh105.echopet.compat.api.entity.HorseType; +import com.dsh105.echopet.compat.api.entity.HorseTypeKt; + +import net.minecraft.server.v1_13_R2.EntityHorseAbstract; +import net.techcable.sonarpet.nms.NMSEntityHorse; + +import org.bukkit.entity.AbstractHorse; +import org.bukkit.entity.ChestedHorse; +import org.bukkit.entity.Horse; + +public class NMSEntityHorseImpl extends NMSEntityInsentientImpl implements NMSEntityHorse { + public NMSEntityHorseImpl(EntityHorseAbstract handle) { + super(handle); + } + + // + // !!!!! Highly version-dependent !!!!! + // Check these every minor update! + // + + @Override + public void setSaddled(boolean saddled) { + getHandle().x(saddled); // MCP: AbstractHorse.setHorseSaddled + } + + @Override + public boolean isSaddled() { + return getHandle().dV(); // MCP: AbstractHorse.isHorseSaddled + } + + // Deobfuscated methods + + @Override + public void setRearing(boolean b) { + getHandle().setStanding(b); + } + + @Override + public void setStyle(Horse.Style bukkitStyle) { + if (getBukkitEntity() instanceof Horse) { + ((Horse) getBukkitEntity()).setStyle(bukkitStyle); + } + } + + @Override + public void setColor(Horse.Color color) { + if (getBukkitEntity() instanceof Horse) { + ((Horse) getBukkitEntity()).setColor(color); + } + } + + @Override + public HorseType getHorseType() { + return HorseTypeKt.getSonarType(getBukkitEntity().getVariant()); + } + + @Override + public void setCarryingChest(boolean flag) { + if (getBukkitEntity() instanceof ChestedHorse) { + ((ChestedHorse) getBukkitEntity()).setCarryingChest(flag); + } + } + + @Override + public EntityHorseAbstract getHandle() { + return (EntityHorseAbstract) super.getHandle(); + } + + @Override + public AbstractHorse getBukkitEntity() { + return (AbstractHorse) super.getBukkitEntity(); + } +} diff --git a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSEntityImpl.java b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSEntityImpl.java new file mode 100644 index 00000000..2ad92df0 --- /dev/null +++ b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSEntityImpl.java @@ -0,0 +1,67 @@ +package net.techcable.sonarpet.nms.versions.v1_13_R2; + +import lombok.*; + +import com.google.common.collect.ImmutableList; + +import net.minecraft.server.v1_13_R2.DamageSource; +import net.minecraft.server.v1_13_R2.Entity; +import net.techcable.sonarpet.nms.INMS; +import net.techcable.sonarpet.nms.NMSEntity; + +import org.bukkit.entity.Player; + +@RequiredArgsConstructor +public class NMSEntityImpl implements NMSEntity { + @Getter + private final Entity handle; + + // + // Deobfuscated methods + // + + @Override + public boolean damageEntity(net.techcable.sonarpet.nms.DamageSource rawSource, float amount) { + DamageSource damageSource = ((DamageSourceImpl) rawSource).getHandle(); + return getHandle().damageEntity(damageSource, amount); + } + + @Override + public org.bukkit.entity.Entity getBukkitEntity() { + return handle.getBukkitEntity(); + } + + @Override + public ImmutableList getPassengers() { + return ImmutableList.copyOf(handle.passengers.stream() + .map(Entity::getBukkitEntity) + .map(INMS.getInstance()::wrapEntity) + .toArray(NMSEntity[]::new)); + } + + @Override + public int hashCode() { + return handle.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return obj != null && obj instanceof NMSEntityImpl && ((NMSEntityImpl) obj).handle.equals(this.handle); + } + + @Override + public String toString() { + if (getBukkitEntity() instanceof Player) { + return "NMSPlayer(" + getBukkitEntity().getName() + ")"; + } else { + StringBuilder builder = new StringBuilder("NMSEntity("); + builder.append(getBukkitEntity().getType()); + if (getBukkitEntity().getCustomName() != null) { + builder.append(":"); + builder.append(getBukkitEntity().getCustomName()); + } + builder.append(')'); + return builder.toString(); + } + } +} diff --git a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSEntityInsentientImpl.java b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSEntityInsentientImpl.java new file mode 100644 index 00000000..ed8da971 --- /dev/null +++ b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSEntityInsentientImpl.java @@ -0,0 +1,123 @@ +package net.techcable.sonarpet.nms.versions.v1_13_R2; + +import lombok.*; + +import java.lang.invoke.MethodHandle; +import java.util.Set; + +import com.google.common.collect.ImmutableList; + +import net.minecraft.server.v1_13_R2.*; +import net.techcable.pineapple.reflection.PineappleField; +import net.techcable.pineapple.reflection.Reflection; +import net.techcable.sonarpet.nms.NMSInsentientEntity; +import net.techcable.sonarpet.nms.NMSSound; + +import org.bukkit.craftbukkit.v1_13_R2.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_13_R2.entity.CraftLivingEntity; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; + +public class NMSEntityInsentientImpl extends NMSLivingEntityImpl implements NMSInsentientEntity { + + // + // !!!!! Highly version-dependent !!!!! + // Check these every minor update! + // + + private static final MethodHandle GET_DEATH_SOUND_METHOD_HANDLE = Reflection.getMethod( + EntityLiving.class, + "d", // MCP: EntityLivingBase.getHurtSound + DamageSource.class + ); + + + // + // Breakage likely, check for bugs here + // + + @Override + public float getVerticalFaceSpeed() { + return getHandle().K(); // MCP: EntityLiving.getVerticalFaceSpeed + } + + // + // Unlikely to break, even across major versions + // IE: never broken yet ^_^ + // + + @Override + public void clearGoals() { + PathfinderGoalSelector goalSelector = getHandle().goalSelector; + ImmutableList> fieldsToClear = PineappleField.findFieldsWithType(PathfinderGoalSelector.class, Set.class); + if (fieldsToClear.size() != 2) { + throw new AssertionError("Unexpected number of fields to clear: " + fieldsToClear); + } + for (PineappleField field : fieldsToClear) { + field.get(goalSelector).clear(); + } + } + + @Override + public void lookAt(Entity other, float perTick, float verticalFaceSpeed) { + getHandle().getControllerLook().a(((CraftEntity) other).getHandle(), perTick, verticalFaceSpeed); + } + + @Override + public void jump() { + getHandle().getControllerJump().a(); + } + + @Override + public void setCanSwim(boolean b) { + NavigationAbstract navigation = getHandle().getNavigation(); + if (navigation instanceof Navigation) { + ((Navigation) navigation).c(b); + } + } + + // + // Deobfuscated methods :) + // + + @Override + public void setFollowRange(double followRange) { + getHandle().getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(followRange); + } + + @Override + public LivingEntity getTarget() { + EntityLiving entity = getHandle().getGoalTarget(); + return entity != null ? (LivingEntity) entity.getBukkitEntity() : null; + } + + @Override + public void setTarget(LivingEntity target) { + getHandle().setGoalTarget(((CraftLivingEntity) target).getHandle()); + } + + @Override + public net.techcable.sonarpet.nms.Navigation getNavigation() { + return new NavigationImpl((NavigationAbstract) getHandle().getNavigation()); + } + + // + // Utility methods and wrappers + // + + @Override + public EntityInsentient getHandle() { + return (EntityInsentient) super.getHandle(); + } + + @Override + @SneakyThrows + public NMSSound getDeathSound() { + SoundEffect soundEffect = (SoundEffect) GET_DEATH_SOUND_METHOD_HANDLE.invoke(getHandle(), DamageSource.GENERIC); + return soundEffect != null ? new NMSSoundImpl(soundEffect) : null; + } + + public NMSEntityInsentientImpl(EntityInsentient handle) { + super(handle); + } +} diff --git a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSEntityRegistry.java b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSEntityRegistry.java new file mode 100644 index 00000000..4aad384a --- /dev/null +++ b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSEntityRegistry.java @@ -0,0 +1,120 @@ +package net.techcable.sonarpet.nms.versions.v1_13_R2; + +import com.google.common.base.Preconditions; +import lombok.*; + +import java.lang.invoke.MethodHandle; + +import net.minecraft.server.v1_13_R2.*; +import net.techcable.pineapple.SneakyThrow; +import net.techcable.pineapple.reflection.PineappleField; +import net.techcable.pineapple.reflection.Reflection; +import net.techcable.sonarpet.nms.EntityRegistry; + +public class NMSEntityRegistry implements EntityRegistry { + // + // Very rarely breaks + // Only broken once on 1.13 + // + + /* + * NOTE: Although classes are rarely obfuscated, + * EntityTypes.a should really be EntityTypes.Builder (according to MCP). + * EntityTypes is also a misleading name, + * it should really be EntityType since it represents only a single entity. + */ + @SuppressWarnings("unchecked") + private static final PineappleField>, RegistryID>> REGISTRY_ID_FIELD = + (PineappleField) PineappleField.findFieldWithType(RegistryMaterials.class, RegistryID.class); + private static final MethodHandle REGISTER_ENTITY_METHOD = + Reflection.getMethod(EntityTypes.class, "a", String.class, EntityTypes.a.class); // EntityList.register + + @Override + @SneakyThrows + public void registerEntityClass(Class entityClass, String name, int id) { + /* + * EntityTypes uses the following code to register an entity + * ```` + * AREA_EFFECT_CLOUD = a( + * "area_effect_cloud", + * EntityTypes.a.a( + * EntityAreaEffectCloud.class, + * EntityAreaEffectCloud::new + * ) + * ) + * ``` + * This roughHuhly deobfuscates as + * ```` + * EntityType.register( + * "area_effect_cloud", + * EntityTypes.Builder.create( + * EntityAreaEffectCloud.class, + * EntityAreaEffectClood::new + * ) + * ) + * NOTE: EntityTypes.Builder.create is missing from MCP + * ```` + */ + MethodHandle constructor = Reflection.getConstructor(entityClass, World.class); + // TODO: This seems to use whatever id it wants + REGISTER_ENTITY_METHOD.invoke(name, EntityTypes.a.a( + entityClass.asSubclass(Entity.class), + (world) -> { + try { + return (Entity) constructor.invoke(world); + } catch (Throwable t) { + throw SneakyThrow.sneakyThrow(t); + } + } + )); + } + + @Override + public void unregisterEntityClass(Class entityClass, String name, int id) { + // TODO: unregister + } + + @Override + public int getEntityId(Class entityClass) { + MinecraftKey key = EntityTypes.clsToKeyMap.get(entityClass.asSubclass(Entity.class)); + Preconditions.checkNotNull(key, "Invalid class %s", entityClass); + EntityTypes entityType = IRegistry.ENTITY_TYPE.get(key); + /* + * I was stuck on how to use ids until I looked in the packet system. + * In PacketPlayOutSpawnEntityLiving: `IRegistry.ENTITY_TYPE.a(var1.P())` + * This deobfuscates to `IRegistry.ENTITY_TYPE.getId(var1.getType())` + */ + // MCP: IRegistry.getId + return IRegistry.ENTITY_TYPE.a(entityType); + } + + @Override + public Class getEntityClass(int id) { + EntityTypes entityType = IRegistry.ENTITY_TYPE.fromId(id); + // MCP: EntityType.getEntityClass + return entityType.c(); + } + + + @Override + public String getEntityName(Class entityClass) { + MinecraftKey key = EntityTypes.clsToKeyMap.get(entityClass.asSubclass(Entity.class)); + Preconditions.checkNotNull(key, "Invalid class %s", entityClass); + EntityTypes entityType = IRegistry.ENTITY_TYPE.get(key); + return EntityTypes.getName(entityType).getKey(); + } + + @SuppressWarnings("unchecked") // I am already doing dark magic + @Override + public void registerEntityId(int id, Class entityClass) { + REGISTRY_ID_FIELD.get((RegistryMaterials) IRegistry.ENTITY_TYPE) + .a(entityClass, id); // IntIdentityHashBiMap.put + } + + @SuppressWarnings("unchecked") // I am already doing dark magic + @Override + public void unregisterEntityId(int id, Class entityClass) { + REGISTRY_ID_FIELD.get((RegistryMaterials) IRegistry.ENTITY_TYPE) + .a(null, id); // IntIdentityHashBiMap.put + } +} diff --git a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSImpl.java b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSImpl.java new file mode 100644 index 00000000..1f1e7ab3 --- /dev/null +++ b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSImpl.java @@ -0,0 +1,119 @@ +package net.techcable.sonarpet.nms.versions.v1_13_R2; + +import net.minecraft.server.v1_13_R2.*; +import net.minecraft.server.v1_13_R2.DamageSource; +import net.techcable.pineapple.reflection.PineappleField; +import net.techcable.sonarpet.item.SpawnEggItemData; +import net.techcable.sonarpet.nms.*; +import net.techcable.sonarpet.nms.versions.v1_13_R2.data.NMSSpawnEggItemData; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.craftbukkit.v1_13_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_13_R2.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_13_R2.entity.CraftLivingEntity; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.inventory.meta.ItemMeta; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +public class NMSImpl implements INMS { + @Override + public SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta) { + checkNotNull(entityType, "Null entity type"); + checkNotNull(meta, "Null item meta"); + return new NMSSpawnEggItemData((byte) 0, meta, entityType); + } + + @Override + public void mount(Entity bukkitRider, Entity bukkitVehicle) { + net.minecraft.server.v1_13_R2.Entity rider = ((CraftEntity) bukkitRider).getHandle(); + if (bukkitVehicle == null) { + net.minecraft.server.v1_13_R2.Entity vehicle = rider.getVehicle(); // This is how you *really* get the vehicle :/ + if (rider instanceof DismountingBlocked) { + ((DismountingBlocked) rider).reallyStopRiding(); + } + rider.stopRiding(); + if (vehicle != null) { + Packet packet = new PacketPlayOutMount(vehicle); + for (EntityHuman human : rider.world.players) { + ((EntityPlayer) human).playerConnection.sendPacket(packet); + } + } + } else { + checkArgument(bukkitRider.getWorld().equals(bukkitVehicle.getWorld()), "Rider is in world %s, while vehicle is in world %s", bukkitRider.getWorld().getName(), bukkitVehicle.getWorld().getName()); + net.minecraft.server.v1_13_R2.Entity vehicle = ((CraftEntity) bukkitVehicle).getHandle(); + rider.a(vehicle, true); // !! Obfuscated !! + Packet packet = new PacketPlayOutMount(vehicle); + for (EntityHuman human : rider.world.players) { + ((EntityPlayer) human).playerConnection.sendPacket(packet); + } + } + } + + @Override + public boolean spawnEntity(NMSInsentientEntity wrapper, Location l) { + EntityLiving entity = ((NMSEntityInsentientImpl) wrapper).getHandle(); + entity.spawnIn(((CraftWorld) l.getWorld()).getHandle()); + ((LivingEntity) entity.getBukkitEntity()).setCollidable(false); + entity.setLocation(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch()); + if (!l.getChunk().isLoaded()) { + l.getChunk().load(); + } + return entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); + } + + @Override + public net.techcable.sonarpet.nms.DamageSource mobAttackDamageSource(LivingEntity entity) { + return new DamageSourceImpl(DamageSource.mobAttack(((CraftLivingEntity) entity).getHandle())); + } + + @Override + public net.techcable.sonarpet.nms.DamageSource wrapDamageSource(Object handle) { + return new DamageSourceImpl((DamageSource) handle); + } + + @Override + public NMSEntity wrapEntity(Entity entity) { + net.minecraft.server.v1_13_R2.Entity handle = ((CraftEntity) entity).getHandle(); + if (handle instanceof EntityPlayer) { + return new NMSPlayerImpl((EntityPlayer) handle); + } else if (handle instanceof EntityHorseAbstract) { + return new NMSEntityHorseImpl((EntityHorseAbstract) handle); + } else if (handle instanceof EntityInsentient) { + return new NMSEntityInsentientImpl((EntityInsentient) handle); + } else if (handle instanceof EntityLiving) { + return new NMSLivingEntityImpl((EntityLiving) handle); + } else { + return new NMSEntityImpl(handle); + } + } + + private PineappleField STEP_SOUND_FIELD = PineappleField.create(Block.class, "stepSound", SoundEffectType.class); + @Override + @SuppressWarnings("deprecation") // I know about ur stupid magic value warning mom + public BlockSoundData getBlockSoundData(Material material) { + Block block = Block.getByCombinedId(material.getId()).getBlock(); + return new BlockSoundDataImpl(STEP_SOUND_FIELD.get(block)); + } + + @Override + @SuppressWarnings("deprecation") // I know about ur stupid magic value warning mom + public boolean isLiquid(Material block) { + return Block.getByCombinedId(block.getId()).getMaterial().isLiquid(); + } + + @Override + public EntityRegistry createDefaultEntityRegistry() { + return new NMSEntityRegistry(); + } + + @Override + public NMSSound getNmsSound(Sound bukkitSound) { + return new NMSSoundImpl(NMSSoundImplKt.getSoundEffect(bukkitSound)); + } +} diff --git a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSLivingEntityImpl.java b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSLivingEntityImpl.java new file mode 100644 index 00000000..88a79c61 --- /dev/null +++ b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSLivingEntityImpl.java @@ -0,0 +1,180 @@ +package net.techcable.sonarpet.nms.versions.v1_13_R2; + +import net.minecraft.server.v1_13_R2.EntityHuman; +import net.minecraft.server.v1_13_R2.EntityLiving; +import net.minecraft.server.v1_13_R2.SoundEffect; +import net.techcable.pineapple.reflection.PineappleField; +import net.techcable.sonarpet.nms.DataWatcher; +import net.techcable.sonarpet.nms.NMSLivingEntity; +import net.techcable.sonarpet.nms.NMSSound; + +import org.bukkit.craftbukkit.v1_13_R2.CraftSound; +import org.bukkit.craftbukkit.v1_13_R2.entity.CraftEntity; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; + +public class NMSLivingEntityImpl extends NMSEntityImpl implements NMSLivingEntity { + + // + // !!!!! Highly version-dependent !!!!! + // Check these every minor update! + // + public static final String IS_JUMPING_FIELD_NAME = "bg"; // EntityLivingBase.isJumping + + public NMSLivingEntityImpl(EntityLiving handle) { + super(handle); + } + + /** + * Set the 'offsets' for pitch and yaw to the same value as the yaw itself. + * Apparently this is needed to set rotation. + * See EntityLiving.h(FF) for details (method profiler 'headTurn'). + * Note that EntityInsentient overrides h(FF) and delegates to 'EntityAIBodyControl'. + * 'EntityAIBodyControl' is what actually accesses/uses these fields and where the mappings should be fetched. + *

+ * Also, these fields have the MCP names 'renderYawOffset' and 'rotationYawHead' + */ + @Override + public void correctYaw() { + getHandle().aQ = getHandle().aS = getHandle().yaw; + } + + @Override + public boolean isInLava() { + return getHandle().ax(); // MCP: Entity.isInLava + } + + // + // Breakage likely, check for bugs here + // + + @Override + public void setMoveSpeed(double rideSpeed) { + getHandle().o((float) rideSpeed); // MCP: EntityLivingBase.setAIMoveSpeed + } + + @Override + public void setStepHeight(float stepHeight) { + getHandle().Q = stepHeight; // MCP: Entity.stepHeight + } + + + // + // Unlikely to break, even across major versions + // IE: never broken yet ^_^ + // + + @Override + public void playSound(NMSSound sound, float volume, float pitch) { + getHandle().a(((NMSSoundImpl) sound).getHandle(), volume, pitch); + } + + @Override + public double distanceTo(Entity other) { + return getHandle().h(((CraftEntity) other).getHandle()); + } + + + // + // Deobfuscated methods :) + // + + @Override + public Player findNearbyPlayer(double range) { + EntityHuman player = getHandle().world.findNearbyPlayer(getHandle(), range); + return player == null ? null : (Player) player.getBukkitEntity(); + } + + @Override + public boolean isInvisible() { + return getHandle().isInvisible(); + } + + @Override + public boolean isSneaking() { + return getHandle().isSneaking(); + } + + @Override + public void setSneaking(boolean b) { + getHandle().setSneaking(b); + } + + @Override + public void setInvisible(boolean b) { + getHandle().setInvisible(b); + } + + @Override + public boolean isSprinting() { + return getHandle().isSprinting(); + } + + @Override + public void setSprinting(boolean b) { + getHandle().setSprinting(b); + } + + @Override + public void setYaw(float yaw) { + getHandle().yaw = yaw; + } + + @Override + public void setPitch(float pitch) { + getHandle().pitch = pitch; + } + + @Override + public void setNoClip(boolean b) { + getHandle().noclip = b; + } + + @Override + public boolean isInWater() { + return getHandle().isInWater(); + } + + + @Override + public void setUpwardsMotion(double motY) { + getHandle().motY = motY; + } + + @Override + public DataWatcher getDataWatcher() { + return new DataWatcherImpl(getHandle().getDataWatcher()); + } + + @Override + public double getWidth() { + return getHandle().width; + } + + @Override + public double getLength() { + return getHandle().length; + } + + // + // Utility methods and wrappers + // + + private static final PineappleField IS_JUMPING_FIELD = PineappleField.create(EntityLiving.class, IS_JUMPING_FIELD_NAME, boolean.class); + + @Override + public boolean isJumping() { + return IS_JUMPING_FIELD.getBoxed(getHandle()); + } + + @Override + public EntityLiving getHandle() { + return (EntityLiving) super.getHandle(); + } + + @Override + public LivingEntity getBukkitEntity() { + return (LivingEntity) getHandle().getBukkitEntity(); + } +} diff --git a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSPlayerImpl.java b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSPlayerImpl.java new file mode 100644 index 00000000..f4999eac --- /dev/null +++ b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSPlayerImpl.java @@ -0,0 +1,27 @@ +package net.techcable.sonarpet.nms.versions.v1_13_R2; + +import net.minecraft.server.v1_13_R2.EntityPlayer; +import net.techcable.sonarpet.nms.NMSPlayer; + +import org.bukkit.entity.Player; + +public class NMSPlayerImpl extends NMSLivingEntityImpl implements NMSPlayer { + public NMSPlayerImpl(EntityPlayer handle) { + super(handle); + } + + @Override + public boolean isOnGround() { + return getHandle().onGround; + } + + @Override + public EntityPlayer getHandle() { + return (EntityPlayer) super.getHandle(); + } + + @Override + public Player getBukkitEntity() { + return (Player) super.getBukkitEntity(); + } +} diff --git a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NavigationImpl.java b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NavigationImpl.java new file mode 100644 index 00000000..6d124097 --- /dev/null +++ b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NavigationImpl.java @@ -0,0 +1,55 @@ +package net.techcable.sonarpet.nms.versions.v1_13_R2; + +import lombok.*; + +import net.minecraft.server.v1_13_R2.Navigation; +import net.minecraft.server.v1_13_R2.NavigationAbstract; +import net.techcable.sonarpet.nms.PathEntity; + +import org.bukkit.craftbukkit.v1_13_R2.entity.CraftEntity; +import org.bukkit.entity.Entity; + +@RequiredArgsConstructor +public class NavigationImpl implements net.techcable.sonarpet.nms.Navigation { + private final NavigationAbstract handle; + + + // + // Breakage likely, check for bugs here + // + + @Override + public boolean canEnterDoors() { + return handle.s().c(); // MCP: PathNavigate.getNodeProcessor().getCanEnterDoors() + } + + @Override + public void finish() { + handle.p(); // MCP: PathNavigate.noPath + } + + // + // Unlikely to break, even across major versions + // IE: never broken yet ^_^ + // + + @Override + public PathEntity getPathToLocation(int blockX, int blockY, int blockZ) { + return new PathEntityImpl(handle.a(blockX, blockY, blockZ)); + } + + @Override + public PathEntity getPathTo(Entity other) { + return new PathEntityImpl(handle.a(((CraftEntity) other).getHandle())); + } + + @Override + public void navigateTo(PathEntity path, double speed) { + handle.a(((PathEntityImpl) path).handle, speed); + } + + @RequiredArgsConstructor + private static class PathEntityImpl implements PathEntity { + /* package */ final net.minecraft.server.v1_13_R2.PathEntity handle; + } +} diff --git a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/data/NMSSpawnEggItemData.java b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/data/NMSSpawnEggItemData.java new file mode 100644 index 00000000..8291b4fc --- /dev/null +++ b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/data/NMSSpawnEggItemData.java @@ -0,0 +1,46 @@ +package net.techcable.sonarpet.nms.versions.v1_13_R2.data; + +import java.util.Optional; + +import com.google.common.base.Preconditions; + +import net.minecraft.server.v1_13_R2.*; +import net.techcable.sonarpet.item.SpawnEggItemData; + +import net.techcable.sonarpet.utils.ModernSpawnEggs; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_13_R2.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_13_R2.util.CraftMagicNumbers; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.meta.ItemMeta; + +public class NMSSpawnEggItemData extends SpawnEggItemData { + public NMSSpawnEggItemData(byte rawData, ItemMeta meta, EntityType type) { + super(ModernSpawnEggs.getEggMaterial(type), rawData, meta); + } + + @Override + public EntityType getSpawnedType() { + return ModernSpawnEggs.getSpawnEggType(this.getMaterialData().getItemType()); + } + + + public static ItemMeta create(Material type, NBTTagCompound tag) { + Item item = CraftMagicNumbers.getItem(Preconditions.checkNotNull(type, "Null type")); + ItemStack stack = new ItemStack(item); + stack.setTag(Preconditions.checkNotNull(tag, "Null nbt tag")); + return CraftItemStack.getItemMeta(stack); + } + + public static NBTTagCompound getTagFromMeta(Material type, ItemMeta meta) { + Preconditions.checkNotNull(meta, "Null meta"); + Preconditions.checkNotNull(type, "Null type"); + Preconditions.checkArgument(Bukkit.getItemFactory().isApplicable(meta, type), "Meta %s isn't applicable to %s", meta, type); + Item item = CraftMagicNumbers.getItem(type); + ItemStack stack = new ItemStack(item); + boolean worked = CraftItemStack.setItemMeta(stack, meta); + if (!worked) throw new RuntimeException("Didn't work"); + return stack.getTag(); + } +} diff --git a/nms/v1_13_R2/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSSoundImpl.kt b/nms/v1_13_R2/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSSoundImpl.kt new file mode 100644 index 00000000..421a368e --- /dev/null +++ b/nms/v1_13_R2/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSSoundImpl.kt @@ -0,0 +1,21 @@ +package net.techcable.sonarpet.nms.versions.v1_13_R2 + +import net.minecraft.server.v1_13_R2.SoundEffect +import net.techcable.sonarpet.nms.NMSSound +import net.techcable.sonarpet.utils.buildImmutableMap +import org.bukkit.Sound +import org.bukkit.craftbukkit.v1_13_R2.CraftSound + +private val BUKKIT_SOUNDS = buildImmutableMap { + for (sound in enumValues()) { + put(sound.soundEffect, sound) + } +} + +val Sound.soundEffect: SoundEffect + get() = CraftSound.getSoundEffect(CraftSound.getSound(this))!! + +class NMSSoundImpl(val handle: SoundEffect): NMSSound { + override val bukkitSound: Sound? + get() = BUKKIT_SOUNDS[handle] +} \ No newline at end of file diff --git a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSImpl.java b/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSImpl.java index e70678be..4e37f790 100644 --- a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSImpl.java +++ b/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSImpl.java @@ -41,13 +41,6 @@ import static com.google.common.base.Preconditions.*; public class NMSImpl implements INMS { - @Override - public SpawnEggItemData createSpawnEggData(byte rawData, ItemMeta meta) { - EntityType entityType = NMSSpawnEggItemData.getSpawnEggEntityTypeIfPresent(meta).orElse(EntityType.fromId(rawData)); - if (entityType == null) entityType = SpawnEggItemData.DEFAULT_TYPE; // 'Fix' broken configs - return new NMSSpawnEggItemData(rawData, meta, entityType); - } - @Override public SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta) { checkNotNull(entityType, "Null entity type"); diff --git a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/data/NMSSpawnEggItemData.java b/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/data/NMSSpawnEggItemData.java index 5e6e3e63..151425b7 100644 --- a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/data/NMSSpawnEggItemData.java +++ b/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/data/NMSSpawnEggItemData.java @@ -23,7 +23,7 @@ public NMSSpawnEggItemData(byte rawData, ItemMeta meta) { } public NMSSpawnEggItemData(byte rawData, ItemMeta meta, EntityType type) { - super(rawData, createMetaWithEntityType(meta, type)); + super(Material.MONSTER_EGG, rawData, createMetaWithEntityType(meta, type)); } @Override diff --git a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSImpl.java b/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSImpl.java index 178d6f45..434b2793 100644 --- a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSImpl.java +++ b/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSImpl.java @@ -41,13 +41,6 @@ import static com.google.common.base.Preconditions.*; public class NMSImpl implements INMS { - @Override - public SpawnEggItemData createSpawnEggData(byte rawData, ItemMeta meta) { - EntityType entityType = NMSSpawnEggItemData.getSpawnEggEntityTypeIfPresent(meta).orElse(EntityType.fromId(rawData)); - if (entityType == null) entityType = SpawnEggItemData.DEFAULT_TYPE; // 'Fix' broken configs - return new NMSSpawnEggItemData(rawData, meta, entityType); - } - @Override public SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta) { checkNotNull(entityType, "Null entity type"); diff --git a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/data/NMSSpawnEggItemData.java b/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/data/NMSSpawnEggItemData.java index 1691fe89..f24119d2 100644 --- a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/data/NMSSpawnEggItemData.java +++ b/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/data/NMSSpawnEggItemData.java @@ -23,7 +23,7 @@ public NMSSpawnEggItemData(byte rawData, ItemMeta meta) { } public NMSSpawnEggItemData(byte rawData, ItemMeta meta, EntityType type) { - super(rawData, createMetaWithEntityType(meta, type)); + super(Material.MONSTER_EGG, rawData, createMetaWithEntityType(meta, type)); } @Override diff --git a/settings.gradle b/settings.gradle index af29a06e..8f8271cc 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,7 +1,7 @@ rootProject.name = 'SonarPet' rootProject.buildFileName = "build.gradle.kts" include 'api' -List nmsVersions = ["v1_8_R3", "v1_9_R1", "v1_9_R2", "v1_10_R1", "v1_11_R1", "v1_12_R1"] +List nmsVersions = ["v1_8_R3", "v1_9_R1", "v1_9_R2", "v1_10_R1", "v1_11_R1", "v1_12_R1", "v1_13_R2"] for (version in nmsVersions) { include "nms-$version" project(":nms-$version").projectDir = "$rootDir/nms/$version" as File From decc1f6df992b8f14526a785f4f659c8cbcce12d Mon Sep 17 00:00:00 2001 From: Techcable Date: Sun, 14 Oct 2018 15:27:47 -0700 Subject: [PATCH 2/8] Update to 1.13: Work on supporting the new Material system This update still isn't complete and won't even load. The alpha probably will break your config files, alhtough your databases are probably safe. Bukkit has pretty much dropped support for integer block ids. If that's not enough, they've written a compelex bytecode rewriting backwards compatibility system which screws with my attempt to support 1.13. I can use reflection to bypass it, but it's still kind of clumsy. The new bukkit API for dealing with `BlockData` is great, but the `ItemMeta` API is still lagging way behind. I'm going to have to rewrite and expand the `ItemData` system in order to abstract around these differences. I also intend to write a new `BlockData` API, which will abstract over the differences between versions (so I don't have to use reflection). For 1.13 compatibility, we must finally stop using all block and item ids. However, we must do this without using any of Bukkit's new APIs (for 1.12 compat). The only solution I can come up with is rerouting all item manipulation and access through my new `ItemData` and `BlockData` APIs. --- .../compat/api/config/ConfigOptions.java | 5 +- .../compat/api/util/inventory/MenuIcon.java | 6 +- .../compat/api/util/menu/SelectorItem.java | 6 +- .../compat/api/util/menu/SelectorLayout.java | 9 +- .../net/techcable/sonarpet/item/ItemData.java | 49 +++++---- .../sonarpet/item/LegacyMaterialSystem.java | 23 ++++ .../sonarpet/item/MaterialSystem.java | 22 ++++ .../sonarpet/item/ModernMaterialSystem.java | 101 ++++++++++++++++++ .../java/net/techcable/sonarpet/nms/INMS.java | 3 +- .../sonarpet/utils/ModernSpawnEggs.java | 8 +- .../techcable/sonarpet/utils/NmsVersion.java | 25 +++++ .../nms/versions/v1_13_R2/NMSImpl.java | 6 ++ .../v1_13_R2/data/NMSSpawnEggItemData.java | 13 +-- 13 files changed, 223 insertions(+), 53 deletions(-) create mode 100644 api/src/main/java/net/techcable/sonarpet/item/LegacyMaterialSystem.java create mode 100644 api/src/main/java/net/techcable/sonarpet/item/MaterialSystem.java create mode 100644 api/src/main/java/net/techcable/sonarpet/item/ModernMaterialSystem.java diff --git a/api/src/main/java/com/dsh105/echopet/compat/api/config/ConfigOptions.java b/api/src/main/java/com/dsh105/echopet/compat/api/config/ConfigOptions.java index 05a0d2b9..d0312eef 100644 --- a/api/src/main/java/com/dsh105/echopet/compat/api/config/ConfigOptions.java +++ b/api/src/main/java/com/dsh105/echopet/compat/api/config/ConfigOptions.java @@ -23,6 +23,7 @@ import com.dsh105.echopet.compat.api.entity.PetType; import com.dsh105.echopet.compat.api.util.menu.SelectorIcon; import com.dsh105.echopet.compat.api.util.menu.SelectorLayout; +import net.techcable.sonarpet.item.MaterialSystem; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -156,8 +157,8 @@ public void setDefaults() { int friendlySlot = icon.getSlot() + 1; set("petSelector.menu.slot-" + friendlySlot + ".command", icon.getCommand()); set("petSelector.menu.slot-" + friendlySlot + ".petType", icon.getPetType() == null ? "" : icon.getPetType().toString()); - set("petSelector.menu.slot-" + friendlySlot + ".materialId", icon.getType().getId()); - set("petSelector.menu.slot-" + friendlySlot + ".materialData", icon.getMaterialData().getData()); + // NOTE: Temporarily upgraded from old system + set("petSelector.menu.slot-" + friendlySlot + ".material", MaterialSystem.getInstance().serializeData(icon.getItemData())); set("petSelector.menu.slot-" + friendlySlot + ".name", (icon.getName() == null ? "" : icon.getName()).replace(ChatColor.COLOR_CHAR, '&')); ArrayList lore = new ArrayList(); for (String s : icon.getLore()) { diff --git a/api/src/main/java/com/dsh105/echopet/compat/api/util/inventory/MenuIcon.java b/api/src/main/java/com/dsh105/echopet/compat/api/util/inventory/MenuIcon.java index 1211bc19..db97e518 100644 --- a/api/src/main/java/com/dsh105/echopet/compat/api/util/inventory/MenuIcon.java +++ b/api/src/main/java/com/dsh105/echopet/compat/api/util/inventory/MenuIcon.java @@ -49,11 +49,7 @@ public int getSlot() { } public Material getType() { - return getMaterialData().getItemType(); - } - - public MaterialData getMaterialData() { - return itemData.getMaterialData(); + return itemData.getType(); } public String getName() { diff --git a/api/src/main/java/com/dsh105/echopet/compat/api/util/menu/SelectorItem.java b/api/src/main/java/com/dsh105/echopet/compat/api/util/menu/SelectorItem.java index 8f0c1204..554f5c33 100644 --- a/api/src/main/java/com/dsh105/echopet/compat/api/util/menu/SelectorItem.java +++ b/api/src/main/java/com/dsh105/echopet/compat/api/util/menu/SelectorItem.java @@ -64,17 +64,13 @@ public String getCommand() { } public Material getType() { - return getMaterialData().getItemType(); + return getItemData().getType(); } public int getAmount() { return amount; } - public MaterialData getMaterialData() { - return getItemData().getMaterialData(); - } - public String getName() { return getItemData().getDisplayName().get(); } diff --git a/api/src/main/java/com/dsh105/echopet/compat/api/util/menu/SelectorLayout.java b/api/src/main/java/com/dsh105/echopet/compat/api/util/menu/SelectorLayout.java index 32232990..dccbc116 100644 --- a/api/src/main/java/com/dsh105/echopet/compat/api/util/menu/SelectorLayout.java +++ b/api/src/main/java/com/dsh105/echopet/compat/api/util/menu/SelectorLayout.java @@ -24,6 +24,7 @@ import com.dsh105.echopet.compat.api.entity.PetType; import com.google.common.collect.ImmutableList; +import net.techcable.sonarpet.item.MaterialSystem; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.event.HandlerList; @@ -83,8 +84,9 @@ public static void loadLayout() { if (petType != null && GeneralUtil.isEnumType(PetType.class, petType.toUpperCase())) { pt = PetType.valueOf(petType.toUpperCase()); } - int id = config.getInt(s + ".slot-" + i + ".materialId"); - int data = config.getInt(s + ".slot-" + i + ".materialData"); + // TODO: Convert from legacy ids + ItemData basicData = MaterialSystem.getInstance().parseData( + config.getString(s + ".slot-" + i + ".material")); String name = config.getString(s + ".slot-" + i + ".name"); if (name == null) { continue; @@ -99,8 +101,7 @@ public static void loadLayout() { loreList.add(ChatColor.translateAlternateColorCodes('&', part)); } } - Material type = Material.getMaterial(id); - selectorLayout.add(new SelectorIcon(i - 1, cmd, pt, ItemData.create(type, data).withDisplayName(name.trim().isEmpty() ? Optional.empty() : Optional.of(name)).withLore(loreList))); + selectorLayout.add(new SelectorIcon(i - 1, cmd, pt, basicData.withDisplayName(name.trim().isEmpty() ? Optional.empty() : Optional.of(name)).withLore(loreList))); } selectorMenu = new SelectorMenu(); diff --git a/api/src/main/java/net/techcable/sonarpet/item/ItemData.java b/api/src/main/java/net/techcable/sonarpet/item/ItemData.java index 7c36573c..cc6d809c 100644 --- a/api/src/main/java/net/techcable/sonarpet/item/ItemData.java +++ b/api/src/main/java/net/techcable/sonarpet/item/ItemData.java @@ -5,14 +5,17 @@ import java.util.List; import java.util.Optional; +import net.techcable.sonarpet.item.ModernMaterialSystem; import net.techcable.sonarpet.nms.INMS; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import net.techcable.sonarpet.utils.ModernSpawnEggs; +import net.techcable.sonarpet.utils.NmsVersion; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BlockStateMeta; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.material.MaterialData; import org.bukkit.material.MonsterEggs; @@ -74,40 +77,26 @@ public static ItemData create(Material type, int rawData, ItemMeta meta) { * NOTE: I'm keeping Material.MONSTER_EGG out of the switch * since it's deprecated on 1.13. * It'll now be conditional on whether we have 'modern' monster egg support + * Furthermore we have to switch on the raw string, + * since bukkit does some crazy madness with the ordinal. */ - switch (type) { - case INK_SACK: + switch (type.name()) { + case "INK_SACK": return new DyeItemData((byte) rawData, meta); - case SKULL_ITEM: + case "SKULL_ITEM": return new SkullItemData((byte) rawData, meta); - case MONSTER_EGG: - case STAINED_CLAY: + case "STAINED_CLAY": return new StainedClayItemData((byte) rawData, meta); - case WOOL: + case "WOOL": return new StainedClayItemData((byte) rawData, meta); default: return new ItemData(type, (byte) rawData, meta); } } - public MaterialData getMaterialData() { - return type.getNewData(rawData); - } - - public ItemData withType(Material type) { - Preconditions.checkNotNull(type, "Null material"); - return withMaterialData(new MaterialData(type, getRawData())); - } - - public ItemData withRawData(int rawData) { Preconditions.checkArgument((byte) rawData == rawData, "Raw data doesn't fit into byte: %s", rawData); - return withMaterialData(new MaterialData(getType(), (byte) rawData)); - } - - public ItemData withMaterialData(MaterialData data) { - Preconditions.checkNotNull(data, "Material data"); - return this.withType(data.getItemType()).withRawData(data.getData()); + return ItemData.create(this.type, rawData, this.meta); } public ItemData withMeta(ItemMeta meta) { @@ -162,4 +151,20 @@ public ItemStack createStack(int amount) { stack.setItemMeta(this.meta.clone()); return stack; } + + public MaterialData getLegacyMaterialData() { + NmsVersion.ensureBefore(NmsVersion.v1_13_R2); + return this.type.getNewData(this.rawData); + } + + public Object getModernBlockData() { + NmsVersion.ensureAtLeast(NmsVersion.v1_13_R2); + if (this.meta instanceof BlockStateMeta) { + return ModernMaterialSystem.getDataFromState( + ((BlockStateMeta) this.meta).getBlockState() + ); + } else { + return ModernMaterialSystem.createDefaultBlockData(this.type); + } + } } diff --git a/api/src/main/java/net/techcable/sonarpet/item/LegacyMaterialSystem.java b/api/src/main/java/net/techcable/sonarpet/item/LegacyMaterialSystem.java new file mode 100644 index 00000000..6b1c65bc --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/item/LegacyMaterialSystem.java @@ -0,0 +1,23 @@ +package net.techcable.sonarpet.item; + +public class LegacyMaterialSystem implements MaterialSystem { + @SuppressWarnings("deprecation") // this is legacy + @Override + public String serializeData(ItemData m) { + byte data = m.getLegacyMaterialData().getData(); + int id = m.getType().getId(); + return id + ":" + data; + } + + @Override + public ItemData parseData(String s) { + String[] parts = s.split(":"); + if (parts.length == 2) { + try { + int id = Integer.parseInt(parts[0]); + byte data = Byte.parseByte(parts[1]); + } catch (NumberFormatException ignored) {} + } + throw new IllegalArgumentException("Invalid item data: " + s); + } +} diff --git a/api/src/main/java/net/techcable/sonarpet/item/MaterialSystem.java b/api/src/main/java/net/techcable/sonarpet/item/MaterialSystem.java new file mode 100644 index 00000000..970de868 --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/item/MaterialSystem.java @@ -0,0 +1,22 @@ +package net.techcable.sonarpet.item; + +import net.techcable.sonarpet.utils.NmsVersion; + +/** + * Defines a system for interacting between `org.bukkit.Material`. + * + * This is necessary for the new and radical changes in 1.13. + */ +public interface MaterialSystem { + String serializeData(ItemData m); + + ItemData parseData(String s); + + static MaterialSystem getInstance() { + if (NmsVersion.current().isAtLeast(NmsVersion.v1_13_R2)) { + return new ModernMaterialSystem(); + } else { + return new LegacyMaterialSystem(); + } + } +} diff --git a/api/src/main/java/net/techcable/sonarpet/item/ModernMaterialSystem.java b/api/src/main/java/net/techcable/sonarpet/item/ModernMaterialSystem.java new file mode 100644 index 00000000..0d6f5674 --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/item/ModernMaterialSystem.java @@ -0,0 +1,101 @@ +package net.techcable.sonarpet.item; + +import com.google.common.base.Preconditions; +import lombok.SneakyThrows; +import net.techcable.pineapple.reflection.Reflection; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.block.BlockState; +import org.bukkit.inventory.meta.BlockStateMeta; +import org.bukkit.inventory.meta.ItemMeta; + +import java.lang.invoke.MethodHandle; +import java.util.Objects; + +public class ModernMaterialSystem implements MaterialSystem { + @Override + @SneakyThrows + public String serializeData(ItemData m) { + if (m.getType().isBlock()) { + // Give them the whole block data + return (String) BLOCK_DATA_GET_AS_STRING.invoke(m.getModernBlockData()); + } else { + // Otherwise we just give them the material without any data + // This strips all information, but the bukkit API has no real alternative + // NOTE: Must use reflection in order to bypass the 1.13 compat hacks + return (String) MATERIAL_NAME.invoke(m.getType()); + } + } + + @Override + @SneakyThrows + public ItemData parseData(String s) { + Preconditions.checkNotNull(s, "Null data"); + { + Material m = (Material) MATERIAL_GET_MATERIAL.invokeExact(s); + if (m != null) { + // First we try just the material, in case it's an item + return ItemData.create(m); + } + } + Object data = SERVER_CREATE_BLOCK_DATA.invoke(Bukkit.getServer(), s); + Material m = (Material) BLOCK_DATA_GET_MATERIAL.invoke(data); + ItemMeta meta = Bukkit.getItemFactory().getItemMeta(m); + if (meta instanceof BlockStateMeta) { + // TODO: I think this should always be the case + // Really, we need to just make ItemData fully version-dependent on modern versions + BlockState state = ((BlockStateMeta) meta).getBlockState(); + BLOCK_STATE_SET_DATA.invoke(state, data); + } + return ItemData.create(m, meta); + } + + private static final Class BLOCK_DATA_CLASS = Objects.requireNonNull( + Reflection.getClass("org.bukkit.block.data.BlockData")); + private static final MethodHandle SERVER_CREATE_BLOCK_DATA = Reflection.getMethod( + Server.class, + "createBlockData", + String.class + ); + private static final MethodHandle BLOCK_DATA_GET_AS_STRING = Reflection.getMethod( + BLOCK_DATA_CLASS, + "getAsString" + ); + private static final MethodHandle BLOCK_DATA_GET_MATERIAL = Reflection.getMethod( + BLOCK_DATA_CLASS, + "getMaterial" + ); + private static final MethodHandle MATERIAL_CREATE_BLOCK_DATA = Reflection.getMethod( + Material.class, + "createBlockData" + ); + + private static final MethodHandle MATERIAL_NAME = Reflection.getMethod( + Enum.class, + "name" + ); + private static final MethodHandle MATERIAL_GET_MATERIAL = Reflection.getMethod( + Material.class, + "getMaterial", + String.class + ); + private static final MethodHandle BLOCK_STATE_GET_DATA = Reflection.getMethod( + BlockState.class, + "getBlockData" + ); + private static final MethodHandle BLOCK_STATE_SET_DATA = Reflection.getMethod( + BlockState.class, + "setBlockData", + BLOCK_DATA_CLASS + ); + + @SneakyThrows + public static Object createDefaultBlockData(Material m) { + return MATERIAL_CREATE_BLOCK_DATA.invoke(m); + } + @SneakyThrows + public static Object getDataFromState(BlockState state) { + return BLOCK_STATE_GET_DATA.invoke(state); + } +} diff --git a/api/src/main/java/net/techcable/sonarpet/nms/INMS.java b/api/src/main/java/net/techcable/sonarpet/nms/INMS.java index e958c2e8..00dfdd57 100644 --- a/api/src/main/java/net/techcable/sonarpet/nms/INMS.java +++ b/api/src/main/java/net/techcable/sonarpet/nms/INMS.java @@ -44,7 +44,6 @@ @SuppressWarnings("deprecation") public interface INMS { - default SpawnEggItemData createSpawnEggData(Material material, byte rawData, ItemMeta meta) { EntityType entityType; if (ModernSpawnEggs.isSupported()) { @@ -66,7 +65,7 @@ default SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta @Override @SuppressWarnings("depreciation") // Bukkit is okay on versions less than 1.9, and we've already checked above public EntityType getSpawnedType() { - return ((SpawnEgg) getMaterialData()).getSpawnedType(); + return ((SpawnEgg) getLegacyMaterialData()).getSpawnedType(); } }; } diff --git a/api/src/main/java/net/techcable/sonarpet/utils/ModernSpawnEggs.java b/api/src/main/java/net/techcable/sonarpet/utils/ModernSpawnEggs.java index 89c8ca8c..013b7304 100644 --- a/api/src/main/java/net/techcable/sonarpet/utils/ModernSpawnEggs.java +++ b/api/src/main/java/net/techcable/sonarpet/utils/ModernSpawnEggs.java @@ -1,10 +1,13 @@ package net.techcable.sonarpet.utils; +import lombok.SneakyThrows; import org.bukkit.Material; import org.bukkit.entity.EntityType; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; public class ModernSpawnEggs { private ModernSpawnEggs() {} @@ -44,10 +47,13 @@ public static EntityType getSpawnEggType(Material m) { } private static final String SUFFIX = "_SPAWN_EGG"; @Nullable + @SneakyThrows(ReflectiveOperationException.class) private static Material tryGetEggMaterial(EntityType entityType) { ModernSpawnEggs.ensureSupported(); + Class materialClass = Class.forName("org.bukkit.Material"); try { - return Material.valueOf(entityType.name() + SUFFIX); + //noinspection unchecked + return (Material) Enum.valueOf(materialClass, entityType.name() + SUFFIX); } catch (IllegalArgumentException ignored) { return null; } diff --git a/api/src/main/java/net/techcable/sonarpet/utils/NmsVersion.java b/api/src/main/java/net/techcable/sonarpet/utils/NmsVersion.java index 734e6f95..096a362c 100644 --- a/api/src/main/java/net/techcable/sonarpet/utils/NmsVersion.java +++ b/api/src/main/java/net/techcable/sonarpet/utils/NmsVersion.java @@ -121,4 +121,29 @@ private static int parseMajorVersion(String s) { public static NmsVersion current() { return Versioning.NMS_VERSION; } + + public boolean isAtLeast(NmsVersion minimum) { + return this.compareTo(minimum) >= 0; + } + public boolean isBefore(NmsVersion other) { + return this.compareTo(other) < 0; + } + public static void ensureAtLeast(NmsVersion minimum) { + NmsVersion current = NmsVersion.current(); + if (!current.isAtLeast(minimum)) { + throw new IllegalStateException("Expected NMS version at least " + + minimum + + ", but got " + + current); + } + } + public static void ensureBefore(NmsVersion maximum) { + NmsVersion current = NmsVersion.current(); + if (!current.isBefore(maximum)) { + throw new IllegalStateException("Expected NMS version before " + + maximum + + ", but got " + + current); + } + } } diff --git a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSImpl.java b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSImpl.java index 1f1e7ab3..a42e522e 100644 --- a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSImpl.java +++ b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSImpl.java @@ -3,13 +3,16 @@ import net.minecraft.server.v1_13_R2.*; import net.minecraft.server.v1_13_R2.DamageSource; import net.techcable.pineapple.reflection.PineappleField; +import net.techcable.sonarpet.item.ItemData; import net.techcable.sonarpet.item.SpawnEggItemData; import net.techcable.sonarpet.nms.*; import net.techcable.sonarpet.nms.versions.v1_13_R2.data.NMSSpawnEggItemData; +import net.techcable.sonarpet.utils.ModernSpawnEggs; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.craftbukkit.v1_13_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_13_R2.block.data.CraftBlockData; import org.bukkit.craftbukkit.v1_13_R2.entity.CraftEntity; import org.bukkit.craftbukkit.v1_13_R2.entity.CraftLivingEntity; import org.bukkit.entity.Entity; @@ -26,6 +29,9 @@ public class NMSImpl implements INMS { public SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta) { checkNotNull(entityType, "Null entity type"); checkNotNull(meta, "Null item meta"); + if (!ModernSpawnEggs.hasSpawnEgg(entityType)) { + entityType = SpawnEggItemData.DEFAULT_TYPE; + } return new NMSSpawnEggItemData((byte) 0, meta, entityType); } diff --git a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/data/NMSSpawnEggItemData.java b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/data/NMSSpawnEggItemData.java index 8291b4fc..f7d5a122 100644 --- a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/data/NMSSpawnEggItemData.java +++ b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/data/NMSSpawnEggItemData.java @@ -22,7 +22,7 @@ public NMSSpawnEggItemData(byte rawData, ItemMeta meta, EntityType type) { @Override public EntityType getSpawnedType() { - return ModernSpawnEggs.getSpawnEggType(this.getMaterialData().getItemType()); + return ModernSpawnEggs.getSpawnEggType(this.getType()); } @@ -32,15 +32,4 @@ public static ItemMeta create(Material type, NBTTagCompound tag) { stack.setTag(Preconditions.checkNotNull(tag, "Null nbt tag")); return CraftItemStack.getItemMeta(stack); } - - public static NBTTagCompound getTagFromMeta(Material type, ItemMeta meta) { - Preconditions.checkNotNull(meta, "Null meta"); - Preconditions.checkNotNull(type, "Null type"); - Preconditions.checkArgument(Bukkit.getItemFactory().isApplicable(meta, type), "Meta %s isn't applicable to %s", meta, type); - Item item = CraftMagicNumbers.getItem(type); - ItemStack stack = new ItemStack(item); - boolean worked = CraftItemStack.setItemMeta(stack, meta); - if (!worked) throw new RuntimeException("Didn't work"); - return stack.getTag(); - } } From 6be16522c1c4e5a7c19ce636c54cac807ae50488 Mon Sep 17 00:00:00 2001 From: Techcable Date: Tue, 16 Oct 2018 10:22:56 -0700 Subject: [PATCH 3/8] Introduce a wrapper for Bukkit's new BlockData API Eventually this will make things simpler, but for now.... --- .../techcable/sonarpet/block/BlockData.java | 36 ++++++ .../sonarpet/block/BlockDataFactory.java | 21 ++++ .../sonarpet/block/LegacyBlockData.java | 21 ++++ .../block/LegacyBlockDataFactory.java | 106 ++++++++++++++++++ .../sonarpet/block/ModernBlockData.java | 42 +++++++ .../block/ModernBlockDataFactory.java | 85 ++++++++++++++ .../sonarpet/block/ParsedLegacyData.java | 19 ++++ .../techcable/sonarpet/nms/IModernNMS.java | 14 +++ .../java/net/techcable/sonarpet/nms/INMS.java | 18 +-- .../nms/versions/v1_13_R2/NMSImpl.java | 52 ++++++++- 10 files changed, 405 insertions(+), 9 deletions(-) create mode 100644 api/src/main/java/net/techcable/sonarpet/block/BlockData.java create mode 100644 api/src/main/java/net/techcable/sonarpet/block/BlockDataFactory.java create mode 100644 api/src/main/java/net/techcable/sonarpet/block/LegacyBlockData.java create mode 100644 api/src/main/java/net/techcable/sonarpet/block/LegacyBlockDataFactory.java create mode 100644 api/src/main/java/net/techcable/sonarpet/block/ModernBlockData.java create mode 100644 api/src/main/java/net/techcable/sonarpet/block/ModernBlockDataFactory.java create mode 100644 api/src/main/java/net/techcable/sonarpet/block/ParsedLegacyData.java create mode 100644 api/src/main/java/net/techcable/sonarpet/nms/IModernNMS.java diff --git a/api/src/main/java/net/techcable/sonarpet/block/BlockData.java b/api/src/main/java/net/techcable/sonarpet/block/BlockData.java new file mode 100644 index 00000000..12ee0bfa --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/block/BlockData.java @@ -0,0 +1,36 @@ +package net.techcable.sonarpet.block; + +import org.bukkit.Material; + +/** + * A facade around the modern `BlockData` interface, + * in order to ensure backwards compatibility. + */ +public interface BlockData { + Material getMaterial(); + String getAsString(); + static BlockData createBlockData(Material m) { + return BlockDataFactory.getInstance().createBlockData(m); + } + static BlockData parseBlockData(String s) { + return BlockDataFactory.getInstance().parseBlockData(s); + } + + /** + * Parse the sepcified block data 'leniently', + * making a decent attempt to convert from legacy data. + * + * @param s the data to parse + * @throws IllegalArgumentException if the data is invalid + * @return the resulting block data + */ + static BlockData parseLeniently(String s) { + return BlockDataFactory.getInstance().parseLeniently(s); + } + static BlockData fromLegacyData(String materialName, byte data) { + return BlockDataFactory.getInstance().fromLegacyData(materialName, data); + } + static BlockData fromLegacyData(Material m, byte data) { + return BlockDataFactory.getInstance().fromLegacyData(m, data); + } +} diff --git a/api/src/main/java/net/techcable/sonarpet/block/BlockDataFactory.java b/api/src/main/java/net/techcable/sonarpet/block/BlockDataFactory.java new file mode 100644 index 00000000..77e2e50b --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/block/BlockDataFactory.java @@ -0,0 +1,21 @@ +package net.techcable.sonarpet.block; + +import net.techcable.sonarpet.utils.NmsVersion; +import org.bukkit.Material; + +public interface BlockDataFactory { + BlockData createBlockData(Material m); + BlockData createBlockData(Material m, String data); + BlockData parseBlockData(String s); + static BlockDataFactory getInstance() { + if (NmsVersion.current().isAtLeast(NmsVersion.v1_13_R2)) { + return new ModernBlockDataFactory(); + } else { + return new LegacyBlockDataFactory(); + } + } + BlockData parseLeniently(String s); + BlockData fromLegacyData(int id, byte data); + BlockData fromLegacyData(String materialName, byte data); + BlockData fromLegacyData(Material m, byte data); +} diff --git a/api/src/main/java/net/techcable/sonarpet/block/LegacyBlockData.java b/api/src/main/java/net/techcable/sonarpet/block/LegacyBlockData.java new file mode 100644 index 00000000..e580dd98 --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/block/LegacyBlockData.java @@ -0,0 +1,21 @@ +package net.techcable.sonarpet.block; + +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import org.bukkit.Material; +import org.bukkit.material.MaterialData; + +@RequiredArgsConstructor(access = AccessLevel.PACKAGE) +public class LegacyBlockData implements BlockData { + private final MaterialData materialData; + + @Override + public Material getMaterial() { + return materialData.getItemType(); + } + + @Override + public String getAsString() { + return "legacy[" + materialData.getItemType().name() + ":" + materialData.getData() + "]"; + } +} diff --git a/api/src/main/java/net/techcable/sonarpet/block/LegacyBlockDataFactory.java b/api/src/main/java/net/techcable/sonarpet/block/LegacyBlockDataFactory.java new file mode 100644 index 00000000..c3409de2 --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/block/LegacyBlockDataFactory.java @@ -0,0 +1,106 @@ +package net.techcable.sonarpet.block; + +import com.google.common.base.Preconditions; +import lombok.SneakyThrows; +import net.techcable.pineapple.reflection.Reflection; +import net.techcable.sonarpet.utils.NmsVersion; +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.material.MaterialData; + +import javax.annotation.Nullable; +import java.lang.invoke.MethodHandle; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class LegacyBlockDataFactory implements BlockDataFactory { + /* package */ LegacyBlockDataFactory() { + NmsVersion.ensureBefore(NmsVersion.v1_13_R2); + } + + @Override + public BlockData createBlockData(Material m) { + return new LegacyBlockData(m.getNewData((byte) 0)); + } + + @Override + public BlockData createBlockData(Material m, String data) { + Preconditions.checkNotNull(m, "Null material"); + Preconditions.checkNotNull(data, "Null data"); + ParsedLegacyData parsed = parseLegacyData(data); + Preconditions.checkArgument( + parsed.getType() == m, + "Expected type %s for data %s", + m, data + ); + return new LegacyBlockData(parsed.toLegacyMaterialData()); + } + + @Override + public BlockData parseBlockData(String s) { + return new LegacyBlockData(parseLegacyData(s).toLegacyMaterialData()); + } + + @Override + public BlockData parseLeniently(String s) { + // we do **not* handle data from future versions, so nothing special to do + return parseBlockData(s); + } + + @Override + public BlockData fromLegacyData(int id, byte data) { + Material material = Material.getMaterial(id); + if (material == null) { + throw new IllegalArgumentException("Invalid material id: " + id); + } + return fromLegacyData(material, data); + } + + @Override + public BlockData fromLegacyData(String materialName, byte data) { + Material material = Material.getMaterial(materialName); + if (material == null) { + throw new IllegalArgumentException("Invalid material name: " + materialName); + } + return fromLegacyData(material, data); + } + + @Override + public BlockData fromLegacyData(Material m, byte data) { + return new LegacyBlockData(m.getNewData(data)); + } + + private static final Pattern LEGACY_DATA_PATTERN = Pattern + .compile("legacy\\[(\\w+)(?::(\\d+))?]"); + public static boolean isLegacyData(String data) { + return LEGACY_DATA_PATTERN.matcher(data).matches(); + } + public static ParsedLegacyData parseLegacyData(String data) { + Preconditions.checkNotNull(data, "Null data"); + Matcher matcher = LEGACY_DATA_PATTERN.matcher(data); + String materialName = matcher.group(1); + Material material = Material.getMaterial(materialName); + if (material == null) { + throw new IllegalArgumentException( + "Invalid material " + materialName + + " for legacy data: " + data + ); + } + String legacyDataStr = matcher.group(2); + final byte legacyData; + if (legacyDataStr != null) { + try { + legacyData = Byte.parseByte(legacyDataStr); + } catch (NumberFormatException e) { + throw new IllegalArgumentException( + "Invalid legacyData " + legacyDataStr + + " for legeacy data: " + data, + e + ); + } + } else { + legacyData = 0; + } + return new ParsedLegacyData(material, legacyData); + } +} diff --git a/api/src/main/java/net/techcable/sonarpet/block/ModernBlockData.java b/api/src/main/java/net/techcable/sonarpet/block/ModernBlockData.java new file mode 100644 index 00000000..23a8a0d0 --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/block/ModernBlockData.java @@ -0,0 +1,42 @@ +package net.techcable.sonarpet.block; + +import com.google.common.base.Preconditions; +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import net.techcable.pineapple.reflection.Reflection; +import org.bukkit.Material; + +import java.lang.invoke.MethodHandle; +import java.util.Objects; + +public final class ModernBlockData implements BlockData { + private final Object handle; + /* package */ ModernBlockData(Object handle) { + Preconditions.checkNotNull(handle); + this.handle = BLOCK_DATA_CLASS.cast(handle); + } + + @Override + @SneakyThrows + public Material getMaterial() { + return (Material) GET_MATERIAL.invoke(handle); + } + + @Override + @SneakyThrows + public String getAsString() { + return (String) GET_AS_STRING.invoke(this.handle); + } + + private static final Class BLOCK_DATA_CLASS = Objects.requireNonNull( + Reflection.getClass("org.bukkit.block.data.BlockData")); + private static final MethodHandle GET_MATERIAL = Reflection.getMethod( + BLOCK_DATA_CLASS, + "getMaterial" + ); + private static final MethodHandle GET_AS_STRING = Reflection.getMethod( + BLOCK_DATA_CLASS, + "getString" + ); +} diff --git a/api/src/main/java/net/techcable/sonarpet/block/ModernBlockDataFactory.java b/api/src/main/java/net/techcable/sonarpet/block/ModernBlockDataFactory.java new file mode 100644 index 00000000..5c79c18d --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/block/ModernBlockDataFactory.java @@ -0,0 +1,85 @@ +package net.techcable.sonarpet.block; + +import lombok.SneakyThrows; +import net.techcable.pineapple.reflection.Reflection; +import net.techcable.sonarpet.nms.IModernNMS; +import net.techcable.sonarpet.nms.INMS; +import net.techcable.sonarpet.utils.NmsVersion; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Server; + +import java.lang.invoke.MethodHandle; + +public class ModernBlockDataFactory implements BlockDataFactory { + /* package */ ModernBlockDataFactory() { + NmsVersion.ensureAtLeast(NmsVersion.v1_13_R2); + } + + @Override + @SneakyThrows + public BlockData createBlockData(Material m) { + return new ModernBlockData(CREATE_BLOCK_DATA_MATERIAL.invoke(m)); + } + + @Override + @SneakyThrows + public BlockData createBlockData(Material m, String data) { + return new ModernBlockData(CREATE_BLOCK_DATA_MATERIAL_STRING.invoke(m, data)); + } + + @Override + @SneakyThrows + public BlockData parseBlockData(String s) { + return new ModernBlockData(CREATE_BLOCK_DATA_STRING.invoke(s)); + } + + @Override + public BlockData parseLeniently(String s) { + if (LegacyBlockDataFactory.isLegacyData(s)) { + ParsedLegacyData parsed = LegacyBlockDataFactory.parseLegacyData(s); + return fromLegacyData(parsed.getType(), parsed.getData()); + } else { + return parseBlockData(s); + } + } + + @Override + public BlockData fromLegacyData(int id, byte data) { + Material m = IModernNMS.getInstance().getMaterialByLegacyId(id); + return fromLegacyData(m, data); + } + + @Override + public BlockData fromLegacyData(String materialName, byte data) { + Material m = Material.getMaterial("LEGACY_" + materialName); + if (m == null) { + throw new IllegalArgumentException("Invalid material name: " + materialName); + } + return fromLegacyData(m, data); + } + + @Override + public BlockData fromLegacyData(Material m, byte data) { + return new ModernBlockData(IModernNMS.getInstance().getBukkitBlockData(m, data)); + } + + private static final MethodHandle CREATE_BLOCK_DATA_STRING = Reflection.getMethod( + Server.class, + "createBlockData", + String.class + ); + + private static final MethodHandle CREATE_BLOCK_DATA_MATERIAL = Reflection.getMethod( + Server.class, + "createBlockData", + Material.class + ); + + private static final MethodHandle CREATE_BLOCK_DATA_MATERIAL_STRING = Reflection.getMethod( + Server.class, + "createBlockData", + Material.class, + String.class + ); +} diff --git a/api/src/main/java/net/techcable/sonarpet/block/ParsedLegacyData.java b/api/src/main/java/net/techcable/sonarpet/block/ParsedLegacyData.java new file mode 100644 index 00000000..e7cafa73 --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/block/ParsedLegacyData.java @@ -0,0 +1,19 @@ +package net.techcable.sonarpet.block; + +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.bukkit.Material; +import org.bukkit.material.MaterialData; + +@RequiredArgsConstructor +@Getter +/* package */ class ParsedLegacyData { + @NonNull + private final Material type; + private final byte data; + + public MaterialData toLegacyMaterialData() { + return type.getNewData(this.data); + } +} diff --git a/api/src/main/java/net/techcable/sonarpet/nms/IModernNMS.java b/api/src/main/java/net/techcable/sonarpet/nms/IModernNMS.java new file mode 100644 index 00000000..e731e72d --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/nms/IModernNMS.java @@ -0,0 +1,14 @@ +package net.techcable.sonarpet.nms; + +import net.techcable.sonarpet.utils.NmsVersion; +import org.bukkit.Material; + +public interface IModernNMS extends INMS { + NmsVersion MINIMUM_VERSION = NmsVersion.v1_13_R2; + Material getMaterialByLegacyId(int id); + Object getBukkitBlockData(Material m, byte b); + static IModernNMS getInstance() { + NmsVersion.ensureAtLeast(MINIMUM_VERSION); + return (IModernNMS) INMS.getInstance(); + } +} diff --git a/api/src/main/java/net/techcable/sonarpet/nms/INMS.java b/api/src/main/java/net/techcable/sonarpet/nms/INMS.java index 00dfdd57..15f87ab0 100644 --- a/api/src/main/java/net/techcable/sonarpet/nms/INMS.java +++ b/api/src/main/java/net/techcable/sonarpet/nms/INMS.java @@ -17,20 +17,13 @@ package net.techcable.sonarpet.nms; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; - import com.dsh105.echopet.compat.api.plugin.IEchoPetPlugin; import com.google.common.base.Preconditions; - -import net.techcable.pineapple.reflection.PineappleField; import net.techcable.pineapple.reflection.Reflection; import net.techcable.sonarpet.item.SpawnEggItemData; import net.techcable.sonarpet.utils.ModernSpawnEggs; import net.techcable.sonarpet.utils.NmsVersion; import net.techcable.sonarpet.utils.Versioning; - import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Sound; @@ -40,7 +33,12 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.material.SpawnEgg; -import static net.techcable.sonarpet.utils.Versioning.*; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +import static net.techcable.sonarpet.utils.Versioning.NMS_VERSION; +import static net.techcable.sonarpet.utils.Versioning.NMS_VERSION_STRING; @SuppressWarnings("deprecation") public interface INMS { @@ -139,5 +137,9 @@ class Helper { throw new AssertionError("NMS constructor threw exception", t); } } + if (NmsVersion.current().isAtLeast(IModernNMS.MINIMUM_VERSION) + && !(instance instanceof IModernNMS)) { + throw new RuntimeException("NMSImpl for " + NMS_VERSION_STRING + " should implement IModernNMS"); + } } } diff --git a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSImpl.java b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSImpl.java index a42e522e..56ca4ec3 100644 --- a/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSImpl.java +++ b/nms/v1_13_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_13_R2/NMSImpl.java @@ -1,8 +1,11 @@ package net.techcable.sonarpet.nms.versions.v1_13_R2; +import com.google.common.base.Preconditions; +import lombok.SneakyThrows; import net.minecraft.server.v1_13_R2.*; import net.minecraft.server.v1_13_R2.DamageSource; import net.techcable.pineapple.reflection.PineappleField; +import net.techcable.pineapple.reflection.Reflection; import net.techcable.sonarpet.item.ItemData; import net.techcable.sonarpet.item.SpawnEggItemData; import net.techcable.sonarpet.nms.*; @@ -15,16 +18,22 @@ import org.bukkit.craftbukkit.v1_13_R2.block.data.CraftBlockData; import org.bukkit.craftbukkit.v1_13_R2.entity.CraftEntity; import org.bukkit.craftbukkit.v1_13_R2.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.v1_13_R2.util.CraftLegacy; +import org.bukkit.craftbukkit.v1_13_R2.util.CraftMagicNumbers; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.inventory.meta.ItemMeta; +import java.lang.invoke.MethodHandle; +import java.util.Arrays; +import java.util.HashMap; + import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -public class NMSImpl implements INMS { +public class NMSImpl implements INMS, IModernNMS { @Override public SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta) { checkNotNull(entityType, "Null entity type"); @@ -122,4 +131,45 @@ public EntityRegistry createDefaultEntityRegistry() { public NMSSound getNmsSound(Sound bukkitSound) { return new NMSSoundImpl(NMSSoundImplKt.getSoundEffect(bukkitSound)); } + + // The isLegacy methods seems to be hidden from us somehow + private static final MethodHandle MATERIAL_IS_LEGACY_METHOD = Reflection.getMethod( + Material.class, + "isLegacy" + ); + @SneakyThrows + private static boolean isLegacy(Material m) { + return (boolean) MATERIAL_IS_LEGACY_METHOD.invokeExact(m); + } + // Looks like this is the best way to do it :( + private static final Material[] LEGACY_MATERIAL_BY_ID; + static { + Material[] byId = new Material[256]; + int maxId = 0; + for (Material m : CraftLegacy.values()) { + if (!isLegacy(m)) continue; + int id = m.getId(); + if (id >= byId.length){ + byId = Arrays.copyOf(byId, id + 128); + } + maxId = Math.max(id, maxId); + } + LEGACY_MATERIAL_BY_ID = Arrays.copyOf(byId, maxId + 1); + } + @Override + public Material getMaterialByLegacyId(int id) { + if (id < LEGACY_MATERIAL_BY_ID.length) { + Material m = LEGACY_MATERIAL_BY_ID[id]; + if (m != null) { + return CraftLegacy.fromLegacy(m); + } + } + throw new IllegalArgumentException("Invalid id: " + id); + } + + @Override + public Object getBukkitBlockData(Material m, byte b) { + IBlockData data = Block.getByCombinedId((m.getId() << 4) | (int) b); + return CraftBlockData.fromData(data); + } } From 8c26ec7ec7d15c96e7a0f2886828977f7bedc982 Mon Sep 17 00:00:00 2001 From: Techcable Date: Wed, 10 Jun 2020 11:10:54 -0700 Subject: [PATCH 4/8] [EXTEREMLY OLD (~2 years)] Attempt to abstract away all the changes to item data APIs This was my attempt - essentially requires rewriting the entire bukkit API from scratch then abstracting over the differences between different (incompatible) versions......... Clearly legacy version support is a dead-end!!!!! --- .../compat/api/config/ConfigOptions.java | 1 - .../compat/api/util/menu/SelectorLayout.java | 19 +- .../sonarpet/block/BlockDataFactory.java | 2 + .../block/LegacyBlockDataFactory.java | 6 + .../block/ModernBlockDataFactory.java | 13 ++ .../techcable/sonarpet/item/DyeItemData.java | 27 +-- .../net/techcable/sonarpet/item/ItemData.java | 167 ++++-------------- .../sonarpet/item/ItemDataFactory.java | 36 ++++ .../sonarpet/item/LegacyMaterialSystem.java | 23 --- .../sonarpet/item/MaterialSystem.java | 22 --- .../sonarpet/item/ModernMaterialSystem.java | 101 ----------- .../sonarpet/item/SkullItemData.java | 107 ++--------- .../sonarpet/item/SpawnEggItemData.java | 19 +- .../sonarpet/item/StainedClayItemData.java | 28 +-- .../techcable/sonarpet/item/WoolItemData.java | 29 +-- .../item/legacy/BasicSerializedItem.java | 65 +++++++ .../item/legacy/LegacyDyeItemData.java | 32 ++++ .../sonarpet/item/legacy/LegacyItemData.java | 101 +++++++++++ .../item/legacy/LegacyItemDataFactory.java | 123 +++++++++++++ .../item/legacy/LegacySkullItemData.java | 97 ++++++++++ .../item/legacy/LegacySpawnEggItemData.java | 16 ++ .../legacy/LegacyStainedClayItemData.java | 30 ++++ .../item/legacy/LegacyWoolItemData.java | 31 ++++ .../java/net/techcable/sonarpet/nms/INMS.java | 34 +--- 24 files changed, 649 insertions(+), 480 deletions(-) create mode 100644 api/src/main/java/net/techcable/sonarpet/item/ItemDataFactory.java delete mode 100644 api/src/main/java/net/techcable/sonarpet/item/LegacyMaterialSystem.java delete mode 100644 api/src/main/java/net/techcable/sonarpet/item/MaterialSystem.java delete mode 100644 api/src/main/java/net/techcable/sonarpet/item/ModernMaterialSystem.java create mode 100644 api/src/main/java/net/techcable/sonarpet/item/legacy/BasicSerializedItem.java create mode 100644 api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyDyeItemData.java create mode 100644 api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyItemData.java create mode 100644 api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyItemDataFactory.java create mode 100644 api/src/main/java/net/techcable/sonarpet/item/legacy/LegacySkullItemData.java create mode 100644 api/src/main/java/net/techcable/sonarpet/item/legacy/LegacySpawnEggItemData.java create mode 100644 api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyStainedClayItemData.java create mode 100644 api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyWoolItemData.java diff --git a/api/src/main/java/com/dsh105/echopet/compat/api/config/ConfigOptions.java b/api/src/main/java/com/dsh105/echopet/compat/api/config/ConfigOptions.java index d0312eef..8076aa6f 100644 --- a/api/src/main/java/com/dsh105/echopet/compat/api/config/ConfigOptions.java +++ b/api/src/main/java/com/dsh105/echopet/compat/api/config/ConfigOptions.java @@ -23,7 +23,6 @@ import com.dsh105.echopet.compat.api.entity.PetType; import com.dsh105.echopet.compat.api.util.menu.SelectorIcon; import com.dsh105.echopet.compat.api.util.menu.SelectorLayout; -import net.techcable.sonarpet.item.MaterialSystem; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; diff --git a/api/src/main/java/com/dsh105/echopet/compat/api/util/menu/SelectorLayout.java b/api/src/main/java/com/dsh105/echopet/compat/api/util/menu/SelectorLayout.java index dccbc116..814de77a 100644 --- a/api/src/main/java/com/dsh105/echopet/compat/api/util/menu/SelectorLayout.java +++ b/api/src/main/java/com/dsh105/echopet/compat/api/util/menu/SelectorLayout.java @@ -22,9 +22,7 @@ import com.dsh105.echopet.compat.api.config.ConfigOptions; import com.dsh105.echopet.compat.api.config.PetItem; import com.dsh105.echopet.compat.api.entity.PetType; -import com.google.common.collect.ImmutableList; - -import net.techcable.sonarpet.item.MaterialSystem; +import net.techcable.sonarpet.item.ItemData; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.event.HandlerList; @@ -36,8 +34,6 @@ import java.util.List; import java.util.Optional; -import net.techcable.sonarpet.item.ItemData; - public class SelectorLayout { private static ArrayList selectorLayout = new ArrayList(); @@ -84,9 +80,16 @@ public static void loadLayout() { if (petType != null && GeneralUtil.isEnumType(PetType.class, petType.toUpperCase())) { pt = PetType.valueOf(petType.toUpperCase()); } - // TODO: Convert from legacy ids - ItemData basicData = MaterialSystem.getInstance().parseData( - config.getString(s + ".slot-" + i + ".material")); + String serializedData = config.getInt(); + if (serializedData != null) { + /* + * Always prefer using the new system of serialization. + * It will gracefully ends our dependence on material ids + * once we update to 1.13 + */ + } + int id = config.getInt(s + ".slot-" + i + ".materialId"); + int data = config.getInt(s + ".slot-" + i + ".materialData"); String name = config.getString(s + ".slot-" + i + ".name"); if (name == null) { continue; diff --git a/api/src/main/java/net/techcable/sonarpet/block/BlockDataFactory.java b/api/src/main/java/net/techcable/sonarpet/block/BlockDataFactory.java index 77e2e50b..ab76418d 100644 --- a/api/src/main/java/net/techcable/sonarpet/block/BlockDataFactory.java +++ b/api/src/main/java/net/techcable/sonarpet/block/BlockDataFactory.java @@ -2,11 +2,13 @@ import net.techcable.sonarpet.utils.NmsVersion; import org.bukkit.Material; +import org.bukkit.block.BlockState; public interface BlockDataFactory { BlockData createBlockData(Material m); BlockData createBlockData(Material m, String data); BlockData parseBlockData(String s); + static BlockDataFactory getInstance() { if (NmsVersion.current().isAtLeast(NmsVersion.v1_13_R2)) { return new ModernBlockDataFactory(); diff --git a/api/src/main/java/net/techcable/sonarpet/block/LegacyBlockDataFactory.java b/api/src/main/java/net/techcable/sonarpet/block/LegacyBlockDataFactory.java index c3409de2..98c1ce92 100644 --- a/api/src/main/java/net/techcable/sonarpet/block/LegacyBlockDataFactory.java +++ b/api/src/main/java/net/techcable/sonarpet/block/LegacyBlockDataFactory.java @@ -6,6 +6,7 @@ import net.techcable.sonarpet.utils.NmsVersion; import org.bukkit.Material; import org.bukkit.Server; +import org.bukkit.block.BlockState; import org.bukkit.material.MaterialData; import javax.annotation.Nullable; @@ -41,6 +42,11 @@ public BlockData parseBlockData(String s) { return new LegacyBlockData(parseLegacyData(s).toLegacyMaterialData()); } + @Override + public BlockData fromState(BlockState state) { + return new LegacyBlockData(state.getData()); + } + @Override public BlockData parseLeniently(String s) { // we do **not* handle data from future versions, so nothing special to do diff --git a/api/src/main/java/net/techcable/sonarpet/block/ModernBlockDataFactory.java b/api/src/main/java/net/techcable/sonarpet/block/ModernBlockDataFactory.java index 5c79c18d..2fc2c551 100644 --- a/api/src/main/java/net/techcable/sonarpet/block/ModernBlockDataFactory.java +++ b/api/src/main/java/net/techcable/sonarpet/block/ModernBlockDataFactory.java @@ -8,6 +8,7 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Server; +import org.bukkit.block.BlockState; import java.lang.invoke.MethodHandle; @@ -34,6 +35,13 @@ public BlockData parseBlockData(String s) { return new ModernBlockData(CREATE_BLOCK_DATA_STRING.invoke(s)); } + + @Override + @SneakyThrows + public BlockData fromState(BlockState state) { + return new ModernBlockData(BLOCK_STATE_GET_DATA.invoke(state)); + } + @Override public BlockData parseLeniently(String s) { if (LegacyBlockDataFactory.isLegacyData(s)) { @@ -82,4 +90,9 @@ public BlockData fromLegacyData(Material m, byte data) { Material.class, String.class ); + + private static final MethodHandle BLOCK_STATE_GET_DATA = Reflection.getMethod( + BlockState.class, + "getBlockData" + ); } diff --git a/api/src/main/java/net/techcable/sonarpet/item/DyeItemData.java b/api/src/main/java/net/techcable/sonarpet/item/DyeItemData.java index 872639c5..dd7e6323 100644 --- a/api/src/main/java/net/techcable/sonarpet/item/DyeItemData.java +++ b/api/src/main/java/net/techcable/sonarpet/item/DyeItemData.java @@ -7,31 +7,16 @@ import org.bukkit.Material; import org.bukkit.inventory.meta.ItemMeta; -public class DyeItemData extends ItemData implements ColoredItemData { +public interface DyeItemData extends ItemData, ColoredItemData { + DyeColor getColor(); - protected DyeItemData(byte rawData, ItemMeta meta) { - super(Material.INK_SACK, rawData, meta); - } - - @SuppressWarnings("deprecation") - public DyeColor getColor() { - return DyeColor.getByDyeData(getRawData()); - } - - @SuppressWarnings("deprecation") - public DyeItemData withColor(DyeColor color) { - return withRawData(Preconditions.checkNotNull(color, "Null color").getDyeData()); - } - - public DyeItemData withRawData(int rawData) { - return (DyeItemData) super.withRawData(rawData); - } + DyeItemData withColor(DyeColor color); - public static DyeItemData create(DyeColor color) { + static DyeItemData create(DyeColor color) { return create(color, Bukkit.getItemFactory().getItemMeta(Material.INK_SACK)); } - public static DyeItemData create(DyeColor color, ItemMeta meta) { - return new DyeItemData(Preconditions.checkNotNull(color, "Null color").getDyeData(), meta); + static DyeItemData create(DyeColor color, ItemMeta meta) { + return ItemDataFactory.getInstance().createDye(color, meta); } } diff --git a/api/src/main/java/net/techcable/sonarpet/item/ItemData.java b/api/src/main/java/net/techcable/sonarpet/item/ItemData.java index cc6d809c..11d06105 100644 --- a/api/src/main/java/net/techcable/sonarpet/item/ItemData.java +++ b/api/src/main/java/net/techcable/sonarpet/item/ItemData.java @@ -1,170 +1,77 @@ package net.techcable.sonarpet.item; -import lombok.*; - -import java.util.List; -import java.util.Optional; - -import net.techcable.sonarpet.item.ModernMaterialSystem; -import net.techcable.sonarpet.nms.INMS; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; - -import net.techcable.sonarpet.utils.ModernSpawnEggs; -import net.techcable.sonarpet.utils.NmsVersion; +import net.techcable.sonarpet.block.BlockData; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.BlockStateMeta; import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.material.MaterialData; -import org.bukkit.material.MonsterEggs; - -@Getter -public class ItemData { - @NonNull - private final Material type; - private final byte rawData; - @Getter(AccessLevel.NONE) // Doesn't make a defensive copy, which is nessicary as it is mutable - private final ItemMeta meta; - - protected ItemData(Material type, byte rawData, ItemMeta meta) { - this.type = Preconditions.checkNotNull(type, "Null type"); - this.rawData = rawData; - Preconditions.checkNotNull(meta, "Null metadata"); - this.meta = Bukkit.getItemFactory().asMetaFor(meta, type).clone(); // Not guarnteed to copy ;) - } - public static ItemData create(MaterialData materialData) { - Preconditions.checkNotNull(materialData, "Null material data"); - return create(materialData.getItemType(), materialData.getData()); - } - - - public static ItemData create(MaterialData materialData, ItemMeta meta) { - Preconditions.checkNotNull(materialData, "Null material data"); - return create(materialData.getItemType(), materialData.getData(), meta); - } - - public static ItemData create(Material type) { - return create(type, 0); - } +import javax.annotation.Nullable; +import java.util.List; +import java.util.Optional; - public static ItemData create(Material type, ItemMeta meta) { - return create(type, 0, meta); - } +public interface ItemData { + Material getType(); + ItemMeta getMeta(); - public static ItemData create(Material type, int rawData) { - Preconditions.checkNotNull(type, "Null type"); - return create(type, rawData, Bukkit.getItemFactory().getItemMeta(type)); - } + /** + * Serialize this ItemData into a string, + * which can be deserialized by {@link ItemDataFactory#parseFromString(String)}. + * + * This is not guarenteed to preserve all the items properties + * and is only 'best-effort'. + * + * @return the serialized string + */ + String serializeAsString(); - public static ItemData create(Material type, int rawData, ItemMeta meta) { - Preconditions.checkNotNull(type, "Null type"); - Preconditions.checkArgument((byte) rawData == rawData, "Raw data doesn't fit in byte: %s", rawData); - Preconditions.checkNotNull(meta, "Null item meta"); - if (ModernSpawnEggs.isSupported()) { - if (ModernSpawnEggs.isSpawnEgg(type)) { - return INMS.getInstance().createSpawnEggData(type, (byte) rawData, meta); - } - } else { - // We're on an older version, where there is only one type of monster egg - if (type == Material.MONSTER_EGG) { - return INMS.getInstance().createSpawnEggData(type, (byte) rawData, meta); - } - } - /* - * NOTE: I'm keeping Material.MONSTER_EGG out of the switch - * since it's deprecated on 1.13. - * It'll now be conditional on whether we have 'modern' monster egg support - * Furthermore we have to switch on the raw string, - * since bukkit does some crazy madness with the ordinal. - */ - switch (type.name()) { - case "INK_SACK": - return new DyeItemData((byte) rawData, meta); - case "SKULL_ITEM": - return new SkullItemData((byte) rawData, meta); - case "STAINED_CLAY": - return new StainedClayItemData((byte) rawData, meta); - case "WOOL": - return new StainedClayItemData((byte) rawData, meta); - default: - return new ItemData(type, (byte) rawData, meta); - } - } + ItemDataFactory getFactory(); - public ItemData withRawData(int rawData) { - Preconditions.checkArgument((byte) rawData == rawData, "Raw data doesn't fit into byte: %s", rawData); - return ItemData.create(this.type, rawData, this.meta); + static ItemData create(Material type) { + return create(type, Bukkit.getItemFactory().getItemMeta(type)); } - public ItemData withMeta(ItemMeta meta) { - Preconditions.checkNotNull(meta, "Null metadata"); - return meta.equals(this.meta) ? this : create(getType(), getRawData(), meta); + static ItemData create(Material type, ItemMeta meta) { + return ItemDataFactory.getInstance().create(type, meta); } - public ItemData withPlainMeta() { - return create(getType(), getRawData()); - } + ItemData withMeta(ItemMeta meta); - public ItemMeta getMeta() { - return meta.clone(); - } + ItemData withPlainMeta(); - public ImmutableList getLore() { - if (meta.hasLore()) { - return ImmutableList.copyOf(meta.getLore()); + default ImmutableList getLore() { + if (getMeta().hasLore()) { + return ImmutableList.copyOf(getMeta().getLore()); } else { return ImmutableList.of(); } } - public Optional getDisplayName() { - return meta.hasDisplayName() ? Optional.of(meta.getDisplayName()) : Optional.empty(); + default Optional getDisplayName() { + return getMeta().hasDisplayName() ? Optional.of(getMeta().getDisplayName()) : Optional.empty(); } - public ItemData withDisplayName(Optional name) { - Preconditions.checkNotNull(name, "Null optional"); + default ItemData withDisplayName(@Nullable String name) { ItemMeta meta = getMeta(); // Returns a copy ;) - if (name.isPresent()) { - Preconditions.checkArgument(!name.get().trim().isEmpty(), "Empty name '%s'", name.get()); - meta.setDisplayName(name.get()); + if (name != null) { + Preconditions.checkArgument(!name.trim().isEmpty(), "Empty name '%s'", name); + meta.setDisplayName(name); } else { meta.setDisplayName(null); // Undocumented behavior of awesomeness } return withMeta(meta); } - public ItemData withDisplayName(String name) { - return withDisplayName(Optional.of(Preconditions.checkNotNull(name, "Null name"))); - } - - public ItemData withLore(List lore) { + default ItemData withLore(List lore) { ItemMeta meta = getMeta(); // Returns a copy ;) meta.setLore(ImmutableList.copyOf(lore)); // Copy lore :D return withMeta(meta); } - public ItemStack createStack(int amount) { - ItemStack stack = new ItemStack(getType(), amount, getRawData()); - stack.setItemMeta(this.meta.clone()); - return stack; - } - - public MaterialData getLegacyMaterialData() { - NmsVersion.ensureBefore(NmsVersion.v1_13_R2); - return this.type.getNewData(this.rawData); - } + ItemStack createStack(int amount); - public Object getModernBlockData() { - NmsVersion.ensureAtLeast(NmsVersion.v1_13_R2); - if (this.meta instanceof BlockStateMeta) { - return ModernMaterialSystem.getDataFromState( - ((BlockStateMeta) this.meta).getBlockState() - ); - } else { - return ModernMaterialSystem.createDefaultBlockData(this.type); - } - } + @Nullable + BlockData getBlockData(); } diff --git a/api/src/main/java/net/techcable/sonarpet/item/ItemDataFactory.java b/api/src/main/java/net/techcable/sonarpet/item/ItemDataFactory.java new file mode 100644 index 00000000..a2e4611f --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/item/ItemDataFactory.java @@ -0,0 +1,36 @@ +package net.techcable.sonarpet.item; + +import net.techcable.sonarpet.nms.INMS; +import net.techcable.sonarpet.utils.ModernSpawnEggs; +import net.techcable.sonarpet.utils.PlayerProfile; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.material.SpawnEgg; + +public interface ItemDataFactory { + ItemData create(Material type, ItemMeta meta); + + DyeItemData createDye(DyeColor color, ItemMeta meta); + StainedClayItemData createStainedClay(DyeColor color, ItemMeta meta); + WoolItemData createWool(DyeColor color, ItemMeta meta); + + /** + * Parse an `ItemData` from its serialized string form. + * This is the deserializer counterpart to {@link ItemData#serializeAsString()} + * + * @param s the serialized string to parse + * @throws IllegalArgumentException if the data is invalid + * @return the deserialized data + */ + ItemData parseFromString(String s); + + static ItemDataFactory getInstance() { + return INMS.getInstance().getItemDataFactory(); + } + + SkullItemData createHumanSkull(PlayerProfile owner, ItemMeta rawData); + SkullItemData createSkull(SkullItemData.SkullType skullType, ItemMeta rawData); + SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta); +} diff --git a/api/src/main/java/net/techcable/sonarpet/item/LegacyMaterialSystem.java b/api/src/main/java/net/techcable/sonarpet/item/LegacyMaterialSystem.java deleted file mode 100644 index 6b1c65bc..00000000 --- a/api/src/main/java/net/techcable/sonarpet/item/LegacyMaterialSystem.java +++ /dev/null @@ -1,23 +0,0 @@ -package net.techcable.sonarpet.item; - -public class LegacyMaterialSystem implements MaterialSystem { - @SuppressWarnings("deprecation") // this is legacy - @Override - public String serializeData(ItemData m) { - byte data = m.getLegacyMaterialData().getData(); - int id = m.getType().getId(); - return id + ":" + data; - } - - @Override - public ItemData parseData(String s) { - String[] parts = s.split(":"); - if (parts.length == 2) { - try { - int id = Integer.parseInt(parts[0]); - byte data = Byte.parseByte(parts[1]); - } catch (NumberFormatException ignored) {} - } - throw new IllegalArgumentException("Invalid item data: " + s); - } -} diff --git a/api/src/main/java/net/techcable/sonarpet/item/MaterialSystem.java b/api/src/main/java/net/techcable/sonarpet/item/MaterialSystem.java deleted file mode 100644 index 970de868..00000000 --- a/api/src/main/java/net/techcable/sonarpet/item/MaterialSystem.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.techcable.sonarpet.item; - -import net.techcable.sonarpet.utils.NmsVersion; - -/** - * Defines a system for interacting between `org.bukkit.Material`. - * - * This is necessary for the new and radical changes in 1.13. - */ -public interface MaterialSystem { - String serializeData(ItemData m); - - ItemData parseData(String s); - - static MaterialSystem getInstance() { - if (NmsVersion.current().isAtLeast(NmsVersion.v1_13_R2)) { - return new ModernMaterialSystem(); - } else { - return new LegacyMaterialSystem(); - } - } -} diff --git a/api/src/main/java/net/techcable/sonarpet/item/ModernMaterialSystem.java b/api/src/main/java/net/techcable/sonarpet/item/ModernMaterialSystem.java deleted file mode 100644 index 0d6f5674..00000000 --- a/api/src/main/java/net/techcable/sonarpet/item/ModernMaterialSystem.java +++ /dev/null @@ -1,101 +0,0 @@ -package net.techcable.sonarpet.item; - -import com.google.common.base.Preconditions; -import lombok.SneakyThrows; -import net.techcable.pineapple.reflection.Reflection; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.Server; -import org.bukkit.block.BlockState; -import org.bukkit.inventory.meta.BlockStateMeta; -import org.bukkit.inventory.meta.ItemMeta; - -import java.lang.invoke.MethodHandle; -import java.util.Objects; - -public class ModernMaterialSystem implements MaterialSystem { - @Override - @SneakyThrows - public String serializeData(ItemData m) { - if (m.getType().isBlock()) { - // Give them the whole block data - return (String) BLOCK_DATA_GET_AS_STRING.invoke(m.getModernBlockData()); - } else { - // Otherwise we just give them the material without any data - // This strips all information, but the bukkit API has no real alternative - // NOTE: Must use reflection in order to bypass the 1.13 compat hacks - return (String) MATERIAL_NAME.invoke(m.getType()); - } - } - - @Override - @SneakyThrows - public ItemData parseData(String s) { - Preconditions.checkNotNull(s, "Null data"); - { - Material m = (Material) MATERIAL_GET_MATERIAL.invokeExact(s); - if (m != null) { - // First we try just the material, in case it's an item - return ItemData.create(m); - } - } - Object data = SERVER_CREATE_BLOCK_DATA.invoke(Bukkit.getServer(), s); - Material m = (Material) BLOCK_DATA_GET_MATERIAL.invoke(data); - ItemMeta meta = Bukkit.getItemFactory().getItemMeta(m); - if (meta instanceof BlockStateMeta) { - // TODO: I think this should always be the case - // Really, we need to just make ItemData fully version-dependent on modern versions - BlockState state = ((BlockStateMeta) meta).getBlockState(); - BLOCK_STATE_SET_DATA.invoke(state, data); - } - return ItemData.create(m, meta); - } - - private static final Class BLOCK_DATA_CLASS = Objects.requireNonNull( - Reflection.getClass("org.bukkit.block.data.BlockData")); - private static final MethodHandle SERVER_CREATE_BLOCK_DATA = Reflection.getMethod( - Server.class, - "createBlockData", - String.class - ); - private static final MethodHandle BLOCK_DATA_GET_AS_STRING = Reflection.getMethod( - BLOCK_DATA_CLASS, - "getAsString" - ); - private static final MethodHandle BLOCK_DATA_GET_MATERIAL = Reflection.getMethod( - BLOCK_DATA_CLASS, - "getMaterial" - ); - private static final MethodHandle MATERIAL_CREATE_BLOCK_DATA = Reflection.getMethod( - Material.class, - "createBlockData" - ); - - private static final MethodHandle MATERIAL_NAME = Reflection.getMethod( - Enum.class, - "name" - ); - private static final MethodHandle MATERIAL_GET_MATERIAL = Reflection.getMethod( - Material.class, - "getMaterial", - String.class - ); - private static final MethodHandle BLOCK_STATE_GET_DATA = Reflection.getMethod( - BlockState.class, - "getBlockData" - ); - private static final MethodHandle BLOCK_STATE_SET_DATA = Reflection.getMethod( - BlockState.class, - "setBlockData", - BLOCK_DATA_CLASS - ); - - @SneakyThrows - public static Object createDefaultBlockData(Material m) { - return MATERIAL_CREATE_BLOCK_DATA.invoke(m); - } - @SneakyThrows - public static Object getDataFromState(BlockState state) { - return BLOCK_STATE_GET_DATA.invoke(state); - } -} diff --git a/api/src/main/java/net/techcable/sonarpet/item/SkullItemData.java b/api/src/main/java/net/techcable/sonarpet/item/SkullItemData.java index 85a621ff..398909ce 100644 --- a/api/src/main/java/net/techcable/sonarpet/item/SkullItemData.java +++ b/api/src/main/java/net/techcable/sonarpet/item/SkullItemData.java @@ -13,119 +13,50 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.SkullMeta; -public class SkullItemData extends ItemData { - private final PlayerProfile profile; - - public Optional getProfile() { - if (getSkullType() == SkullType.HUMAN_SKULL && getMeta().hasOwner()) { - String ownerName = getMeta().getOwner(); - Preconditions.checkState(profile.getName().equals(ownerName), "Profile %s doesn't match owner %s", profile, ownerName); - return Optional.of(profile); - } else { - Preconditions.checkState(profile == null, "Profile %s is present but meta has no owner", profile); - return Optional.empty(); - } - } +public interface SkullItemData extends ItemData { + Optional getProfile(); + SkullItemData withOwner(UUID owner); - protected SkullItemData(byte rawData, ItemMeta meta) { - this(rawData, meta, ((SkullMeta) meta).hasOwner() ? ProfileUtils.lookupOptimistically(((SkullMeta) meta).getOwner()) : null); - } + SkullItemData withOwner(String ownerName); - protected SkullItemData(byte rawData, ItemMeta meta, PlayerProfile profile) { - super(Material.SKULL_ITEM, rawData, meta); - Preconditions.checkArgument(profile == null || profile.getName().equals(((SkullMeta) meta).getOwner())); - this.profile = profile; - } + SkullItemData withOwner(PlayerProfile profile); - public SkullItemData withOwner(UUID owner) { - Preconditions.checkNotNull(owner, "Null owner uuid"); - if (getProfile().isPresent() && getProfile().get().getId().equals(owner)) { - return this; - } else { - return withOwner(ProfileUtils.lookupOptimistically(owner)); - } - } + Optional getOwner(); - public SkullItemData withOwner(String ownerName) { - Preconditions.checkNotNull(ownerName, "Null owner name"); - if (getProfile().isPresent() && getProfile().get().getName().equals(ownerName)) { - return this; - } else { - return withOwner(ProfileUtils.lookupOptimistically(ownerName)); - } - } + Optional getOwnerName(); - public SkullItemData withOwner(PlayerProfile profile) { - return profile.equals(this.profile) ? this : createHuman(profile, this.getMeta()); - } - - public Optional getOwner() { - return getProfile().map(PlayerProfile::getId); - } + boolean hasOwner(); - - public Optional getOwnerName() { - return getProfile().map(PlayerProfile::getName); - } - - public boolean hasOwner() { - return getProfile().isPresent(); - } - - public static SkullItemData createHuman() { + static SkullItemData createHuman() { return create(SkullType.HUMAN_SKULL); } - public static SkullItemData createHuman(PlayerProfile owner) { + static SkullItemData createHuman(PlayerProfile owner) { return createHuman(owner, Bukkit.getItemFactory().getItemMeta(Material.SKULL_ITEM)); } - public static SkullItemData createHuman(PlayerProfile owner, ItemMeta rawMeta) { - Preconditions.checkNotNull(rawMeta, "Null meta"); - Preconditions.checkNotNull(owner, "Null owner"); - SkullMeta meta; - if (rawMeta instanceof SkullMeta) { - meta = (SkullMeta) rawMeta; - } else { - meta = (SkullMeta) Bukkit.getItemFactory().asMetaFor(rawMeta, Material.SKULL_ITEM); - } - meta = meta.clone(); // Don't modify their junk - meta.setOwner(owner.getName()); - return create(SkullType.HUMAN_SKULL, meta); + static SkullItemData createHuman(PlayerProfile owner, ItemMeta rawMeta) { + return ItemDataFactory.getInstance().createHumanSkull(owner, rawMeta); } - public static SkullItemData create(SkullType type) { + static SkullItemData create(SkullType type) { return create(type, Bukkit.getItemFactory().getItemMeta(Material.SKULL_ITEM)); } - public static SkullItemData create(SkullType type, ItemMeta meta) { - return new SkullItemData(Preconditions.checkNotNull(type, "Null skull type").getId(), Preconditions.checkNotNull(meta, "Null meta")); + static SkullItemData create(SkullType type, ItemMeta meta) { + return ItemDataFactory.getInstance().createSkull(type, meta); } - public SkullType getSkullType() { - int data = getRawData(); - SkullType[] values = SkullType.values(); - if (data < 0) { - throw new IllegalStateException("Can't get skull type from negative data: " + data); - } else if (data >= values.length) { - throw new IllegalStateException("Can't get skull type from too large data: " + data); - } else { - return values[data]; - } - } + SkullType getSkullType(); - public ItemData withSkullType(SkullType type) { - return withRawData(Preconditions.checkNotNull(type, "Null type").ordinal()); - } + ItemData withSkullType(SkullType type); @Override - public SkullMeta getMeta() { - return (SkullMeta) super.getMeta(); - } + SkullMeta getMeta(); - public enum SkullType { + enum SkullType { SKELETON_SKULL, WITHER_SKELETON_SKULL, ZOMBIE_SKULL, diff --git a/api/src/main/java/net/techcable/sonarpet/item/SpawnEggItemData.java b/api/src/main/java/net/techcable/sonarpet/item/SpawnEggItemData.java index bbf6fe7c..432eb3f0 100644 --- a/api/src/main/java/net/techcable/sonarpet/item/SpawnEggItemData.java +++ b/api/src/main/java/net/techcable/sonarpet/item/SpawnEggItemData.java @@ -1,32 +1,27 @@ package net.techcable.sonarpet.item; import com.google.common.base.Preconditions; -import net.techcable.sonarpet.nms.INMS; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.EntityType; import org.bukkit.inventory.meta.ItemMeta; -public abstract class SpawnEggItemData extends ItemData { +public interface SpawnEggItemData extends ItemData { - public static final EntityType DEFAULT_TYPE = EntityType.PIG; + EntityType DEFAULT_TYPE = EntityType.PIG; - protected SpawnEggItemData(Material m, byte rawData, ItemMeta meta) { - super(m, rawData, meta); - } - - public SpawnEggItemData withSpawnedType(EntityType entityType) { + default SpawnEggItemData withSpawnedType(EntityType entityType) { Preconditions.checkNotNull(entityType, "Null type"); return getSpawnedType() == entityType ? this : create(entityType, getMeta()); } - public abstract EntityType getSpawnedType(); + EntityType getSpawnedType(); - public static SpawnEggItemData create(EntityType entityType) { + static SpawnEggItemData create(EntityType entityType) { return create(entityType, Bukkit.getItemFactory().getItemMeta(Material.MONSTER_EGG)); } - public static SpawnEggItemData create(EntityType entityType, ItemMeta meta) { - return INMS.getInstance().createSpawnEggData(entityType, meta); + static SpawnEggItemData create(EntityType entityType, ItemMeta meta) { + return ItemDataFactory.getInstance().createSpawnEggData(entityType, meta); } } diff --git a/api/src/main/java/net/techcable/sonarpet/item/StainedClayItemData.java b/api/src/main/java/net/techcable/sonarpet/item/StainedClayItemData.java index f60276c6..a8ef60c6 100644 --- a/api/src/main/java/net/techcable/sonarpet/item/StainedClayItemData.java +++ b/api/src/main/java/net/techcable/sonarpet/item/StainedClayItemData.java @@ -1,37 +1,21 @@ package net.techcable.sonarpet.item; -import com.google.common.base.Preconditions; - import org.bukkit.Bukkit; import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.inventory.meta.ItemMeta; -public class StainedClayItemData extends ItemData implements ColoredItemData { - - protected StainedClayItemData(byte rawData, ItemMeta meta) { - super(Material.STAINED_CLAY, rawData, meta); - } +public interface StainedClayItemData extends ItemData, ColoredItemData { - @SuppressWarnings("deprecation") - public DyeColor getColor() { - return DyeColor.getByWoolData(getRawData()); - } + DyeColor getColor(); - @SuppressWarnings("deprecation") - public StainedClayItemData withColor(DyeColor color) { - return withRawData(Preconditions.checkNotNull(color, "Null color").getWoolData()); - } - - public StainedClayItemData withRawData(int rawData) { - return (StainedClayItemData) super.withRawData(rawData); - } + StainedClayItemData withColor(DyeColor color); - public static StainedClayItemData create(DyeColor color) { + static StainedClayItemData create(DyeColor color) { return create(color, Bukkit.getItemFactory().getItemMeta(Material.STAINED_CLAY)); } - public static StainedClayItemData create(DyeColor color, ItemMeta meta) { - return new StainedClayItemData(Preconditions.checkNotNull(color, "Null color").getWoolData(), meta); + static StainedClayItemData create(DyeColor color, ItemMeta meta) { + return ItemDataFactory.getInstance().createStainedClay(color, meta); } } diff --git a/api/src/main/java/net/techcable/sonarpet/item/WoolItemData.java b/api/src/main/java/net/techcable/sonarpet/item/WoolItemData.java index cf778c71..c283c9bd 100644 --- a/api/src/main/java/net/techcable/sonarpet/item/WoolItemData.java +++ b/api/src/main/java/net/techcable/sonarpet/item/WoolItemData.java @@ -1,38 +1,21 @@ package net.techcable.sonarpet.item; -import com.google.common.base.Preconditions; - import org.bukkit.Bukkit; import org.bukkit.DyeColor; import org.bukkit.Material; -import org.bukkit.entity.Wolf; import org.bukkit.inventory.meta.ItemMeta; -public class WoolItemData extends ItemData implements ColoredItemData { - - protected WoolItemData(byte rawData, ItemMeta meta) { - super(Material.WOOL, rawData, meta); - } +public interface WoolItemData extends ItemData, ColoredItemData { - @SuppressWarnings("deprecation") - public DyeColor getColor() { - return DyeColor.getByWoolData(getRawData()); - } + DyeColor getColor(); - @SuppressWarnings("deprecation") - public WoolItemData withColor(DyeColor color) { - return withRawData(Preconditions.checkNotNull(color, "Null color").getWoolData()); - } - - public WoolItemData withRawData(int rawData) { - return (WoolItemData) super.withRawData(rawData); - } + WoolItemData withColor(DyeColor color); - public static WoolItemData create(DyeColor color) { + static WoolItemData create(DyeColor color) { return create(color, Bukkit.getItemFactory().getItemMeta(Material.WOOL)); } - public static WoolItemData create(DyeColor color, ItemMeta meta) { - return new WoolItemData(Preconditions.checkNotNull(color, "Null color").getWoolData(), meta); + static WoolItemData create(DyeColor color, ItemMeta meta) { + return ItemDataFactory.getInstance().createWool(color, meta); } } diff --git a/api/src/main/java/net/techcable/sonarpet/item/legacy/BasicSerializedItem.java b/api/src/main/java/net/techcable/sonarpet/item/legacy/BasicSerializedItem.java new file mode 100644 index 00000000..4a45e4c4 --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/item/legacy/BasicSerializedItem.java @@ -0,0 +1,65 @@ +package net.techcable.sonarpet.item.legacy; + +import com.google.common.collect.ImmutableList; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.bukkit.Material; + +import javax.annotation.Nullable; + +@RequiredArgsConstructor(access = AccessLevel.PACKAGE) +@Getter +public class BasicSerializedItem { + @NonNull + private final Material type; + private final byte rawData; + private final ImmutableList lore; + @Nullable + private final String displayName; + + private JsonObject serialize() { + JsonObject result = new JsonObject(); + result.addProperty("type", this.type.name()); + result.addProperty("rawData", this.rawData); + if (!this.lore.isEmpty()) { + JsonArray lore = new JsonArray(); + for (String element : this.lore) { + lore.add(element); + } + result.add("lore", lore); + } + if (this.displayName != null) { + result.addProperty("displayName", this.displayName); + } + return result; + } + public String serializeAsString() { + return "legacy(" + this.serialize() + ")"; + } + public static boolean isLegacyItem(String s) { + return s.startsWith("legacy("); + } + + public static BasicSerializedItem deserializeFromString(String s) { + if (s.startsWith("legacy(") && s.endsWith(")")) { + String inner = s.substring("legacy(".length(), s.length() - 1); + try { + return new Gson().fromJson(inner, BasicSerializedItem.class); + } catch (JsonSyntaxException e) { + throw new IllegalArgumentException( + "Invalid legacy item: " + s, + e + ); + } + } else { + throw new IllegalArgumentException("Not a legacy item: " + s); + } + + } +} diff --git a/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyDyeItemData.java b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyDyeItemData.java new file mode 100644 index 00000000..98b96aec --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyDyeItemData.java @@ -0,0 +1,32 @@ +package net.techcable.sonarpet.item.legacy; + +import com.google.common.base.Preconditions; +import net.techcable.sonarpet.item.ColoredItemData; +import net.techcable.sonarpet.item.DyeItemData; +import net.techcable.sonarpet.item.ItemData; +import net.techcable.sonarpet.item.ItemDataFactory; +import org.bukkit.Bukkit; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.inventory.meta.ItemMeta; + +public class LegacyDyeItemData extends LegacyItemData implements DyeItemData { + + /* package */ LegacyDyeItemData(LegacyItemDataFactory factory, byte rawData, ItemMeta meta) { + super(factory, Material.INK_SACK, rawData, meta); + } + + @SuppressWarnings("deprecation") + public DyeColor getColor() { + return DyeColor.getByDyeData(getRawData()); + } + + @SuppressWarnings("deprecation") + public LegacyDyeItemData withColor(DyeColor color) { + return withRawData(Preconditions.checkNotNull(color, "Null color").getDyeData()); + } + + public LegacyDyeItemData withRawData(int rawData) { + return (LegacyDyeItemData) super.withRawData(rawData); + } +} diff --git a/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyItemData.java b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyItemData.java new file mode 100644 index 00000000..e1c6c809 --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyItemData.java @@ -0,0 +1,101 @@ +package net.techcable.sonarpet.item.legacy; + +import com.google.common.base.Preconditions; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NonNull; +import net.techcable.sonarpet.block.BlockData; +import net.techcable.sonarpet.block.BlockDataFactory; +import net.techcable.sonarpet.item.ItemData; +import net.techcable.sonarpet.utils.NmsVersion; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BlockStateMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.material.MaterialData; + +import javax.annotation.Nullable; + +@Getter +public class LegacyItemData implements ItemData { + private final LegacyItemDataFactory factory; + @NonNull + private final Material type; + private final byte rawData; + @Getter(AccessLevel.NONE) // Doesn't make a defensive copy, which is nessicary as it is mutable + private final ItemMeta meta; + + /* package */ LegacyItemData( + LegacyItemDataFactory factory, + Material type, + byte rawData, + ItemMeta meta + ) { + NmsVersion.ensureBefore(NmsVersion.v1_13_R2); + this.factory = Preconditions.checkNotNull(factory); + this.type = Preconditions.checkNotNull(type, "Null type"); + this.rawData = rawData; + Preconditions.checkNotNull(meta, "Null metadata"); + this.meta = Bukkit.getItemFactory().asMetaFor(meta, type).clone(); // Not guarnteed to copy ;) + } + + public LegacyItemData withRawData(int rawData) { + Preconditions.checkArgument((byte) rawData == rawData, "Raw data doesn't fit into byte: %s", rawData); + return factory.create(this.type, rawData, this.meta); + } + + public LegacyItemData withMeta(ItemMeta meta) { + Preconditions.checkNotNull(meta, "Null metadata"); + return meta.equals(this.meta) ? this : factory.create(getType(), getRawData(), meta); + } + + public LegacyItemData withPlainMeta() { + return factory.create(getType(), getRawData(), getMeta()); + } + + public ItemMeta getMeta() { + return meta.clone(); + } + + @Override + public String serializeAsString() { + /* + * NOTE: Since we're on an old version, + * we aren't expected to preserve anything beyond material, + * rawData, lore, and displayName + */ + return new BasicSerializedItem( + this.type, + this.rawData, + this.getLore(), + this.getDisplayName().orElse(null) + ).serializeAsString(); + } + + public ItemStack createStack(int amount) { + ItemStack stack = new ItemStack(getType(), amount, getRawData()); + stack.setItemMeta(this.meta.clone()); + return stack; + } + + public MaterialData getLegacyMaterialData() { + return this.type.getNewData(this.rawData); + } + + @Nullable + @Override + public BlockData getBlockData() { + if (this.getMeta() instanceof BlockStateMeta) { + return BlockDataFactory.getInstance().fromState( + ((BlockStateMeta) this.getMeta()).getBlockState()); + } else if (this.getType().isBlock()) { + return BlockDataFactory.getInstance().fromLegacyData( + this.getType(), + this.rawData + ); + } else { + return null; + } + } +} \ No newline at end of file diff --git a/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyItemDataFactory.java b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyItemDataFactory.java new file mode 100644 index 00000000..afd94ffc --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyItemDataFactory.java @@ -0,0 +1,123 @@ +package net.techcable.sonarpet.item.legacy; + +import com.google.common.base.Preconditions; +import net.techcable.sonarpet.item.*; +import net.techcable.sonarpet.utils.NmsVersion; +import net.techcable.sonarpet.utils.PlayerProfile; +import net.techcable.sonarpet.utils.Versioning; +import org.bukkit.Bukkit; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.material.SpawnEgg; + +public class LegacyItemDataFactory implements ItemDataFactory { + public LegacyItemDataFactory() { + NmsVersion.ensureBefore(NmsVersion.v1_13_R2); + } + + @Override + public ItemData parseFromString(String s) { + BasicSerializedItem data = BasicSerializedItem.deserializeFromString(s); + ItemMeta meta = Bukkit.getItemFactory().getItemMeta(data.getType()); + if (!data.getLore().isEmpty()) { + meta.setLore(data.getLore()); + } + if (data.getDisplayName() != null) { + meta.setDisplayName(data.getDisplayName()); + } + return create(data.getType(), data.getRawData(), meta); + } + + LegacyItemData create(Material type, int rawData, ItemMeta meta) { + Preconditions.checkNotNull(type, "Null type"); + Preconditions.checkArgument((byte) rawData == rawData, "Raw data doesn't fit in byte: %s", rawData); + Preconditions.checkNotNull(meta, "Null item meta"); + switch (type) { + case INK_SACK: + return new LegacyDyeItemData(this, (byte) rawData, meta); + case SKULL_ITEM: + return new LegacySkullItemData(this, (byte) rawData, meta); + case STAINED_CLAY: + return new LegacyStainedClayItemData(this, (byte) rawData, meta); + case WOOL: + return new LegacyWoolItemData(this, (byte) rawData, meta); + case MONSTER_EGG: + // We expect this to be overridden, so we leave a hook + return (LegacyItemData) createSpawnEggData((byte) rawData, meta); + default: + return new LegacyItemData(this, type, (byte) rawData, meta); + } + } + + private SpawnEggItemData createSpawnEggData(byte rawData, ItemMeta meta) { + EntityType entityType = new SpawnEgg(rawData).getSpawnedType(); + if (entityType == null) entityType = SpawnEggItemData.DEFAULT_TYPE; + return createSpawnEggData(entityType, meta); // Convert raw data to entity type + } + + @Override + public ItemData create(Material type, ItemMeta meta) { + return create(type, 0, meta); + } + + @Override + public LegacyDyeItemData createDye(DyeColor color, ItemMeta meta) { + byte data = Preconditions.checkNotNull(color, "Null color").getDyeData(); + return new LegacyDyeItemData(this, data, meta); + } + + @Override + public StainedClayItemData createStainedClay(DyeColor color, ItemMeta meta) { + byte data = Preconditions.checkNotNull(color, "Null color").getWoolData(); + return new LegacyStainedClayItemData(this, data, it); + } + + @Override + public WoolItemData createWool(DyeColor color, ItemMeta meta) { + byte data = Preconditions.checkNotNull(color, "Null color").getWoolData(); + return new LegacyWoolItemData(this, data, it); + } + + @Override + public LegacySkullItemData createHumanSkull(PlayerProfile owner, ItemMeta rawMeta) { + Preconditions.checkNotNull(rawMeta, "Null meta"); + Preconditions.checkNotNull(owner, "Null owner"); + SkullMeta meta; + if (rawMeta instanceof SkullMeta) { + meta = (SkullMeta) rawMeta; + } else { + meta = (SkullMeta) Bukkit.getItemFactory().asMetaFor(rawMeta, Material.SKULL_ITEM); + } + meta = meta.clone(); // Don't modify their junk + meta.setOwner(owner.getName()); + return createSkull(SkullItemData.SkullType.HUMAN_SKULL, meta); + } + + @Override + public LegacySkullItemData createSkull(SkullItemData.SkullType type, ItemMeta rawData) { + return new LegacySkullItemData( + this, + Preconditions.checkNotNull(type, "Null skull type").getId(), + rawData + ); + } + + @Override + public SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta) { + if (Versioning.NMS_VERSION.getMajorVersion() >= 9) { + throw new UnsupportedOperationException("Can't use bukkit API on versions newer than 1.9"); + } + Preconditions.checkNotNull(meta, "Null meta"); + Preconditions.checkNotNull(entityType, "Null entity type"); + return new LegacySpawnEggItemData(this, Material.MONSTER_EGG, new SpawnEgg(entityType).getData(), meta) { + @Override + @SuppressWarnings("depreciation") // Bukkit is okay on versions less than 1.9, and we've already checked above + public EntityType getSpawnedType() { + return ((SpawnEgg) getLegacyMaterialData()).getSpawnedType(); + } + }; + } +} diff --git a/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacySkullItemData.java b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacySkullItemData.java new file mode 100644 index 00000000..8fd1c2fa --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacySkullItemData.java @@ -0,0 +1,97 @@ +package net.techcable.sonarpet.item.legacy; + +import com.google.common.base.Preconditions; +import net.techcable.sonarpet.item.ItemData; +import net.techcable.sonarpet.item.ItemDataFactory; +import net.techcable.sonarpet.item.SkullItemData; +import net.techcable.sonarpet.utils.PlayerProfile; +import net.techcable.sonarpet.utils.ProfileUtils; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import java.util.Optional; +import java.util.UUID; + +public class LegacySkullItemData extends LegacyItemData implements SkullItemData { + private final PlayerProfile profile; + + public Optional getProfile() { + if (getSkullType() == SkullType.HUMAN_SKULL && getMeta().hasOwner()) { + String ownerName = getMeta().getOwner(); + Preconditions.checkState(profile.getName().equals(ownerName), "Profile %s doesn't match owner %s", profile, ownerName); + return Optional.of(profile); + } else { + Preconditions.checkState(profile == null, "Profile %s is present but meta has no owner", profile); + return Optional.empty(); + } + } + + + /* package */ LegacySkullItemData(LegacyItemDataFactory factory, byte rawData, ItemMeta meta) { + this(factory, rawData, meta, ((SkullMeta) meta).hasOwner() ? ProfileUtils.lookupOptimistically(((SkullMeta) meta).getOwner()) : null); + } + + /* package */ LegacySkullItemData(LegacyItemDataFactory factory, byte rawData, ItemMeta meta, PlayerProfile profile) { + super(factory, Material.SKULL_ITEM, rawData, meta); + Preconditions.checkArgument(profile == null || profile.getName().equals(((SkullMeta) meta).getOwner())); + this.profile = profile; + } + + public LegacySkullItemData withOwner(UUID owner) { + Preconditions.checkNotNull(owner, "Null owner uuid"); + if (getProfile().isPresent() && getProfile().get().getId().equals(owner)) { + return this; + } else { + return withOwner(ProfileUtils.lookupOptimistically(owner)); + } + } + + public LegacySkullItemData withOwner(String ownerName) { + Preconditions.checkNotNull(ownerName, "Null owner name"); + if (getProfile().isPresent() && getProfile().get().getName().equals(ownerName)) { + return this; + } else { + return withOwner(ProfileUtils.lookupOptimistically(ownerName)); + } + } + + public LegacySkullItemData withOwner(PlayerProfile profile) { + return profile.equals(this.profile) ? this : getFactory().createHumanSkull(profile, this.getMeta()); + } + + public Optional getOwner() { + return getProfile().map(PlayerProfile::getId); + } + + + public Optional getOwnerName() { + return getProfile().map(PlayerProfile::getName); + } + + public boolean hasOwner() { + return getProfile().isPresent(); + } + + public SkullType getSkullType() { + int data = getRawData(); + SkullType[] values = SkullType.values(); + if (data < 0) { + throw new IllegalStateException("Can't get skull type from negative data: " + data); + } else if (data >= values.length) { + throw new IllegalStateException("Can't get skull type from too large data: " + data); + } else { + return values[data]; + } + } + + public ItemData withSkullType(SkullType type) { + return withRawData(Preconditions.checkNotNull(type, "Null type").ordinal()); + } + + @Override + public SkullMeta getMeta() { + return (SkullMeta) super.getMeta(); + } +} diff --git a/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacySpawnEggItemData.java b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacySpawnEggItemData.java new file mode 100644 index 00000000..758adf04 --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacySpawnEggItemData.java @@ -0,0 +1,16 @@ +package net.techcable.sonarpet.item.legacy; + +import net.techcable.sonarpet.item.SpawnEggItemData; +import org.bukkit.Material; +import org.bukkit.inventory.meta.ItemMeta; + +public abstract class LegacySpawnEggItemData extends LegacyItemData implements SpawnEggItemData { + protected LegacySpawnEggItemData( + LegacyItemDataFactory factory, + Material m, + byte rawData, + ItemMeta meta + ) { + super(factory, m, rawData, meta); + } +} diff --git a/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyStainedClayItemData.java b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyStainedClayItemData.java new file mode 100644 index 00000000..3c6e7317 --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyStainedClayItemData.java @@ -0,0 +1,30 @@ +package net.techcable.sonarpet.item.legacy; + +import com.google.common.base.Preconditions; +import net.techcable.sonarpet.item.StainedClayItemData; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public class LegacyStainedClayItemData extends LegacyItemData implements StainedClayItemData { + + protected LegacyStainedClayItemData(LegacyItemDataFactory factory, byte rawData, ItemMeta meta) { + super(factory, Material.STAINED_CLAY, rawData, meta); + } + + @SuppressWarnings("deprecation") + public DyeColor getColor() { + return DyeColor.getByWoolData(getRawData()); + } + + @SuppressWarnings("deprecation") + public LegacyStainedClayItemData withColor(DyeColor color) { + return withRawData(Preconditions.checkNotNull(color, "Null color").getWoolData()); + } + + public LegacyStainedClayItemData withRawData(int rawData) { + return (LegacyStainedClayItemData) super.withRawData(rawData); + } + +} diff --git a/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyWoolItemData.java b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyWoolItemData.java new file mode 100644 index 00000000..b8008c05 --- /dev/null +++ b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyWoolItemData.java @@ -0,0 +1,31 @@ +package net.techcable.sonarpet.item.legacy; + +import com.google.common.base.Preconditions; +import net.techcable.sonarpet.item.ColoredItemData; +import net.techcable.sonarpet.item.ItemData; +import net.techcable.sonarpet.item.WoolItemData; +import org.bukkit.Bukkit; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.inventory.meta.ItemMeta; + +public class LegacyWoolItemData extends LegacyItemData implements WoolItemData, ColoredItemData { + + protected LegacyWoolItemData(LegacyItemDataFactory factory, byte rawData, ItemMeta meta) { + super(factory, Material.WOOL, rawData, meta); + } + + @SuppressWarnings("deprecation") + public DyeColor getColor() { + return DyeColor.getByWoolData(getRawData()); + } + + @SuppressWarnings("deprecation") + public LegacyWoolItemData withColor(DyeColor color) { + return withRawData(Preconditions.checkNotNull(color, "Null color").getWoolData()); + } + + public LegacyWoolItemData withRawData(int rawData) { + return (LegacyWoolItemData) super.withRawData(rawData); + } +} diff --git a/api/src/main/java/net/techcable/sonarpet/nms/INMS.java b/api/src/main/java/net/techcable/sonarpet/nms/INMS.java index 15f87ab0..88f5a827 100644 --- a/api/src/main/java/net/techcable/sonarpet/nms/INMS.java +++ b/api/src/main/java/net/techcable/sonarpet/nms/INMS.java @@ -20,18 +20,15 @@ import com.dsh105.echopet.compat.api.plugin.IEchoPetPlugin; import com.google.common.base.Preconditions; import net.techcable.pineapple.reflection.Reflection; -import net.techcable.sonarpet.item.SpawnEggItemData; -import net.techcable.sonarpet.utils.ModernSpawnEggs; +import net.techcable.sonarpet.item.ItemDataFactory; +import net.techcable.sonarpet.item.legacy.LegacyItemDataFactory; import net.techcable.sonarpet.utils.NmsVersion; import net.techcable.sonarpet.utils.Versioning; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.material.SpawnEgg; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; @@ -42,30 +39,9 @@ @SuppressWarnings("deprecation") public interface INMS { - default SpawnEggItemData createSpawnEggData(Material material, byte rawData, ItemMeta meta) { - EntityType entityType; - if (ModernSpawnEggs.isSupported()) { - entityType = ModernSpawnEggs.getSpawnEggType(material); - } else { - entityType = new SpawnEgg(rawData).getSpawnedType(); - if (entityType == null) entityType = SpawnEggItemData.DEFAULT_TYPE; - } - return createSpawnEggData(entityType, meta); // Convert raw data to entity type - } - - default SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta) { - if (Versioning.NMS_VERSION.getMajorVersion() >= 9) { - throw new UnsupportedOperationException("Can't use bukkit API on versions newer than 1.9"); - } - Preconditions.checkNotNull(meta, "Null meta"); - Preconditions.checkNotNull(entityType, "Null entity type"); - return new SpawnEggItemData(Material.MONSTER_EGG, new SpawnEgg(entityType).getData(), meta) { - @Override - @SuppressWarnings("depreciation") // Bukkit is okay on versions less than 1.9, and we've already checked above - public EntityType getSpawnedType() { - return ((SpawnEgg) getLegacyMaterialData()).getSpawnedType(); - } - }; + default ItemDataFactory getItemDataFactory() { + NmsVersion.ensureBefore(NmsVersion.v1_13_R2); + return new LegacyItemDataFactory(); } boolean spawnEntity(NMSInsentientEntity entity, Location location); From f1fff9b147eb2294899abcf2b1f9726fa8fe5ffa Mon Sep 17 00:00:00 2001 From: Techcable Date: Wed, 10 Jun 2020 11:52:35 -0700 Subject: [PATCH 5/8] Formally require Paper and drop support for all legacy minecraft versions The project is still officially unmaintained and I'm still officially dead. Please ignore my activity. It is a hallucination I'm requiring Paper for three reasons: 1. The software itself is more stable. It is inherently less prone to bugs 2. I'm already a Paper contributor and I'm more comfortable with their community 3. I intend to start adding new APIs to Paper that I will use inside SonarPet I'm releasing all my changes to this project under the MIT license (retroactively). Generally speaking, I find the GPL distaseful. Users still must comply with the terms of the GPL when using the plugin as a whole because we still use DSH105's original code. However they may freely copy any of my changes into their own projects, including my NPC code and my bizzare set of utilities and abstractions. If it's in kotlin or under my package name it's probably my code (although it could be a different contributor). --- LICENSE.txt => GPL.txt | 0 LICENSE.md | 24 ++++++++++++++++++++++ MIT.txt | 21 ++++++++++++++++++++ README.md | 45 +++++++++++++++++++++++++++++++++++------- 4 files changed, 83 insertions(+), 7 deletions(-) rename LICENSE.txt => GPL.txt (100%) create mode 100644 LICENSE.md create mode 100644 MIT.txt diff --git a/LICENSE.txt b/GPL.txt similarity index 100% rename from LICENSE.txt rename to GPL.txt diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..5c7cd960 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,24 @@ +SonarPet is a fork of [EchoPet](https://github.com/DSH105/EchoPet) and inherits its licensing. + +EchoPet is [GPLv3 Licensed](./GPL.txt). Any uses of this project +must comply with the terms of the GPL. +The original code from DSH105 is under that license +and we must comply with it. + +By default, all contributions are licensed + under the (restrictive) GPLv3 license. + +The GPL is somewhat restrictive and prevents inclusion +in proprietary software. + + +I (Techcable) have chosen to release all +my changes under the [MIT License](./MIT.txt). This is retroactive - it includes all +of my changes that I ever contributed to this repository. + +Contributors may also choose to release their changes under +the (permissive) MIT license by adding their names to the following +list: +```` +Techcable , +```` \ No newline at end of file diff --git a/MIT.txt b/MIT.txt new file mode 100644 index 00000000..18b3002d --- /dev/null +++ b/MIT.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Nicholas Schlabach + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 7acb7c2c..4067b340 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,29 @@ SonarPet [![Build Status](https://travis-ci.org/TechzoneMC/SonarPet.svg?branch=master)](https://travis-ci.org/TechzoneMC/SonarPet) ======== -A fork of [EchoPet](https://github.com/DSH105/EchoPet) updated to 1.11 +A fork of [EchoPet](https://github.com/DSH105/EchoPet) updated to modern versions -## **NOTE**: Unmaintained -I'm no longer willing to be the primary maintainer of SonarPet, -contact me on IRC if you're willing to take over this job. +## **NOTE**: Inactive +In spite of recent activity, SonarPet is still officially unmaintained. +This is still "officially" unsupported unless I decide to +Contact me on IRC if you're willing to help with maintenance and support. + +### Supported Versions/Servers +SonarPet is undergoing some internal changes: +1. Support for "multiple versions" is being dropped. + - Due to rapid changes to mi + - Supporting 10 versions at once is incredibly draining!!!! +2. This plugin officially requires [Paper](https://papermc.io/)!! + - Spigot and CraftBukkit are unsupported - they will no longer work in the future. + - In the future, I plan to use official Paper APIs to replace most of our NMS code + - Ideally we would have zero-NMS dependencies +3. SonarPet will be completely free, and I will no longer offer paid support. + - SonarPet was previously released as a paid resource on Spigot + (with a portion of all revenue going to the old authors) + - I apologize for dropping support for a paid plugin. I should have realized + full-time development was incompatible with my school schedule. It was misleading, + and I won't do it again. + - Don't give me too hard a time: My code was still better than + 99.9% of all other paid plugins ## Features - All mobs can be pets (even enderdragons) @@ -12,20 +31,32 @@ contact me on IRC if you're willing to take over this job. - Pets are greatly customisable, through the extensive Command Base and PetMenu - A Custom AI makes all Pets focused on specific goals, handled closely by the core of the Plugin - Make your pets attack your enemies -- Supports minecraft 1.6.4-1.11 ## Changes I've made some changes to EchoPet in SonarPet, which are listed below. - I've renamed references from 'EchoPet' to 'SonarPet' - Permissions and class names remain, to retain backwards compatibility and to avoid the need to change permissions - I've added 1.9-1.11 support + - Note: Multiple version support will be dropped in the future!!!! ## Requirements -- Java 8 +- Modern Minecraft + - Don't use old versions! + - Eventually I'll drop multi-version support..... +- [Paper](https://papermc.io/) + - Paper is strictly better than Spigot. Use it! ## Credits - Dsh105 - Creating EchoPet - CaptainBern - Helping out with EchoPet -- Techcable - 1.9-1.11 update and maintinaing SonarPet +- Techcable - 1.9+ updates and maintaining SonarPet + - NOTE: I'm officially inactive/dead. Please do not conduct a seance. ## License +EchoPet was originally licensed under the GPLv3. +This essentially requires us to be an open source project. + +As + +Please respect the contributions of the original authors and maintainers +by releasing your contributions to the public. It's the least you can do :) From 187a54538bfd760afdf98793ae9fead4056d03d1 Mon Sep 17 00:00:00 2001 From: Techcable Date: Wed, 10 Jun 2020 15:14:21 -0700 Subject: [PATCH 6/8] Build against on Paper API 1.15 (instead of Bukkit 1.8.8) I may decide to a couple older versions for a while. This code is currently undergoing crazy insane change. This breaks everything - we don't compile at all. The main problem is our plugin dependencies - lots of maven repos have moved or become inactive. My personal repo at repo.techcable.net no longer works - which had much of the stuff I need to build SonarPets........ Update guava to an actually modern version (21.0 instead of 17.0). We don't care about compat with 1.8.8 anymore. Update gradle to v6.4 Update ProtocolLib to 4.5.0 (why cant gradle find this)? --- build.gradle.kts | 81 ++++++---- gradle/compat.gradle | 184 ----------------------- gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 52 insertions(+), 215 deletions(-) delete mode 100644 gradle/compat.gradle diff --git a/build.gradle.kts b/build.gradle.kts index d377127d..df0a598e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,22 +1,20 @@ -import org.gradle.api.tasks.compile.JavaCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import org.gradle.api.tasks.testing.Test -import org.gradle.api.tasks.testing.junit.JUnitOptions buildscript { repositories { - gradleScriptKotlin() + mavenCentral() } dependencies { - classpath("org.ow2.asm:asm-all:5.2") // Used to check for guava compat - classpath(kotlinModule("gradle-plugin")) + classpath(kotlin("gradle-plugin", version = "1.3.72")) } } plugins { id("java") id("maven") - id("org.jetbrains.kotlin.jvm").version("1.2.51") - id("com.github.johnrengelman.shadow").version("1.2.4").apply(false) + kotlin("jvm").version("1.3.72") + id("com.github.johnrengelman.shadow") + .version("5.2.0") + .apply(false) } allprojects { apply { @@ -24,7 +22,7 @@ allprojects { } group = "net.techcable.sonarpet" - version = "1.1.0-alpha2-SNAPSHOT" + version = "1.2.0-alpha1-SNAPSHOT" } var versionSignature: String by rootProject.extra versionSignature = rawComputeVersionSignature() @@ -48,7 +46,7 @@ subprojects { targetCompatibility = "1.8" options.encoding = "UTF-8" } - tasks.withType { + tasks.withType().configureEach { kotlinOptions.jvmTarget = "1.8" } tasks.withType { @@ -63,14 +61,27 @@ subprojects { } repositories { + /* + * NOTE: I have a bunch of local jars to keep + * all this legacy code rolling. For now my laptop + * is the only place you can compile SonarPet ^_^ + */ mavenLocal() mavenCentral() maven { name = "techcable-repo" setUrl("https://repo.techcable.net/content/groups/public/") } - maven { setUrl("https://hub.spigotmc.org/nexus/content/groups/public/") } + maven { + name = "paper-repo" + setUrl("https://papermc.io/repo/repository/maven-public/") + } maven { setUrl("http://repo.dmulloy2.net/content/groups/public/") } + maven { + name = "enginehub-repo" + setUrl("https://maven.enginehub.org/repo/") + } + // TODO: What are all these things for!?! maven { setUrl("http://repo.md-5.net/content/groups/public/") } maven { setUrl("http://ci.hawkfalcon.com/plugin/repository/everything/") } maven { setUrl("http://maven.sk89q.com/repo/") } @@ -79,50 +90,60 @@ subprojects { maven { setUrl("http://maven.elmakers.com/repository/") } } - configurations.all { - resolutionStrategy { - // Force usage of old guava - force("com.google.guava:guava:17.0") - } - } dependencies { + implementation(kotlin("stdlib-jdk8")) testCompile("junit:junit:4.12") testCompile("com.googlecode.junit-toolbox:junit-toolbox:2.3") - compile("net.techcable:pineapple:0.1.0-beta5") - compile("org.jetbrains.kotlin:kotlin-stdlib-jre8:1.2.51") + compile("net.techcable:pineapple:0.1.0-beta6") + // TODO: Get rid of this + // TODO: Drop transitive dependency on "Minecraft-Reflection" compile("com.dsh105:Commodus:1.0.6") { exclude(module = "Minecraft-Reflection") } + // TODO: Get rid of this compile("com.dsh105:PowerMessage:1.0.1-SNAPSHOT") { exclude(module = "Commodus") } compile("org.slf4j:slf4j-jdk14:1.7.5") compile("com.zaxxer:HikariCP:2.4.5") /* - * An outdated version of ASM is used by Paper. - * We need to shade in our (modern) version, - * or else we'll use Paper's outdated version and crash. + * NOTE: Paper already includes ASM. + * + * Since we depend on them, will just assume its already present. + * Shading in this dependency is unessicarry + * * The bootstrap loader also depends on ASM to automatically relocate dependencies too, * since we need to keep our own seperate version of guava and other things. */ - "shade"("org.ow2.asm:asm:5.2") - "shade"("org.ow2.asm:asm-commons:5.2") + compileOnly("org.ow2.asm:asm:8.0.1") + compileOnly("org.ow2.asm:asm-commons:5.2") + /* + * This is not included in paper. It's required by the bootstrap loader, + * so we have to shade it in directly. + * + * Not sure if it will causes issues with the not-shaded asm. + */ + // TODO: Does this create issues since we don't shade the other parts of ASM? "shade"("org.ow2.asm:asm-util:5.2") // Provided dependencies /* - * Compile against old guava, with emulation where necessary. - * Compiling against modern guava causes the source to compile against some missing bytecode. - * For example, a new checkArgument(boolean,String,int) overload was added for effeciency, which was missing in old versions. + * We only support recent minecraft. + * Therefore we can compile against actually modern + * guava versions. */ - compileOnly("com.google.guava:guava:17.0") - compileOnly("org.bukkit:bukkit:1.12-pre5-SNAPSHOT") + compileOnly("com.google.guava:guava:21.0") + // We compile against Paper API - not Bukkit or Spigot API + compileOnly("com.destroystokyo.paper:paper-api:1.15.2-R0.1-SNAPSHOT") compileOnly("org.projectlombok:lombok:1.16.12") + // TODO: Is VanishNoPacket still the standard? + // Do we need to integrate with someone elese? compileOnly("org.kitteh:VanishNoPacket:3.18.7") { exclude(module = "Vault") } compileOnly("com.sk89q:worldedit:6.0.0-SNAPSHOT") compileOnly("com.sk89q:worldguard:6.0.0-SNAPSHOT") - compileOnly("com.comphenix.protocol:ProtocolLib:3.6.5-SNAPSHOT") + // TODO: Update to modern ProtocolLib + compileOnly("com.comphenix.protocol:ProtocolLib:4.5.0") } // All test modules depend on the API's test module diff --git a/gradle/compat.gradle b/gradle/compat.gradle deleted file mode 100644 index 53f511a0..00000000 --- a/gradle/compat.gradle +++ /dev/null @@ -1,184 +0,0 @@ -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath "org.ow2.asm:asm-all:5.2" // Used to check for guava compat - } -} - -import groovy.transform.CompileStatic -import groovy.transform.Immutable -import org.objectweb.asm.* - -import java.util.zip.ZipEntry -import java.util.zip.ZipFile - -import static org.objectweb.asm.Opcodes.* - -@CompileStatic -class ClassMembers { - String className - Set> methods = new HashSet<>() - Set fields = new HashSet<>() -} - -@CompileStatic -@Immutable -class JarMembers { - private Map classes - - boolean isKnownClass(String className) { - this.classes[className] != null - } - - boolean isKnownMethod(String owner, String name, String desc) { - ClassMembers classMembers = this.classes[owner] - if (classMembers == null) return null - return new Tuple2(name, desc) in classMembers.methods - } - - boolean isKnownField(String owner, String name) { - ClassMembers classMembers = this.classes[owner] - if (classMembers == null) return null - return name in classMembers.fields - } - - static JarMembers parse(File jarFile) { - def zip = new ZipFile(jarFile) - Map classes = [:] - try { - zip.entries().each { ZipEntry entry -> - def reader = new ClassReader(zip.getInputStream(entry).bytes) - reader.accept(new ClassVisitor(ASM5) { - private ClassMembers classMembers = null - @Override - void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - this.classMembers = new ClassMembers(className: name) - } - - @Override - MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - this.classMembers.methods.add(new Tuple2(name, desc)) - return null - } - - @Override - FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { - this.classMembers.fields.add(name) - return null - } - - @Override - void visitEnd() { - classes[this.classMembers.className] = this.classMembers - } - }, ClassReader.SKIP_DEBUG | ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES) - } - return new JarMembers(classes: classes) - } finally { - zip.close() - } - } -} - -Logger logger = logger -@CompileStatic -class GuavaCompatEnforcementTask extends DefaultTask { - static File localRepo = new File(System.getProperty("user.home"), ".m2/repository") - @Input - String minimumVersion - @InputFiles - @SkipWhenEmpty - FileCollection classFiles - - File findOrDownloadGuava(String version) { - File localJar = new File(localRepo, "com/google/guava/guava/$version/guava-${version}.jar" as String) - if (!localJar.exists()) { - logger.info("Downloading guava $version from central repository!") - localJar.parentFile.mkdirs() - new URL("https://repo1.maven.org/maven2/com/google/guava/guava/$version/guava-${version}.jar").withInputStream { input -> - localJar << input - } - } - return localJar - } - - @TaskAction - void checkCompat() { - logger.info("Examining guava $minimumVersion") - JarMembers guavaMembers = JarMembers.parse(findOrDownloadGuava(minimumVersion)) - logger.info("Checking compliance with guava $minimumVersion") - for (File classFile in classFiles) { - classFile.withInputStream { - def reader = new ClassReader(it) - String className = reader.className - char[] buffer = new char[reader.maxStringLength] - // NOTE: We don't need to actually read the code, just the constant pool ;) - for (int constantPoolIndex = 0; constantPoolIndex < reader.itemCount; constantPoolIndex++) { - int offset = reader.getItem(constantPoolIndex) - int itemType = reader.b[offset- 1] // See wikipedia for details - switch (itemType) { - case 7: // class reference - String name = reader.readClass(offset, buffer) - if (name.startsWith("com/google/common") && !guavaMembers.isKnownClass(name)) { - throw new GradleException("$className uses guava class not found in version $minimumVersion: ${name.replace('/', '.')}") - } - break - case 9: // field reference - case 10: // method reference - case 11: // interface method reference - case 15: // MethodHandle - Handle handle = reader.readConst(offset, buffer) as Handle - if (handle.owner.startsWith("com/google/common")) { - switch (handle.tag) { - case H_INVOKEVIRTUAL: - case H_INVOKESTATIC: - case H_INVOKESPECIAL: - case H_NEWINVOKESPECIAL: - case H_INVOKEINTERFACE: - if (!guavaMembers.isKnownMethod(handle.owner, handle.name, handle.desc)) { - def methodType = Type.getMethodType(handle.desc) - def methodId = new StringBuilder(handle.owner.length() + handle.desc.length() + handle.name.length() + 50) - methodId.append(handle.owner.replace('/', '.')) - methodId.append('.') - methodId.append(handle.name) - methodId.append('(') - def argTypes = methodType.argumentTypes - if (argTypes.length > 0) { - methodId.append(argTypes[0].className) - for (int i = 1; i < argTypes.length; i++) { - methodId.append(',') - methodId.append(argTypes[i].className) - } - } - methodId.append(')') - throw new GradleException( - "$className uses guava method not found in $minimumVersion: $methodId" - ) - } - break - case H_GETFIELD: - case H_GETSTATIC: - case H_PUTFIELD: - case H_PUTSTATIC: - if (!guavaMembers.isKnownField(handle.owner, handle.name)) { - throw new GradleException( - "$className uses guava field not found in $minimumVersion: ${handle.owner.replace('/', '.')}.${handle.name}" - ) - } - } - } - break - case 3..6: - case [1, 8, 12, 16, 18]: - break // Ignored - default: - throw new AssertionError("Unknown constant pool type id: $itemType") - } - } - } - } - } -} -ext.GuavaCompatEnforcementTask = GuavaCompatEnforcementTask diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 76493013..341693ac 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-all.zip From 708a4cb4a925eded01e8e4563662bc1c72e5f084 Mon Sep 17 00:00:00 2001 From: Techcable Date: Wed, 10 Jun 2020 15:36:34 -0700 Subject: [PATCH 7/8] Remove all the NMS code for 1.8.8, 1.9, 1.10 and 1.11 Remove some associated compatibility code (but not all of it). I'm kind of just deleting at random and hoping I hit something good :D --- .../net/techcable/sonarpet/SafeSound.java | 3 + .../item/legacy/LegacyItemDataFactory.java | 5 +- .../item/legacy/LegacySkullItemData.java | 3 +- .../particles/BukkitParticleBuilder.java | 6 + .../particles/PacketParticleBuilder.java | 37 ---- .../particles/v18ParticleBuilder.java | 33 ---- .../techcable/sonarpet/utils/NmsVersion.java | 5 - .../sonarpet/particles/ParticleBuilder.kt | 3 +- nms/v1_10_R1/build.gradle.kts | 4 - .../versions/v1_10_R1/BlockSoundDataImpl.java | 37 ---- .../versions/v1_10_R1/DamageSourceImpl.java | 11 -- .../versions/v1_10_R1/DataWatcherImpl.java | 35 ---- .../versions/v1_10_R1/NMSEntityHorseImpl.java | 77 -------- .../nms/versions/v1_10_R1/NMSEntityImpl.java | 70 ------- .../v1_10_R1/NMSEntityInsentientImpl.java | 125 ------------ .../versions/v1_10_R1/NMSEntityRegistry.java | 70 ------- .../nms/versions/v1_10_R1/NMSImpl.java | 137 ------------- .../v1_10_R1/NMSLivingEntityImpl.java | 181 ------------------ .../nms/versions/v1_10_R1/NMSPlayerImpl.java | 27 --- .../nms/versions/v1_10_R1/NavigationImpl.java | 54 ------ .../v1_10_R1/data/NMSSpawnEggItemData.java | 86 --------- .../nms/versions/v1_10_R1/NMSSoundImpl.kt | 21 -- nms/v1_11_R1/build.gradle.kts | 4 - .../versions/v1_11_R1/BlockSoundDataImpl.java | 37 ---- .../versions/v1_11_R1/DamageSourceImpl.java | 11 -- .../versions/v1_11_R1/DataWatcherImpl.java | 35 ---- .../versions/v1_11_R1/NMSEntityHorseImpl.java | 75 -------- .../nms/versions/v1_11_R1/NMSEntityImpl.java | 67 ------- .../v1_11_R1/NMSEntityInsentientImpl.java | 125 ------------ .../versions/v1_11_R1/NMSEntityRegistry.java | 63 ------ .../nms/versions/v1_11_R1/NMSImpl.java | 138 ------------- .../v1_11_R1/NMSLivingEntityImpl.java | 181 ------------------ .../nms/versions/v1_11_R1/NMSPlayerImpl.java | 27 --- .../nms/versions/v1_11_R1/NavigationImpl.java | 54 ------ .../v1_11_R1/data/NMSSpawnEggItemData.java | 87 --------- .../nms/versions/v1_11_R1/NMSSoundImpl.kt | 21 -- nms/v1_8_R3/build.gradle.kts | 4 - .../versions/v1_8_R3/BlockSoundDataImpl.java | 37 ---- .../versions/v1_8_R3/DamageSourceImpl.java | 11 -- .../nms/versions/v1_8_R3/DataWatcherImpl.java | 24 --- .../versions/v1_8_R3/NMSEntityHorseImpl.java | 77 -------- .../nms/versions/v1_8_R3/NMSEntityImpl.java | 68 ------- .../v1_8_R3/NMSEntityInsentientImpl.java | 123 ------------ .../versions/v1_8_R3/NMSEntityRegistry.java | 72 ------- .../nms/versions/v1_8_R3/NMSImpl.java | 90 --------- .../versions/v1_8_R3/NMSLivingEntityImpl.java | 178 ----------------- .../nms/versions/v1_8_R3/NMSPlayerImpl.java | 27 --- .../nms/versions/v1_8_R3/NavigationImpl.java | 53 ----- .../nms/versions/v1_8_R3/NMSSoundImpl.kt | 20 -- nms/v1_9_R1/build.gradle.kts | 7 - .../versions/v1_9_R1/BlockSoundDataImpl.java | 37 ---- .../versions/v1_9_R1/DamageSourceImpl.java | 11 -- .../nms/versions/v1_9_R1/DataWatcherImpl.java | 35 ---- .../versions/v1_9_R1/NMSEntityHorseImpl.java | 77 -------- .../nms/versions/v1_9_R1/NMSEntityImpl.java | 68 ------- .../v1_9_R1/NMSEntityInsentientImpl.java | 124 ------------ .../versions/v1_9_R1/NMSEntityRegistry.java | 72 ------- .../nms/versions/v1_9_R1/NMSImpl.java | 138 ------------- .../versions/v1_9_R1/NMSLivingEntityImpl.java | 181 ------------------ .../nms/versions/v1_9_R1/NMSPlayerImpl.java | 27 --- .../nms/versions/v1_9_R1/NavigationImpl.java | 53 ----- .../v1_9_R1/data/NMSSpawnEggItemData.java | 86 --------- .../nms/versions/v1_9_R1/NMSSoundImpl.kt | 21 -- nms/v1_9_R2/build.gradle.kts | 4 - .../versions/v1_9_R2/BlockSoundDataImpl.java | 37 ---- .../versions/v1_9_R2/DamageSourceImpl.java | 11 -- .../nms/versions/v1_9_R2/DataWatcherImpl.java | 35 ---- .../versions/v1_9_R2/NMSEntityHorseImpl.java | 77 -------- .../nms/versions/v1_9_R2/NMSEntityImpl.java | 68 ------- .../v1_9_R2/NMSEntityInsentientImpl.java | 124 ------------ .../versions/v1_9_R2/NMSEntityRegistry.java | 72 ------- .../nms/versions/v1_9_R2/NMSImpl.java | 138 ------------- .../versions/v1_9_R2/NMSLivingEntityImpl.java | 181 ------------------ .../nms/versions/v1_9_R2/NMSPlayerImpl.java | 27 --- .../nms/versions/v1_9_R2/NavigationImpl.java | 53 ----- .../v1_9_R2/data/NMSSpawnEggItemData.java | 86 --------- .../nms/versions/v1_9_R2/NMSSoundImpl.kt | 21 -- settings.gradle | 2 +- 78 files changed, 15 insertions(+), 4597 deletions(-) delete mode 100644 api/src/main/java/net/techcable/sonarpet/particles/PacketParticleBuilder.java delete mode 100644 api/src/main/java/net/techcable/sonarpet/particles/v18ParticleBuilder.java delete mode 100644 nms/v1_10_R1/build.gradle.kts delete mode 100644 nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/BlockSoundDataImpl.java delete mode 100644 nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/DamageSourceImpl.java delete mode 100644 nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/DataWatcherImpl.java delete mode 100644 nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSEntityHorseImpl.java delete mode 100644 nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSEntityImpl.java delete mode 100644 nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSEntityInsentientImpl.java delete mode 100644 nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSEntityRegistry.java delete mode 100644 nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSImpl.java delete mode 100644 nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSLivingEntityImpl.java delete mode 100644 nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSPlayerImpl.java delete mode 100644 nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NavigationImpl.java delete mode 100644 nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/data/NMSSpawnEggItemData.java delete mode 100644 nms/v1_10_R1/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSSoundImpl.kt delete mode 100644 nms/v1_11_R1/build.gradle.kts delete mode 100644 nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/BlockSoundDataImpl.java delete mode 100644 nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/DamageSourceImpl.java delete mode 100644 nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/DataWatcherImpl.java delete mode 100644 nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSEntityHorseImpl.java delete mode 100644 nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSEntityImpl.java delete mode 100644 nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSEntityInsentientImpl.java delete mode 100644 nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSEntityRegistry.java delete mode 100644 nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSImpl.java delete mode 100644 nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSLivingEntityImpl.java delete mode 100644 nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSPlayerImpl.java delete mode 100644 nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NavigationImpl.java delete mode 100644 nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/data/NMSSpawnEggItemData.java delete mode 100644 nms/v1_11_R1/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSSoundImpl.kt delete mode 100644 nms/v1_8_R3/build.gradle.kts delete mode 100644 nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/BlockSoundDataImpl.java delete mode 100644 nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/DamageSourceImpl.java delete mode 100644 nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/DataWatcherImpl.java delete mode 100644 nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSEntityHorseImpl.java delete mode 100644 nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSEntityImpl.java delete mode 100644 nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSEntityInsentientImpl.java delete mode 100644 nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSEntityRegistry.java delete mode 100644 nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSImpl.java delete mode 100644 nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSLivingEntityImpl.java delete mode 100644 nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSPlayerImpl.java delete mode 100644 nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NavigationImpl.java delete mode 100644 nms/v1_8_R3/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSSoundImpl.kt delete mode 100644 nms/v1_9_R1/build.gradle.kts delete mode 100644 nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/BlockSoundDataImpl.java delete mode 100644 nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/DamageSourceImpl.java delete mode 100644 nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/DataWatcherImpl.java delete mode 100644 nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSEntityHorseImpl.java delete mode 100644 nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSEntityImpl.java delete mode 100644 nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSEntityInsentientImpl.java delete mode 100644 nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSEntityRegistry.java delete mode 100644 nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSImpl.java delete mode 100644 nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSLivingEntityImpl.java delete mode 100644 nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSPlayerImpl.java delete mode 100644 nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NavigationImpl.java delete mode 100644 nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/data/NMSSpawnEggItemData.java delete mode 100644 nms/v1_9_R1/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSSoundImpl.kt delete mode 100644 nms/v1_9_R2/build.gradle.kts delete mode 100644 nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/BlockSoundDataImpl.java delete mode 100644 nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/DamageSourceImpl.java delete mode 100644 nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/DataWatcherImpl.java delete mode 100644 nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSEntityHorseImpl.java delete mode 100644 nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSEntityImpl.java delete mode 100644 nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSEntityInsentientImpl.java delete mode 100644 nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSEntityRegistry.java delete mode 100644 nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSImpl.java delete mode 100644 nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSLivingEntityImpl.java delete mode 100644 nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSPlayerImpl.java delete mode 100644 nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NavigationImpl.java delete mode 100644 nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/data/NMSSpawnEggItemData.java delete mode 100644 nms/v1_9_R2/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSSoundImpl.kt diff --git a/api/src/main/java/net/techcable/sonarpet/SafeSound.java b/api/src/main/java/net/techcable/sonarpet/SafeSound.java index de46610f..2d0522ea 100644 --- a/api/src/main/java/net/techcable/sonarpet/SafeSound.java +++ b/api/src/main/java/net/techcable/sonarpet/SafeSound.java @@ -9,7 +9,10 @@ /** * A version independent enumeration of sounds. + * + * @deprecated Legacy 1.8.8 compat */ +@Deprecated public enum SafeSound { BLAZE_AMBIENT("ENTITY_BLAZE_AMBIENT", "BLAZE_BREATH"), BLAZE_DEATH("ENTITY_BLAZE_DEATH", "BLAZE_DEATH"), diff --git a/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyItemDataFactory.java b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyItemDataFactory.java index afd94ffc..473579dc 100644 --- a/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyItemDataFactory.java +++ b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacyItemDataFactory.java @@ -107,12 +107,9 @@ public LegacySkullItemData createSkull(SkullItemData.SkullType type, ItemMeta ra @Override public SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta) { - if (Versioning.NMS_VERSION.getMajorVersion() >= 9) { - throw new UnsupportedOperationException("Can't use bukkit API on versions newer than 1.9"); - } Preconditions.checkNotNull(meta, "Null meta"); Preconditions.checkNotNull(entityType, "Null entity type"); - return new LegacySpawnEggItemData(this, Material.MONSTER_EGG, new SpawnEgg(entityType).getData(), meta) { + return new LegacySpawnEggItemData(this, Material.LEGACY_MONSTER_EGG, new SpawnEgg(entityType).getData(), meta) { @Override @SuppressWarnings("depreciation") // Bukkit is okay on versions less than 1.9, and we've already checked above public EntityType getSpawnedType() { diff --git a/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacySkullItemData.java b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacySkullItemData.java index 8fd1c2fa..16cb5fec 100644 --- a/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacySkullItemData.java +++ b/api/src/main/java/net/techcable/sonarpet/item/legacy/LegacySkullItemData.java @@ -34,7 +34,8 @@ public Optional getProfile() { } /* package */ LegacySkullItemData(LegacyItemDataFactory factory, byte rawData, ItemMeta meta, PlayerProfile profile) { - super(factory, Material.SKULL_ITEM, rawData, meta); + // Pretty sure this is okay s + super(factory, Material.LEGACY_SKULL_ITEM, rawData, meta); Preconditions.checkArgument(profile == null || profile.getName().equals(((SkullMeta) meta).getOwner())); this.profile = profile; } diff --git a/api/src/main/java/net/techcable/sonarpet/particles/BukkitParticleBuilder.java b/api/src/main/java/net/techcable/sonarpet/particles/BukkitParticleBuilder.java index 738e2451..9781eecb 100644 --- a/api/src/main/java/net/techcable/sonarpet/particles/BukkitParticleBuilder.java +++ b/api/src/main/java/net/techcable/sonarpet/particles/BukkitParticleBuilder.java @@ -6,6 +6,12 @@ import org.bukkit.entity.Player; import org.bukkit.material.MaterialData; +/** + * This is used on all modern versions (v1.8.8+) + * + * @deprecated Was only used for 1.8.8 support. + */ +@Deprecated public class BukkitParticleBuilder extends ParticleBuilder { public BukkitParticleBuilder(Particle type, float speed, int amount) { super(type, speed, amount); diff --git a/api/src/main/java/net/techcable/sonarpet/particles/PacketParticleBuilder.java b/api/src/main/java/net/techcable/sonarpet/particles/PacketParticleBuilder.java deleted file mode 100644 index 1fb60fef..00000000 --- a/api/src/main/java/net/techcable/sonarpet/particles/PacketParticleBuilder.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.techcable.sonarpet.particles; - -import com.google.common.base.Preconditions; - -import net.techcable.pineapple.reflection.Reflection; -import net.techcable.sonarpet.utils.reflection.MinecraftReflection; -import net.techcable.sonarpet.utils.reflection.PacketType; - -import org.bukkit.entity.Player; - -public abstract class PacketParticleBuilder extends ParticleBuilder { - public PacketParticleBuilder(Particle type, float speed, int amount) { - super(type, speed, amount); - } - public static final PacketType PARTICLE_PACKET_TYPE = PacketType.forName("PlayOutWorldParticles"); - public void show(Player player) { - Object packet = PARTICLE_PACKET_TYPE.newPacket(); - setupPacket(packet); - Preconditions.checkState(getPosition() != null, "Position not set"); - Preconditions.checkState(getPosition() != null, "Offset not set"); - MinecraftReflection.sendPacket(player, packet); - } - - protected abstract Object getNMSParticleType(); - - protected void setupPacket(Object packet) { - PARTICLE_PACKET_TYPE.putObject(packet, 0, this.getNMSParticleType()); - PARTICLE_PACKET_TYPE.putFloat(packet, 0, (float) getPosition().getX()); - PARTICLE_PACKET_TYPE.putFloat(packet, 1, (float) getPosition().getY()); - PARTICLE_PACKET_TYPE.putFloat(packet, 2, (float) getPosition().getZ()); - PARTICLE_PACKET_TYPE.putFloat(packet, 3, (float) getOffset().getX()); - PARTICLE_PACKET_TYPE.putFloat(packet, 4, (float) getOffset().getY()); - PARTICLE_PACKET_TYPE.putFloat(packet, 5, (float) getOffset().getZ()); - PARTICLE_PACKET_TYPE.putFloat(packet, 6, getSpeed()); - PARTICLE_PACKET_TYPE.putInt(packet, 0, getAmount()); - } -} diff --git a/api/src/main/java/net/techcable/sonarpet/particles/v18ParticleBuilder.java b/api/src/main/java/net/techcable/sonarpet/particles/v18ParticleBuilder.java deleted file mode 100644 index 5e6b9caf..00000000 --- a/api/src/main/java/net/techcable/sonarpet/particles/v18ParticleBuilder.java +++ /dev/null @@ -1,33 +0,0 @@ -package net.techcable.sonarpet.particles; - -import lombok.*; - -import com.dsh105.commodus.reflection.Reflection; - -import org.apache.commons.lang.ArrayUtils; - -@Getter -public class v18ParticleBuilder extends PacketParticleBuilder { - private boolean forced = true; - - public v18ParticleBuilder(Particle type, float speed, int amount) { - super(type, speed, amount); - } - - @Override - protected Object getNMSParticleType() { - Class var6 = Reflection.getNMSClass("EnumParticle"); - return var6.getEnumConstants()[this.getType().getId()]; - } - - @Override - protected void setupPacket(Object packet) { - super.setupPacket(packet); - PARTICLE_PACKET_TYPE.putObject(packet, 1, createData()); - PARTICLE_PACKET_TYPE.putBoolean(packet, 0, isForced()); - } - - private int[] createData() { - return hasBlockData() ? new int[] {getBlockType().getId(), getBlockMeta()} : ArrayUtils.EMPTY_INT_ARRAY; - } -} diff --git a/api/src/main/java/net/techcable/sonarpet/utils/NmsVersion.java b/api/src/main/java/net/techcable/sonarpet/utils/NmsVersion.java index 096a362c..f213f47e 100644 --- a/api/src/main/java/net/techcable/sonarpet/utils/NmsVersion.java +++ b/api/src/main/java/net/techcable/sonarpet/utils/NmsVersion.java @@ -24,11 +24,6 @@ //ToDo: Version Fix Here @Getter public enum NmsVersion { - v1_8_R3, - v1_9_R1, - v1_9_R2, - v1_10_R1, - v1_11_R1, v1_12_R1, v1_13_R2; diff --git a/api/src/main/kotlin/net/techcable/sonarpet/particles/ParticleBuilder.kt b/api/src/main/kotlin/net/techcable/sonarpet/particles/ParticleBuilder.kt index aaae6639..fdeebef4 100644 --- a/api/src/main/kotlin/net/techcable/sonarpet/particles/ParticleBuilder.kt +++ b/api/src/main/kotlin/net/techcable/sonarpet/particles/ParticleBuilder.kt @@ -10,6 +10,7 @@ import org.bukkit.entity.Player import org.bukkit.util.Vector import java.util.* +@Deprecated(message = "Only needed for 1.8.8 compat.....") abstract class ParticleBuilder protected constructor( var type: Particle, var speed: Float = 0f, @@ -73,7 +74,7 @@ abstract class ParticleBuilder protected constructor( v1_12_R1, v1_11_R1, v1_10_R1, v1_9_R1, v1_9_R2, v1_13_R2 -> { BukkitParticleBuilder(type, speed, amount) } - v1_8_R3 -> v18ParticleBuilder(type, speed, amount) + -> v18ParticleBuilder(type, speed, amount) } } } diff --git a/nms/v1_10_R1/build.gradle.kts b/nms/v1_10_R1/build.gradle.kts deleted file mode 100644 index 85acc775..00000000 --- a/nms/v1_10_R1/build.gradle.kts +++ /dev/null @@ -1,4 +0,0 @@ -dependencies { - compileOnly("org.bukkit:craftbukkit:1.10.2-R0.1-SNAPSHOT") - compileOnly(project(":api")) -} diff --git a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/BlockSoundDataImpl.java b/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/BlockSoundDataImpl.java deleted file mode 100644 index 8c81b135..00000000 --- a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/BlockSoundDataImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_10_R1; - -import lombok.*; - -import net.minecraft.server.v1_10_R1.SoundEffectType; -import net.techcable.sonarpet.nms.BlockSoundData; - -@RequiredArgsConstructor -public class BlockSoundDataImpl implements BlockSoundData { - private final SoundEffectType handle; - - @Override - public float getVolume() { - return handle.a(); - } - - @Override - public float getPitch() { - return handle.b(); - } - - @Override - public boolean equals(Object o) { // We need this!! - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - BlockSoundDataImpl that = (BlockSoundDataImpl) o; - - return handle.equals(that.handle); - } - - @Override - public int hashCode() { - return handle.hashCode(); - } -} - diff --git a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/DamageSourceImpl.java b/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/DamageSourceImpl.java deleted file mode 100644 index 58660c8f..00000000 --- a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/DamageSourceImpl.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_10_R1; - -import lombok.*; - -import net.minecraft.server.v1_10_R1.DamageSource; - -@RequiredArgsConstructor -public class DamageSourceImpl implements net.techcable.sonarpet.nms.DamageSource { - @Getter - private final DamageSource handle; -} diff --git a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/DataWatcherImpl.java b/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/DataWatcherImpl.java deleted file mode 100644 index 887a4484..00000000 --- a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/DataWatcherImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_10_R1; - -import lombok.*; - -import net.minecraft.server.v1_10_R1.DataWatcher; -import net.minecraft.server.v1_10_R1.DataWatcherObject; -import net.minecraft.server.v1_10_R1.DataWatcherRegistry; -import net.minecraft.server.v1_10_R1.DataWatcherSerializer; - -@RequiredArgsConstructor -public class DataWatcherImpl implements net.techcable.sonarpet.nms.DataWatcher { - private final DataWatcher dataWatcher; - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - private static final DataWatcherSerializer BOOLEAN_SERIALIZER = DataWatcherRegistry.h; - private static final DataWatcherSerializer INTEGER_SERIALIZER = DataWatcherRegistry.b; - - // - // Deobfuscated methods - // - - @Override - public void setBoolean(int id, boolean value) { - dataWatcher.set(new DataWatcherObject<>(id, BOOLEAN_SERIALIZER), value); - } - - @Override - public void setInteger(int id, int value) { - dataWatcher.set(new DataWatcherObject<>(id, INTEGER_SERIALIZER), value); - } -} diff --git a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSEntityHorseImpl.java b/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSEntityHorseImpl.java deleted file mode 100644 index 899da8c2..00000000 --- a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSEntityHorseImpl.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_10_R1; - -import com.dsh105.echopet.compat.api.entity.HorseType; -import com.dsh105.echopet.compat.api.entity.HorseTypeKt; - -import net.minecraft.server.v1_10_R1.EntityHorse; -import net.techcable.sonarpet.nms.NMSEntityHorse; - -import org.bukkit.entity.Horse; - -public class NMSEntityHorseImpl extends NMSEntityInsentientImpl implements NMSEntityHorse { - public NMSEntityHorseImpl(EntityHorse handle) { - super(handle); - } - - // - // !!!!! Highly version-dependent !!!!! - // Check these every minor update! - // - - @Override - public void setSaddled(boolean saddled) { - getHandle().u(saddled); // EntityHorse.setHorseSaddled - } - - @Override - public boolean isSaddled() { - return getHandle().dz(); // EntityHorse.isHorseSaddled - } - - // - // Breakage likely, check for bugs here - // - - @Override - public void setRearing(boolean b) { - // metadata flag with id 64 - getHandle().v(b); - } - - // Deobfuscated methods - - @Override - public void setStyle(Horse.Style bukkitStyle) { - getBukkitEntity().setStyle(bukkitStyle); - } - - @Override - public void setHorseType(HorseType t) { - getBukkitEntity().setVariant(t.getBukkitVariant()); - } - - @Override - public void setColor(Horse.Color color) { - getBukkitEntity().setColor(color); - } - - @Override - public HorseType getHorseType() { - return HorseTypeKt.getSonarType(getBukkitEntity().getVariant()); - } - - @Override - public void setCarryingChest(boolean flag) { - getBukkitEntity().setCarryingChest(flag); - } - - @Override - public EntityHorse getHandle() { - return (EntityHorse) super.getHandle(); - } - - @Override - public Horse getBukkitEntity() { - return (Horse) super.getBukkitEntity(); - } -} diff --git a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSEntityImpl.java b/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSEntityImpl.java deleted file mode 100644 index e4e37ed5..00000000 --- a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSEntityImpl.java +++ /dev/null @@ -1,70 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_10_R1; - -import lombok.*; - -import java.util.Objects; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.server.v1_10_R1.DamageSource; -import net.minecraft.server.v1_10_R1.Entity; -import net.techcable.sonarpet.nms.INMS; -import net.techcable.sonarpet.nms.NMSEntity; -import net.techcable.sonarpet.nms.NMSLivingEntity; - -import org.bukkit.entity.Player; - -@RequiredArgsConstructor -public class NMSEntityImpl implements NMSEntity { - @Getter - private final Entity handle; - - // - // Deobfuscated methods - // - - @Override - public boolean damageEntity(net.techcable.sonarpet.nms.DamageSource rawSource, float amount) { - DamageSource damageSource = ((DamageSourceImpl) rawSource).getHandle(); - return getHandle().damageEntity(damageSource, amount); - } - - @Override - public org.bukkit.entity.Entity getBukkitEntity() { - return handle.getBukkitEntity(); - } - - @Override - public ImmutableList getPassengers() { - return ImmutableList.copyOf(handle.passengers.stream() - .map(Entity::getBukkitEntity) - .map(INMS.getInstance()::wrapEntity) - .toArray(NMSEntity[]::new)); - } - - @Override - public int hashCode() { - return handle.hashCode(); - } - - @Override - public boolean equals(Object obj) { - return obj != null && obj instanceof NMSEntityImpl && ((NMSEntityImpl) obj).handle.equals(this.handle); - } - - @Override - public String toString() { - if (getBukkitEntity() instanceof Player) { - return "NMSPlayer(" + getBukkitEntity().getName() + ")"; - } else { - StringBuilder builder = new StringBuilder("NMSEntity("); - builder.append(getBukkitEntity().getType()); - if (getBukkitEntity().getCustomName() != null) { - builder.append(":"); - builder.append(getBukkitEntity().getCustomName()); - } - builder.append(')'); - return builder.toString(); - } - } -} diff --git a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSEntityInsentientImpl.java b/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSEntityInsentientImpl.java deleted file mode 100644 index 8f4ddf46..00000000 --- a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSEntityInsentientImpl.java +++ /dev/null @@ -1,125 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_10_R1; - -import lombok.*; - -import java.lang.invoke.MethodHandle; -import java.util.Set; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.server.v1_10_R1.EntityInsentient; -import net.minecraft.server.v1_10_R1.EntityLiving; -import net.minecraft.server.v1_10_R1.GenericAttributes; -import net.minecraft.server.v1_10_R1.Navigation; -import net.minecraft.server.v1_10_R1.PathfinderGoalSelector; -import net.minecraft.server.v1_10_R1.SoundEffect; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.pineapple.reflection.Reflection; -import net.techcable.sonarpet.nms.NMSInsentientEntity; -import net.techcable.sonarpet.nms.NMSSound; - -import org.bukkit.Sound; -import org.bukkit.craftbukkit.v1_10_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_10_R1.entity.CraftLivingEntity; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; - -public class NMSEntityInsentientImpl extends NMSLivingEntityImpl implements NMSInsentientEntity { - - // - // !!!!! Highly version-dependent !!!!! - // Check these every minor update! - // - - private static final MethodHandle GET_DEATH_SOUND_METHOD_HANDLE = Reflection.getMethod( - EntityLiving.class, - "bV" - ); - - - // - // Breakage likely, check for bugs here - // - - @Override - public float getVerticalFaceSpeed() { - return getHandle().N(); - } - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - @Override - public void clearGoals() { - PathfinderGoalSelector goalSelector = getHandle().goalSelector; - ImmutableList> fieldsToClear = PineappleField.findFieldsWithType(PathfinderGoalSelector.class, Set.class); - if (fieldsToClear.size() != 2) { - throw new AssertionError("Unexpected number of fields to clear: " + fieldsToClear); - } - for (PineappleField field : fieldsToClear) { - field.get(goalSelector).clear(); - } - } - - @Override - public void lookAt(Entity other, float perTick, float verticalFaceSpeed) { - getHandle().getControllerLook().a(((CraftEntity) other).getHandle(), perTick, verticalFaceSpeed); - } - - @Override - public void jump() { - getHandle().getControllerJump().a(); - } - - @Override - public void setCanSwim(boolean b) { - ((Navigation) getHandle().getNavigation()).c(b); - } - - // - // Deobfuscated methods :) - // - - @Override - public void setFollowRange(double followRange) { - getHandle().getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(followRange); - } - - @Override - public LivingEntity getTarget() { - EntityLiving entity = getHandle().getGoalTarget(); - return entity != null ? (LivingEntity) entity.getBukkitEntity() : null; - } - - @Override - public void setTarget(LivingEntity target) { - getHandle().setGoalTarget(((CraftLivingEntity) target).getHandle()); - } - - @Override - public net.techcable.sonarpet.nms.Navigation getNavigation() { - return new NavigationImpl((Navigation) getHandle().getNavigation()); - } - - // - // Utility methods and wrappers - // - - @Override - public EntityInsentient getHandle() { - return (EntityInsentient) super.getHandle(); - } - - @Override - @SneakyThrows - public NMSSound getDeathSound() { - SoundEffect soundEffect = (SoundEffect) GET_DEATH_SOUND_METHOD_HANDLE.invoke(getHandle()); - return soundEffect != null ? new NMSSoundImpl(soundEffect) : null; - } - - public NMSEntityInsentientImpl(EntityInsentient handle) { - super(handle); - } -} diff --git a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSEntityRegistry.java b/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSEntityRegistry.java deleted file mode 100644 index fb54bc61..00000000 --- a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSEntityRegistry.java +++ /dev/null @@ -1,70 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_10_R1; - -import java.util.Map; -import java.util.Objects; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.server.v1_10_R1.EntityTypes; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.sonarpet.nms.EntityRegistry; -public class NMSEntityRegistry implements EntityRegistry { - private static final PineappleField, String>> CLASS_TO_NAME_FIELD; - private static final PineappleField>> ID_TO_CLASS_FIELD; - private static final PineappleField, Integer>> CLASS_TO_ID_FIELD; - static { - ImmutableList> mapFields = PineappleField.findFieldsWithType(EntityTypes.class, Map.class); - assert mapFields.size() == 5; - //noinspection unchecked - CLASS_TO_NAME_FIELD = (PineappleField) mapFields.get(1); - //noinspection unchecked - ID_TO_CLASS_FIELD = (PineappleField) mapFields.get(2); - //noinspection unchecked - CLASS_TO_ID_FIELD = (PineappleField) mapFields.get(3); - } - - @Override - public void registerEntityClass(Class entityClass, String name, int id) { - CLASS_TO_NAME_FIELD.getStatic().put(entityClass, name); - CLASS_TO_ID_FIELD.getStatic().put(entityClass, id); - } - - @Override - public void unregisterEntityClass(Class entityClass, String name, int id) { - String actualName = CLASS_TO_NAME_FIELD.getStatic().remove(entityClass); - Integer actualId = CLASS_TO_ID_FIELD.getStatic().remove(entityClass); - if (!Objects.equals(name, actualName)) { - throw new IllegalArgumentException("Expected name " + name + " didn't equal actual name " + Objects.toString(actualName)); - } else if (actualId == null || actualId != id) { - throw new IllegalArgumentException("Expected id " + id + " didn't equal actual id " + Objects.toString(actualId)); - } - } - - @Override - public Class getEntityClass(int id) { - return ID_TO_CLASS_FIELD.getStatic().get(id); - } - - @Override - public int getEntityId(Class entityClass) { - return CLASS_TO_ID_FIELD.getStatic().get(entityClass); - } - - @Override - public String getEntityName(Class entityClass) { - return CLASS_TO_NAME_FIELD.getStatic().get(entityClass); - } - - @Override - public void registerEntityId(int id, Class entityClass) { - ID_TO_CLASS_FIELD.getStatic().put(id, entityClass); - } - - @Override - public void unregisterEntityId(int id, Class entityClass) { - Class actualEntityClass = ID_TO_CLASS_FIELD.getStatic().remove(id); - if (!Objects.equals(actualEntityClass, entityClass)) { - throw new IllegalArgumentException("Exepcted entity class " + entityClass + " didn't equal actual entity class " + Objects.toString(actualEntityClass)); - } - } -} diff --git a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSImpl.java b/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSImpl.java deleted file mode 100644 index cfa43b1c..00000000 --- a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSImpl.java +++ /dev/null @@ -1,137 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_10_R1; - -import net.minecraft.server.v1_10_R1.EntityHorse; -import net.minecraft.server.v1_10_R1.EntityInsentient; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.sonarpet.nms.DismountingBlocked; -import net.techcable.sonarpet.nms.EntityRegistry; -import net.techcable.sonarpet.nms.INMS; -import com.google.common.collect.ImmutableMap; - -import net.minecraft.server.v1_10_R1.Block; -import net.minecraft.server.v1_10_R1.DamageSource; -import net.minecraft.server.v1_10_R1.EntityHuman; -import net.minecraft.server.v1_10_R1.EntityLiving; -import net.minecraft.server.v1_10_R1.EntityPlayer; -import net.minecraft.server.v1_10_R1.Packet; -import net.minecraft.server.v1_10_R1.PacketPlayOutMount; -import net.minecraft.server.v1_10_R1.SoundEffect; -import net.minecraft.server.v1_10_R1.SoundEffectType; -import net.techcable.sonarpet.item.SpawnEggItemData; -import net.techcable.sonarpet.nms.BlockSoundData; -import net.techcable.sonarpet.nms.NMSEntity; -import net.techcable.sonarpet.nms.NMSInsentientEntity; -import net.techcable.sonarpet.nms.NMSSound; -import net.techcable.sonarpet.nms.versions.v1_10_R1.data.NMSSpawnEggItemData; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.craftbukkit.v1_10_R1.CraftSound; -import org.bukkit.craftbukkit.v1_10_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_10_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_10_R1.entity.CraftLivingEntity; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.material.SpawnEgg; - -import static com.google.common.base.Preconditions.*; - -public class NMSImpl implements INMS { - @Override - public SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta) { - checkNotNull(entityType, "Null entity type"); - checkNotNull(meta, "Null item meta"); - return new NMSSpawnEggItemData(new SpawnEgg(entityType).getData(), meta, entityType); // Pretend we use metadata to make the code happy - } - - @Override - public void mount(Entity bukkitRider, Entity bukkitVehicle) { - net.minecraft.server.v1_10_R1.Entity rider = ((CraftEntity) bukkitRider).getHandle(); - if (bukkitVehicle == null) { - net.minecraft.server.v1_10_R1.Entity vehicle = rider.getVehicle(); // This is how you *really* get the vehicle :/ - if (rider instanceof DismountingBlocked) { - ((DismountingBlocked) rider).reallyStopRiding();; - } - rider.stopRiding(); - if (vehicle != null) { - Packet packet = new PacketPlayOutMount(vehicle); - for (EntityHuman human : rider.world.players) { - ((EntityPlayer) human).playerConnection.sendPacket(packet); - } - } - } else { - checkArgument(bukkitRider.getWorld().equals(bukkitVehicle.getWorld()), "Rider is in world %s, while vehicle is in world %s", bukkitRider.getWorld().getName(), bukkitVehicle.getWorld().getName()); - net.minecraft.server.v1_10_R1.Entity vehicle = ((CraftEntity) bukkitVehicle).getHandle(); - rider.a(vehicle, true); // !! Obfuscated !! - Packet packet = new PacketPlayOutMount(vehicle); - for (EntityHuman human : rider.world.players) { - ((EntityPlayer) human).playerConnection.sendPacket(packet); - } - } - } - - @Override - public boolean spawnEntity(NMSInsentientEntity wrapper, Location l) { - EntityLiving entity = ((NMSEntityInsentientImpl) wrapper).getHandle(); - entity.spawnIn(((CraftWorld) l.getWorld()).getHandle()); - ((LivingEntity) entity.getBukkitEntity()).setCollidable(false); - entity.setLocation(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch()); - if (!l.getChunk().isLoaded()) { - l.getChunk().load(); - } - return entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); - } - - @Override - public net.techcable.sonarpet.nms.DamageSource mobAttackDamageSource(LivingEntity entity) { - return new DamageSourceImpl(DamageSource.mobAttack(((CraftLivingEntity) entity).getHandle())); - } - - @Override - public net.techcable.sonarpet.nms.DamageSource wrapDamageSource(Object handle) { - return new DamageSourceImpl((DamageSource) handle); - } - - @Override - public NMSEntity wrapEntity(Entity entity) { - net.minecraft.server.v1_10_R1.Entity handle = ((CraftEntity) entity).getHandle(); - if (handle instanceof EntityPlayer) { - return new NMSPlayerImpl((EntityPlayer) handle); - } else if (handle instanceof EntityHorse) { - return new NMSEntityHorseImpl((EntityHorse) handle); - } else if (handle instanceof EntityInsentient) { - return new NMSEntityInsentientImpl((EntityInsentient) handle); - } else if (handle instanceof EntityLiving) { - return new NMSLivingEntityImpl((EntityLiving) handle); - } else { - return new NMSEntityImpl(handle); - } - } - - private PineappleField STEP_SOUND_FIELD = PineappleField.create(Block.class, "stepSound", SoundEffectType.class); - @Override - @SuppressWarnings("deprecation") // I know about ur stupid magic value warning mom - public BlockSoundData getBlockSoundData(Material material) { - return new BlockSoundDataImpl(STEP_SOUND_FIELD.get(Block.getById(material.getId()))); - } - - @Override - @SuppressWarnings("deprecation") // I know about ur stupid magic value warning mom - public boolean isLiquid(Material block) { - return Block.getById(block.getId()).getBlockData().getMaterial().isLiquid(); - } - - @Override - public EntityRegistry createDefaultEntityRegistry() { - return new NMSEntityRegistry(); - } - - @Override - public NMSSound getNmsSound(Sound bukkitSound) { - return new NMSSoundImpl(NMSSoundImplKt.getSoundEffect(bukkitSound)); - } -} diff --git a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSLivingEntityImpl.java b/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSLivingEntityImpl.java deleted file mode 100644 index 3a91f156..00000000 --- a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSLivingEntityImpl.java +++ /dev/null @@ -1,181 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_10_R1; - -import net.minecraft.server.v1_10_R1.EntityHuman; -import net.minecraft.server.v1_10_R1.EntityLiving; -import net.minecraft.server.v1_10_R1.SoundEffect; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.sonarpet.nms.DataWatcher; -import net.techcable.sonarpet.nms.NMSLivingEntity; -import net.techcable.sonarpet.nms.NMSSound; - -import org.bukkit.Sound; -import org.bukkit.craftbukkit.v1_10_R1.CraftSound; -import org.bukkit.craftbukkit.v1_10_R1.entity.CraftEntity; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; - -public class NMSLivingEntityImpl extends NMSEntityImpl implements NMSLivingEntity { - - // - // !!!!! Highly version-dependent !!!!! - // Check these every minor update! - // - public static final String IS_JUMPING_FIELD_NAME = "be"; - - public NMSLivingEntityImpl(EntityLiving handle) { - super(handle); - } - - /** - * Set the 'offsets' for pitch and yaw to the same value as the yaw itself. - * Apparently this is needed to set rotation. - * See EntityLiving.h(FF) for details (method profiler 'headTurn'). - * Note that EntityInsentient overrides h(FF) and delegates to 'EntityAIBodyControl'. - * 'EntityAIBodyControl' is what actually accesses/uses these fields and where the mappings should be fetched. - *

- * Also, these fields have the MCP names 'renderYawOffset' and 'rotationYawHead' - */ - @Override - public void correctYaw() { - getHandle().aO = getHandle().aQ = getHandle().yaw; - } - - @Override - public boolean isInLava() { - return getHandle().aO(); - } - - // - // Breakage likely, check for bugs here - // - - @Override - public void setMoveSpeed(double rideSpeed) { - getHandle().l((float) rideSpeed); - } - - @Override - public void setStepHeight(float stepHeight) { - getHandle().P = stepHeight; - } - - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - @Override - public void playSound(NMSSound sound, float volume, float pitch) { - getHandle().a(((NMSSoundImpl) sound).getHandle(), volume, pitch); - } - - @Override - public double distanceTo(Entity other) { - return getHandle().h(((CraftEntity) other).getHandle()); - } - - - // - // Deobfuscated methods :) - // - - @Override - public Player findNearbyPlayer(double range) { - EntityHuman player = getHandle().world.findNearbyPlayer(getHandle(), range); - return player == null ? null : (Player) player.getBukkitEntity(); - } - - @Override - public boolean isInvisible() { - return getHandle().isInvisible(); - } - - @Override - public boolean isSneaking() { - return getHandle().isSneaking(); - } - - @Override - public void setSneaking(boolean b) { - getHandle().setSneaking(b); - } - - @Override - public void setInvisible(boolean b) { - getHandle().setInvisible(b); - } - - @Override - public boolean isSprinting() { - return getHandle().isSprinting(); - } - - @Override - public void setSprinting(boolean b) { - getHandle().setSprinting(b); - } - - @Override - public void setYaw(float yaw) { - getHandle().yaw = yaw; - } - - @Override - public void setPitch(float pitch) { - getHandle().pitch = pitch; - } - - @Override - public void setNoClip(boolean b) { - getHandle().noclip = b; - } - - @Override - public boolean isInWater() { - return getHandle().isInWater(); - } - - - @Override - public void setUpwardsMotion(double motY) { - getHandle().motY = motY; - } - - @Override - public DataWatcher getDataWatcher() { - return new DataWatcherImpl(getHandle().getDataWatcher()); - } - - @Override - public double getWidth() { - return getHandle().width; - } - - @Override - public double getLength() { - return getHandle().length; - } - - // - // Utility methods and wrappers - // - - private static final PineappleField IS_JUMPING_FIELD = PineappleField.create(EntityLiving.class, IS_JUMPING_FIELD_NAME, boolean.class); - - @Override - public boolean isJumping() { - return IS_JUMPING_FIELD.getBoxed(getHandle()); - } - - @Override - public EntityLiving getHandle() { - return (EntityLiving) super.getHandle(); - } - - @Override - public LivingEntity getBukkitEntity() { - return (LivingEntity) getHandle().getBukkitEntity(); - } -} diff --git a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSPlayerImpl.java b/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSPlayerImpl.java deleted file mode 100644 index 5812d767..00000000 --- a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSPlayerImpl.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_10_R1; - -import net.minecraft.server.v1_10_R1.EntityPlayer; -import net.techcable.sonarpet.nms.NMSPlayer; - -import org.bukkit.entity.Player; - -public class NMSPlayerImpl extends NMSLivingEntityImpl implements NMSPlayer { - public NMSPlayerImpl(EntityPlayer handle) { - super(handle); - } - - @Override - public boolean isOnGround() { - return getHandle().onGround; - } - - @Override - public EntityPlayer getHandle() { - return (EntityPlayer) super.getHandle(); - } - - @Override - public Player getBukkitEntity() { - return (Player) super.getBukkitEntity(); - } -} diff --git a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NavigationImpl.java b/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NavigationImpl.java deleted file mode 100644 index 80a73da3..00000000 --- a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/NavigationImpl.java +++ /dev/null @@ -1,54 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_10_R1; - -import lombok.*; - -import net.minecraft.server.v1_10_R1.Navigation; -import net.techcable.sonarpet.nms.PathEntity; - -import org.bukkit.craftbukkit.v1_10_R1.entity.CraftEntity; -import org.bukkit.entity.Entity; - -@RequiredArgsConstructor -public class NavigationImpl implements net.techcable.sonarpet.nms.Navigation { - private final Navigation handle; - - - // - // Breakage likely, check for bugs here - // - - @Override - public boolean canEnterDoors() { - return handle.f(); - } - - @Override - public void finish() { - handle.n(); - } - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - @Override - public PathEntity getPathToLocation(int blockX, int blockY, int blockZ) { - return new PathEntityImpl(handle.a(blockX, blockY, blockZ)); - } - - @Override - public PathEntity getPathTo(Entity other) { - return new PathEntityImpl(handle.a(((CraftEntity) other).getHandle())); - } - - @Override - public void navigateTo(PathEntity path, double speed) { - handle.a(((PathEntityImpl) path).handle, speed); - } - - @RequiredArgsConstructor - private static class PathEntityImpl implements PathEntity { - /* package */ final net.minecraft.server.v1_10_R1.PathEntity handle; - } -} diff --git a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/data/NMSSpawnEggItemData.java b/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/data/NMSSpawnEggItemData.java deleted file mode 100644 index 1ca0fece..00000000 --- a/nms/v1_10_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_10_R1/data/NMSSpawnEggItemData.java +++ /dev/null @@ -1,86 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_10_R1.data; - -import java.util.Optional; - -import com.google.common.base.Preconditions; - -import net.minecraft.server.v1_10_R1.EntityTypes; -import net.minecraft.server.v1_10_R1.Item; -import net.minecraft.server.v1_10_R1.ItemStack; -import net.minecraft.server.v1_10_R1.NBTTagCompound; -import net.techcable.sonarpet.item.SpawnEggItemData; - -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.craftbukkit.v1_10_R1.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_10_R1.util.CraftMagicNumbers; -import org.bukkit.entity.EntityType; -import org.bukkit.inventory.meta.ItemMeta; - -public class NMSSpawnEggItemData extends SpawnEggItemData { - public NMSSpawnEggItemData(byte rawData, ItemMeta meta) { - this(rawData, meta, SpawnEggItemData.DEFAULT_TYPE); - } - - public NMSSpawnEggItemData(byte rawData, ItemMeta meta, EntityType type) { - super(Material.MONSTER_EGG, rawData, createMetaWithEntityType(meta, type)); - } - - @Override - public EntityType getSpawnedType() { - return getSpawnEggEntityType(this.getMeta()); - } - - public static EntityType getSpawnEggEntityType(ItemMeta meta) { - Preconditions.checkNotNull(meta, "Null meta"); - NBTTagCompound tag = getTagFromMeta(Material.MONSTER_EGG, meta); - Preconditions.checkState(tag != null, "No nbt tag"); - Preconditions.checkState(tag.hasKeyOfType("EntityTag", 10), "No entity tag"); - NBTTagCompound entityTag = tag.getCompound("EntityTag"); - Preconditions.checkState(entityTag.hasKeyOfType("id", 8), "No internal name"); - String internalName = entityTag.getString("id"); - int id = EntityTypes.a(internalName); - EntityType type = EntityType.fromId(id); - if (type == null) - throw new IllegalStateException("No entity found with internal name " + internalName + " and id " + id); - return type; - } - - public static Optional getSpawnEggEntityTypeIfPresent(ItemMeta meta) { - try { - return Optional.of(getSpawnEggEntityType(meta)); - } catch (IllegalArgumentException | IllegalStateException e) { - return Optional.empty(); - } - } - - public static ItemMeta createMetaWithEntityType(ItemMeta meta, EntityType entityType) { - NBTTagCompound entityTag = new NBTTagCompound(); - String internalName = EntityTypes.getName(EntityTypes.a(entityType.getTypeId())); - if (internalName == null) throw new AssertionError("Couldn't find internal name for type: " + entityType); - entityTag.setString("id", internalName); - NBTTagCompound tag = getTagFromMeta(Material.MONSTER_EGG, Preconditions.checkNotNull(meta, "Null meta")); - if (tag == null) tag = new NBTTagCompound(); - tag.set("EntityTag", entityTag); - return createMetaFromTag(Material.MONSTER_EGG, tag); - } - - - public static ItemMeta createMetaFromTag(Material type, NBTTagCompound tag) { - Item item = CraftMagicNumbers.getItem(Preconditions.checkNotNull(type, "Null type")); - ItemStack stack = new ItemStack(item); - stack.setTag(Preconditions.checkNotNull(tag, "Null nbt tag")); - return CraftItemStack.getItemMeta(stack); - } - - public static NBTTagCompound getTagFromMeta(Material type, ItemMeta meta) { - Preconditions.checkNotNull(meta, "Null meta"); - Preconditions.checkNotNull(type, "Null type"); - Preconditions.checkArgument(Bukkit.getItemFactory().isApplicable(meta, type), "Meta %s isn't applicable to %s", meta, type); - Item item = CraftMagicNumbers.getItem(type); - ItemStack stack = new ItemStack(item); - boolean worked = CraftItemStack.setItemMeta(stack, meta); - if (!worked) throw new RuntimeException("Didn't work"); - return stack.getTag(); - } -} diff --git a/nms/v1_10_R1/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSSoundImpl.kt b/nms/v1_10_R1/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSSoundImpl.kt deleted file mode 100644 index 9ce7ac31..00000000 --- a/nms/v1_10_R1/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_10_R1/NMSSoundImpl.kt +++ /dev/null @@ -1,21 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_10_R1 - -import net.minecraft.server.v1_10_R1.SoundEffect -import net.techcable.sonarpet.nms.NMSSound -import net.techcable.sonarpet.utils.buildImmutableMap -import org.bukkit.Sound -import org.bukkit.craftbukkit.v1_10_R1.CraftSound - -private val BUKKIT_SOUNDS = buildImmutableMap { - for (sound in enumValues()) { - put(sound.soundEffect, sound) - } -} - -val Sound.soundEffect: SoundEffect - get() = CraftSound.getSoundEffect(CraftSound.getSound(this))!! - -class NMSSoundImpl(val handle: SoundEffect): NMSSound { - override val bukkitSound: Sound? - get() = BUKKIT_SOUNDS[handle] -} \ No newline at end of file diff --git a/nms/v1_11_R1/build.gradle.kts b/nms/v1_11_R1/build.gradle.kts deleted file mode 100644 index 35aaabfd..00000000 --- a/nms/v1_11_R1/build.gradle.kts +++ /dev/null @@ -1,4 +0,0 @@ -dependencies { - compileOnly("org.bukkit:craftbukkit:1.11-R0.1-SNAPSHOT") - compileOnly(project(":api")) -} diff --git a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/BlockSoundDataImpl.java b/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/BlockSoundDataImpl.java deleted file mode 100644 index 14ca9cce..00000000 --- a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/BlockSoundDataImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_11_R1; - -import lombok.*; - -import net.minecraft.server.v1_11_R1.SoundEffectType; -import net.techcable.sonarpet.nms.BlockSoundData; - -@RequiredArgsConstructor -public class BlockSoundDataImpl implements BlockSoundData { - private final SoundEffectType handle; - - @Override - public float getVolume() { - return handle.a(); - } - - @Override - public float getPitch() { - return handle.b(); - } - - @Override - public boolean equals(Object o) { // We need this!! - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - BlockSoundDataImpl that = (BlockSoundDataImpl) o; - - return handle.equals(that.handle); - } - - @Override - public int hashCode() { - return handle.hashCode(); - } -} - diff --git a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/DamageSourceImpl.java b/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/DamageSourceImpl.java deleted file mode 100644 index 84a92464..00000000 --- a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/DamageSourceImpl.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_11_R1; - -import lombok.*; - -import net.minecraft.server.v1_11_R1.DamageSource; - -@RequiredArgsConstructor -public class DamageSourceImpl implements net.techcable.sonarpet.nms.DamageSource { - @Getter - private final DamageSource handle; -} diff --git a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/DataWatcherImpl.java b/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/DataWatcherImpl.java deleted file mode 100644 index 4e3624f6..00000000 --- a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/DataWatcherImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_11_R1; - -import lombok.*; - -import net.minecraft.server.v1_11_R1.DataWatcher; -import net.minecraft.server.v1_11_R1.DataWatcherObject; -import net.minecraft.server.v1_11_R1.DataWatcherRegistry; -import net.minecraft.server.v1_11_R1.DataWatcherSerializer; - -@RequiredArgsConstructor -public class DataWatcherImpl implements net.techcable.sonarpet.nms.DataWatcher { - private final DataWatcher dataWatcher; - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - private static final DataWatcherSerializer BOOLEAN_SERIALIZER = DataWatcherRegistry.h; - private static final DataWatcherSerializer INTEGER_SERIALIZER = DataWatcherRegistry.b; - - // - // Deobfuscated methods - // - - @Override - public void setBoolean(int id, boolean value) { - dataWatcher.set(new DataWatcherObject<>(id, BOOLEAN_SERIALIZER), value); - } - - @Override - public void setInteger(int id, int value) { - dataWatcher.set(new DataWatcherObject<>(id, INTEGER_SERIALIZER), value); - } -} diff --git a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSEntityHorseImpl.java b/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSEntityHorseImpl.java deleted file mode 100644 index 15f0232b..00000000 --- a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSEntityHorseImpl.java +++ /dev/null @@ -1,75 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_11_R1; - -import com.dsh105.echopet.compat.api.entity.HorseType; -import com.dsh105.echopet.compat.api.entity.HorseTypeKt; - -import net.minecraft.server.v1_11_R1.EntityHorseAbstract; -import net.techcable.sonarpet.nms.NMSEntityHorse; - -import org.bukkit.entity.AbstractHorse; -import org.bukkit.entity.ChestedHorse; -import org.bukkit.entity.Horse; - -public class NMSEntityHorseImpl extends NMSEntityInsentientImpl implements NMSEntityHorse { - public NMSEntityHorseImpl(EntityHorseAbstract handle) { - super(handle); - } - - // - // !!!!! Highly version-dependent !!!!! - // Check these every minor update! - // - - @Override - public void setSaddled(boolean saddled) { - getHandle().t(saddled); // AbstractHorse.setHorseSaddled - } - - @Override - public boolean isSaddled() { - return getHandle().dB(); // AbstractHorse.isHorseSaddled - } - - // Deobfuscated methods - - @Override - public void setRearing(boolean b) { - getHandle().setStanding(b); - } - - @Override - public void setStyle(Horse.Style bukkitStyle) { - if (getBukkitEntity() instanceof Horse) { - ((Horse) getBukkitEntity()).setStyle(bukkitStyle); - } - } - - @Override - public void setColor(Horse.Color color) { - if (getBukkitEntity() instanceof Horse) { - ((Horse) getBukkitEntity()).setColor(color); - } - } - - @Override - public HorseType getHorseType() { - return HorseTypeKt.getSonarType(getBukkitEntity().getVariant()); - } - - @Override - public void setCarryingChest(boolean flag) { - if (getBukkitEntity() instanceof ChestedHorse) { - ((ChestedHorse) getBukkitEntity()).setCarryingChest(flag); - } - } - - @Override - public EntityHorseAbstract getHandle() { - return (EntityHorseAbstract) super.getHandle(); - } - - @Override - public AbstractHorse getBukkitEntity() { - return (AbstractHorse) super.getBukkitEntity(); - } -} diff --git a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSEntityImpl.java b/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSEntityImpl.java deleted file mode 100644 index fd98933c..00000000 --- a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSEntityImpl.java +++ /dev/null @@ -1,67 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_11_R1; - -import lombok.*; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.server.v1_11_R1.DamageSource; -import net.minecraft.server.v1_11_R1.Entity; -import net.techcable.sonarpet.nms.INMS; -import net.techcable.sonarpet.nms.NMSEntity; - -import org.bukkit.entity.Player; - -@RequiredArgsConstructor -public class NMSEntityImpl implements NMSEntity { - @Getter - private final Entity handle; - - // - // Deobfuscated methods - // - - @Override - public boolean damageEntity(net.techcable.sonarpet.nms.DamageSource rawSource, float amount) { - DamageSource damageSource = ((DamageSourceImpl) rawSource).getHandle(); - return getHandle().damageEntity(damageSource, amount); - } - - @Override - public org.bukkit.entity.Entity getBukkitEntity() { - return handle.getBukkitEntity(); - } - - @Override - public ImmutableList getPassengers() { - return ImmutableList.copyOf(handle.passengers.stream() - .map(Entity::getBukkitEntity) - .map(INMS.getInstance()::wrapEntity) - .toArray(NMSEntity[]::new)); - } - - @Override - public int hashCode() { - return handle.hashCode(); - } - - @Override - public boolean equals(Object obj) { - return obj != null && obj instanceof NMSEntityImpl && ((NMSEntityImpl) obj).handle.equals(this.handle); - } - - @Override - public String toString() { - if (getBukkitEntity() instanceof Player) { - return "NMSPlayer(" + getBukkitEntity().getName() + ")"; - } else { - StringBuilder builder = new StringBuilder("NMSEntity("); - builder.append(getBukkitEntity().getType()); - if (getBukkitEntity().getCustomName() != null) { - builder.append(":"); - builder.append(getBukkitEntity().getCustomName()); - } - builder.append(')'); - return builder.toString(); - } - } -} diff --git a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSEntityInsentientImpl.java b/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSEntityInsentientImpl.java deleted file mode 100644 index 46bce34f..00000000 --- a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSEntityInsentientImpl.java +++ /dev/null @@ -1,125 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_11_R1; - -import lombok.*; - -import java.lang.invoke.MethodHandle; -import java.util.Set; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.server.v1_11_R1.EntityInsentient; -import net.minecraft.server.v1_11_R1.EntityLiving; -import net.minecraft.server.v1_11_R1.GenericAttributes; -import net.minecraft.server.v1_11_R1.Navigation; -import net.minecraft.server.v1_11_R1.PathfinderGoalSelector; -import net.minecraft.server.v1_11_R1.SoundEffect; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.pineapple.reflection.Reflection; -import net.techcable.sonarpet.nms.NMSInsentientEntity; -import net.techcable.sonarpet.nms.NMSSound; - -import org.bukkit.Sound; -import org.bukkit.craftbukkit.v1_11_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_11_R1.entity.CraftLivingEntity; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; - -public class NMSEntityInsentientImpl extends NMSLivingEntityImpl implements NMSInsentientEntity { - - // - // !!!!! Highly version-dependent !!!!! - // Check these every minor update! - // - - private static final MethodHandle GET_DEATH_SOUND_METHOD_HANDLE = Reflection.getMethod( - EntityLiving.class, - "bW" // EntityLivingBase.getHurtSound - ); - - - // - // Breakage likely, check for bugs here - // - - @Override - public float getVerticalFaceSpeed() { - return getHandle().N(); - } - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - @Override - public void clearGoals() { - PathfinderGoalSelector goalSelector = getHandle().goalSelector; - ImmutableList> fieldsToClear = PineappleField.findFieldsWithType(PathfinderGoalSelector.class, Set.class); - if (fieldsToClear.size() != 2) { - throw new AssertionError("Unexpected number of fields to clear: " + fieldsToClear); - } - for (PineappleField field : fieldsToClear) { - field.get(goalSelector).clear(); - } - } - - @Override - public void lookAt(Entity other, float perTick, float verticalFaceSpeed) { - getHandle().getControllerLook().a(((CraftEntity) other).getHandle(), perTick, verticalFaceSpeed); - } - - @Override - public void jump() { - getHandle().getControllerJump().a(); - } - - @Override - public void setCanSwim(boolean b) { - ((Navigation) getHandle().getNavigation()).c(b); - } - - // - // Deobfuscated methods :) - // - - @Override - public void setFollowRange(double followRange) { - getHandle().getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(followRange); - } - - @Override - public LivingEntity getTarget() { - EntityLiving entity = getHandle().getGoalTarget(); - return entity != null ? (LivingEntity) entity.getBukkitEntity() : null; - } - - @Override - public void setTarget(LivingEntity target) { - getHandle().setGoalTarget(((CraftLivingEntity) target).getHandle()); - } - - @Override - public net.techcable.sonarpet.nms.Navigation getNavigation() { - return new NavigationImpl((Navigation) getHandle().getNavigation()); - } - - // - // Utility methods and wrappers - // - - @Override - public EntityInsentient getHandle() { - return (EntityInsentient) super.getHandle(); - } - - @Override - @SneakyThrows - public NMSSound getDeathSound() { - SoundEffect soundEffect = (SoundEffect) GET_DEATH_SOUND_METHOD_HANDLE.invoke(getHandle()); - return soundEffect != null ? new NMSSoundImpl(soundEffect) : null; - } - - public NMSEntityInsentientImpl(EntityInsentient handle) { - super(handle); - } -} diff --git a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSEntityRegistry.java b/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSEntityRegistry.java deleted file mode 100644 index 704b5808..00000000 --- a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSEntityRegistry.java +++ /dev/null @@ -1,63 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_11_R1; - -import lombok.*; - -import java.lang.invoke.MethodHandle; - -import net.minecraft.server.v1_11_R1.Entity; -import net.minecraft.server.v1_11_R1.EntityTypes; -import net.minecraft.server.v1_11_R1.MinecraftKey; -import net.minecraft.server.v1_11_R1.RegistryID; -import net.minecraft.server.v1_11_R1.RegistryMaterials; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.pineapple.reflection.Reflection; -import net.techcable.sonarpet.nms.EntityRegistry; - -public class NMSEntityRegistry implements EntityRegistry { - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - @SuppressWarnings("unchecked") - private final PineappleField>, RegistryID>> REGISTRY_ID_FIELD = - (PineappleField) PineappleField.findFieldWithType(RegistryMaterials.class, RegistryID.class); - private final MethodHandle REGISTER_ENTITY_METHOD = - Reflection.getMethod(EntityTypes.class, "a", int.class, String.class, Class.class, String.class); // EntityList.register - - @Override - @SneakyThrows - public void registerEntityClass(Class entityClass, String name, int id) { - REGISTER_ENTITY_METHOD.invokeExact(id, name, entityClass, name); - } - - @Override - public void unregisterEntityClass(Class entityClass, String name, int id) { - // TODO: unregister - } - - @Override - public Class getEntityClass(int id) { - return REGISTRY_ID_FIELD.get(EntityTypes.b).fromId(id); - } - - @Override - public int getEntityId(Class entityClass) { - return REGISTRY_ID_FIELD.get(EntityTypes.b).getId(entityClass); - } - - @Override - public String getEntityName(Class entityClass) { - return EntityTypes.getName(entityClass.asSubclass(Entity.class)).a(); - } - - @Override - public void registerEntityId(int id, Class entityClass) { - REGISTRY_ID_FIELD.get(EntityTypes.b).a(entityClass, id); // IntIdentityHashBiMap.put - } - - @Override - public void unregisterEntityId(int id, Class entityClass) { - REGISTRY_ID_FIELD.get(EntityTypes.b).a(null, id); // IntIdentityHashBiMap.put - } -} diff --git a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSImpl.java b/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSImpl.java deleted file mode 100644 index 7c4cdd34..00000000 --- a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSImpl.java +++ /dev/null @@ -1,138 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_11_R1; - -import com.google.common.collect.ImmutableMap; - -import net.minecraft.server.v1_11_R1.Block; -import net.minecraft.server.v1_11_R1.DamageSource; -import net.minecraft.server.v1_11_R1.EntityHorseAbstract; -import net.minecraft.server.v1_11_R1.EntityHuman; -import net.minecraft.server.v1_11_R1.EntityInsentient; -import net.minecraft.server.v1_11_R1.EntityLiving; -import net.minecraft.server.v1_11_R1.EntityPlayer; -import net.minecraft.server.v1_11_R1.Packet; -import net.minecraft.server.v1_11_R1.PacketPlayOutMount; -import net.minecraft.server.v1_11_R1.SoundEffect; -import net.minecraft.server.v1_11_R1.SoundEffectType; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.sonarpet.item.SpawnEggItemData; -import net.techcable.sonarpet.nms.BlockSoundData; -import net.techcable.sonarpet.nms.DismountingBlocked; -import net.techcable.sonarpet.nms.EntityRegistry; -import net.techcable.sonarpet.nms.INMS; -import net.techcable.sonarpet.nms.NMSEntity; -import net.techcable.sonarpet.nms.NMSInsentientEntity; -import net.techcable.sonarpet.nms.NMSSound; -import net.techcable.sonarpet.nms.versions.v1_11_R1.data.NMSSpawnEggItemData; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.craftbukkit.v1_11_R1.CraftSound; -import org.bukkit.craftbukkit.v1_11_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_11_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_11_R1.entity.CraftLivingEntity; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.material.SpawnEgg; - -import static com.google.common.base.Preconditions.*; - -public class NMSImpl implements INMS { - - @Override - public SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta) { - checkNotNull(entityType, "Null entity type"); - checkNotNull(meta, "Null item meta"); - return new NMSSpawnEggItemData(new SpawnEgg(entityType).getData(), meta, entityType); // Pretend we use metadata to make the code happy - } - - @Override - public void mount(Entity bukkitRider, Entity bukkitVehicle) { - net.minecraft.server.v1_11_R1.Entity rider = ((CraftEntity) bukkitRider).getHandle(); - if (bukkitVehicle == null) { - net.minecraft.server.v1_11_R1.Entity vehicle = rider.getVehicle(); // This is how you *really* get the vehicle :/ - if (rider instanceof DismountingBlocked) { - ((DismountingBlocked) rider).reallyStopRiding();; - } - rider.stopRiding(); - if (vehicle != null) { - Packet packet = new PacketPlayOutMount(vehicle); - for (EntityHuman human : rider.world.players) { - ((EntityPlayer) human).playerConnection.sendPacket(packet); - } - } - } else { - checkArgument(bukkitRider.getWorld().equals(bukkitVehicle.getWorld()), "Rider is in world %s, while vehicle is in world %s", bukkitRider.getWorld().getName(), bukkitVehicle.getWorld().getName()); - net.minecraft.server.v1_11_R1.Entity vehicle = ((CraftEntity) bukkitVehicle).getHandle(); - rider.a(vehicle, true); // !! Obfuscated !! - Packet packet = new PacketPlayOutMount(vehicle); - for (EntityHuman human : rider.world.players) { - ((EntityPlayer) human).playerConnection.sendPacket(packet); - } - } - } - - @Override - public boolean spawnEntity(NMSInsentientEntity wrapper, Location l) { - EntityLiving entity = ((NMSEntityInsentientImpl) wrapper).getHandle(); - entity.spawnIn(((CraftWorld) l.getWorld()).getHandle()); - ((LivingEntity) entity.getBukkitEntity()).setCollidable(false); - entity.setLocation(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch()); - if (!l.getChunk().isLoaded()) { - l.getChunk().load(); - } - return entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); - } - - @Override - public net.techcable.sonarpet.nms.DamageSource mobAttackDamageSource(LivingEntity entity) { - return new DamageSourceImpl(DamageSource.mobAttack(((CraftLivingEntity) entity).getHandle())); - } - - @Override - public net.techcable.sonarpet.nms.DamageSource wrapDamageSource(Object handle) { - return new DamageSourceImpl((DamageSource) handle); - } - - @Override - public NMSEntity wrapEntity(Entity entity) { - net.minecraft.server.v1_11_R1.Entity handle = ((CraftEntity) entity).getHandle(); - if (handle instanceof EntityPlayer) { - return new NMSPlayerImpl((EntityPlayer) handle); - } else if (handle instanceof EntityHorseAbstract) { - return new NMSEntityHorseImpl((EntityHorseAbstract) handle); - } else if (handle instanceof EntityInsentient) { - return new NMSEntityInsentientImpl((EntityInsentient) handle); - } else if (handle instanceof EntityLiving) { - return new NMSLivingEntityImpl((EntityLiving) handle); - } else { - return new NMSEntityImpl(handle); - } - } - - private PineappleField STEP_SOUND_FIELD = PineappleField.create(Block.class, "stepSound", SoundEffectType.class); - @Override - @SuppressWarnings("deprecation") // I know about ur stupid magic value warning mom - public BlockSoundData getBlockSoundData(Material material) { - return new BlockSoundDataImpl(STEP_SOUND_FIELD.get(Block.getById(material.getId()))); - } - - @Override - @SuppressWarnings("deprecation") // I know about ur stupid magic value warning mom - public boolean isLiquid(Material block) { - return Block.getById(block.getId()).getBlockData().getMaterial().isLiquid(); - } - - @Override - public EntityRegistry createDefaultEntityRegistry() { - return new NMSEntityRegistry(); - } - - @Override - public NMSSound getNmsSound(Sound bukkitSound) { - return new NMSSoundImpl(NMSSoundImplKt.getSoundEffect(bukkitSound)); - } -} diff --git a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSLivingEntityImpl.java b/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSLivingEntityImpl.java deleted file mode 100644 index f526cfb7..00000000 --- a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSLivingEntityImpl.java +++ /dev/null @@ -1,181 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_11_R1; - -import net.minecraft.server.v1_11_R1.EntityHuman; -import net.minecraft.server.v1_11_R1.EntityLiving; -import net.minecraft.server.v1_11_R1.SoundEffect; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.sonarpet.nms.DataWatcher; -import net.techcable.sonarpet.nms.NMSLivingEntity; -import net.techcable.sonarpet.nms.NMSSound; - -import org.bukkit.Sound; -import org.bukkit.craftbukkit.v1_11_R1.CraftSound; -import org.bukkit.craftbukkit.v1_11_R1.entity.CraftEntity; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; - -public class NMSLivingEntityImpl extends NMSEntityImpl implements NMSLivingEntity { - - // - // !!!!! Highly version-dependent !!!!! - // Check these every minor update! - // - public static final String IS_JUMPING_FIELD_NAME = "bd"; // EntityLivingBase.isJumping - - public NMSLivingEntityImpl(EntityLiving handle) { - super(handle); - } - - /** - * Set the 'offsets' for pitch and yaw to the same value as the yaw itself. - * Apparently this is needed to set rotation. - * See EntityLiving.h(FF) for details (method profiler 'headTurn'). - * Note that EntityInsentient overrides h(FF) and delegates to 'EntityAIBodyControl'. - * 'EntityAIBodyControl' is what actually accesses/uses these fields and where the mappings should be fetched. - *

- * Also, these fields have the MCP names 'renderYawOffset' and 'rotationYawHead' - */ - @Override - public void correctYaw() { - getHandle().aN = getHandle().aP = getHandle().yaw; - } - - @Override - public boolean isInLava() { - return getHandle().ao(); // Entity.isInLava - } - - // - // Breakage likely, check for bugs here - // - - @Override - public void setMoveSpeed(double rideSpeed) { - getHandle().l((float) rideSpeed); - } - - @Override - public void setStepHeight(float stepHeight) { - getHandle().P = stepHeight; - } - - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - @Override - public void playSound(NMSSound sound, float volume, float pitch) { - getHandle().a(((NMSSoundImpl) sound).getHandle(), volume, pitch); - } - - @Override - public double distanceTo(Entity other) { - return getHandle().h(((CraftEntity) other).getHandle()); - } - - - // - // Deobfuscated methods :) - // - - @Override - public Player findNearbyPlayer(double range) { - EntityHuman player = getHandle().world.findNearbyPlayer(getHandle(), range); - return player == null ? null : (Player) player.getBukkitEntity(); - } - - @Override - public boolean isInvisible() { - return getHandle().isInvisible(); - } - - @Override - public boolean isSneaking() { - return getHandle().isSneaking(); - } - - @Override - public void setSneaking(boolean b) { - getHandle().setSneaking(b); - } - - @Override - public void setInvisible(boolean b) { - getHandle().setInvisible(b); - } - - @Override - public boolean isSprinting() { - return getHandle().isSprinting(); - } - - @Override - public void setSprinting(boolean b) { - getHandle().setSprinting(b); - } - - @Override - public void setYaw(float yaw) { - getHandle().yaw = yaw; - } - - @Override - public void setPitch(float pitch) { - getHandle().pitch = pitch; - } - - @Override - public void setNoClip(boolean b) { - getHandle().noclip = b; - } - - @Override - public boolean isInWater() { - return getHandle().isInWater(); - } - - - @Override - public void setUpwardsMotion(double motY) { - getHandle().motY = motY; - } - - @Override - public DataWatcher getDataWatcher() { - return new DataWatcherImpl(getHandle().getDataWatcher()); - } - - @Override - public double getWidth() { - return getHandle().width; - } - - @Override - public double getLength() { - return getHandle().length; - } - - // - // Utility methods and wrappers - // - - private static final PineappleField IS_JUMPING_FIELD = PineappleField.create(EntityLiving.class, IS_JUMPING_FIELD_NAME, boolean.class); - - @Override - public boolean isJumping() { - return IS_JUMPING_FIELD.getBoxed(getHandle()); - } - - @Override - public EntityLiving getHandle() { - return (EntityLiving) super.getHandle(); - } - - @Override - public LivingEntity getBukkitEntity() { - return (LivingEntity) getHandle().getBukkitEntity(); - } -} diff --git a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSPlayerImpl.java b/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSPlayerImpl.java deleted file mode 100644 index fe1d80a9..00000000 --- a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSPlayerImpl.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_11_R1; - -import net.minecraft.server.v1_11_R1.EntityPlayer; -import net.techcable.sonarpet.nms.NMSPlayer; - -import org.bukkit.entity.Player; - -public class NMSPlayerImpl extends NMSLivingEntityImpl implements NMSPlayer { - public NMSPlayerImpl(EntityPlayer handle) { - super(handle); - } - - @Override - public boolean isOnGround() { - return getHandle().onGround; - } - - @Override - public EntityPlayer getHandle() { - return (EntityPlayer) super.getHandle(); - } - - @Override - public Player getBukkitEntity() { - return (Player) super.getBukkitEntity(); - } -} diff --git a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NavigationImpl.java b/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NavigationImpl.java deleted file mode 100644 index 1bac4766..00000000 --- a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/NavigationImpl.java +++ /dev/null @@ -1,54 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_11_R1; - -import lombok.*; - -import net.minecraft.server.v1_11_R1.Navigation; -import net.techcable.sonarpet.nms.PathEntity; - -import org.bukkit.craftbukkit.v1_11_R1.entity.CraftEntity; -import org.bukkit.entity.Entity; - -@RequiredArgsConstructor -public class NavigationImpl implements net.techcable.sonarpet.nms.Navigation { - private final Navigation handle; - - - // - // Breakage likely, check for bugs here - // - - @Override - public boolean canEnterDoors() { - return handle.f(); // PathNavigateGround.getEnterDoors - } - - @Override - public void finish() { - handle.n(); // PathNavigate.noPath - } - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - @Override - public PathEntity getPathToLocation(int blockX, int blockY, int blockZ) { - return new PathEntityImpl(handle.a(blockX, blockY, blockZ)); - } - - @Override - public PathEntity getPathTo(Entity other) { - return new PathEntityImpl(handle.a(((CraftEntity) other).getHandle())); - } - - @Override - public void navigateTo(PathEntity path, double speed) { - handle.a(((PathEntityImpl) path).handle, speed); - } - - @RequiredArgsConstructor - private static class PathEntityImpl implements PathEntity { - /* package */ final net.minecraft.server.v1_11_R1.PathEntity handle; - } -} diff --git a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/data/NMSSpawnEggItemData.java b/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/data/NMSSpawnEggItemData.java deleted file mode 100644 index b172e25f..00000000 --- a/nms/v1_11_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_11_R1/data/NMSSpawnEggItemData.java +++ /dev/null @@ -1,87 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_11_R1.data; - -import java.util.Optional; - -import com.google.common.base.Preconditions; - -import net.minecraft.server.v1_11_R1.EntityTypes; -import net.minecraft.server.v1_11_R1.Item; -import net.minecraft.server.v1_11_R1.ItemStack; -import net.minecraft.server.v1_11_R1.MinecraftKey; -import net.minecraft.server.v1_11_R1.NBTTagCompound; -import net.techcable.sonarpet.item.SpawnEggItemData; - -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.craftbukkit.v1_11_R1.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_11_R1.util.CraftMagicNumbers; -import org.bukkit.entity.EntityType; -import org.bukkit.inventory.meta.ItemMeta; - -public class NMSSpawnEggItemData extends SpawnEggItemData { - public NMSSpawnEggItemData(byte rawData, ItemMeta meta) { - this(rawData, meta, SpawnEggItemData.DEFAULT_TYPE); - } - - public NMSSpawnEggItemData(byte rawData, ItemMeta meta, EntityType type) { - super(Material.MONSTER_EGG, rawData, createMetaWithEntityType(meta, type)); - } - - @Override - public EntityType getSpawnedType() { - return getSpawnEggEntityType(this.getMeta()); - } - - public static EntityType getSpawnEggEntityType(ItemMeta meta) { - Preconditions.checkNotNull(meta, "Null meta"); - NBTTagCompound tag = getTagFromMeta(Material.MONSTER_EGG, meta); - Preconditions.checkState(tag != null, "No nbt tag"); - Preconditions.checkState(tag.hasKeyOfType("EntityTag", 10), "No entity tag"); - NBTTagCompound entityTag = tag.getCompound("EntityTag"); - Preconditions.checkState(entityTag.hasKeyOfType("id", 8), "No internal name"); - String internalName = entityTag.getString("id"); - int id = EntityTypes.b.a(EntityTypes.b.get(new MinecraftKey(internalName))); - EntityType type = EntityType.fromId(id); - if (type == null) - throw new IllegalStateException("No entity found with internal name " + internalName + " and id " + id); - return type; - } - - public static Optional getSpawnEggEntityTypeIfPresent(ItemMeta meta) { - try { - return Optional.of(getSpawnEggEntityType(meta)); - } catch (IllegalArgumentException | IllegalStateException e) { - return Optional.empty(); - } - } - - public static ItemMeta createMetaWithEntityType(ItemMeta meta, EntityType entityType) { - NBTTagCompound entityTag = new NBTTagCompound(); - String internalName = EntityTypes.getName(EntityTypes.b.getId(entityType.getTypeId())).b(); - if (internalName == null) throw new AssertionError("Couldn't find internal name for type: " + entityType); - entityTag.setString("id", internalName); - NBTTagCompound tag = getTagFromMeta(Material.MONSTER_EGG, Preconditions.checkNotNull(meta, "Null meta")); - if (tag == null) tag = new NBTTagCompound(); - tag.set("EntityTag", entityTag); - return createMetaFromTag(Material.MONSTER_EGG, tag); - } - - - public static ItemMeta createMetaFromTag(Material type, NBTTagCompound tag) { - Item item = CraftMagicNumbers.getItem(Preconditions.checkNotNull(type, "Null type")); - ItemStack stack = new ItemStack(item); - stack.setTag(Preconditions.checkNotNull(tag, "Null nbt tag")); - return CraftItemStack.getItemMeta(stack); - } - - public static NBTTagCompound getTagFromMeta(Material type, ItemMeta meta) { - Preconditions.checkNotNull(meta, "Null meta"); - Preconditions.checkNotNull(type, "Null type"); - Preconditions.checkArgument(Bukkit.getItemFactory().isApplicable(meta, type), "Meta %s isn't applicable to %s", meta, type); - Item item = CraftMagicNumbers.getItem(type); - ItemStack stack = new ItemStack(item); - boolean worked = CraftItemStack.setItemMeta(stack, meta); - if (!worked) throw new RuntimeException("Didn't work"); - return stack.getTag(); - } -} diff --git a/nms/v1_11_R1/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSSoundImpl.kt b/nms/v1_11_R1/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSSoundImpl.kt deleted file mode 100644 index df0e1bcf..00000000 --- a/nms/v1_11_R1/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_11_R1/NMSSoundImpl.kt +++ /dev/null @@ -1,21 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_11_R1 - -import net.minecraft.server.v1_11_R1.SoundEffect -import net.techcable.sonarpet.nms.NMSSound -import net.techcable.sonarpet.utils.buildImmutableMap -import org.bukkit.Sound -import org.bukkit.craftbukkit.v1_11_R1.CraftSound - -private val BUKKIT_SOUNDS = buildImmutableMap { - for (sound in enumValues()) { - put(sound.soundEffect, sound) - } -} - -val Sound.soundEffect: SoundEffect - get() = CraftSound.getSoundEffect(CraftSound.getSound(this))!! - -class NMSSoundImpl(val handle: SoundEffect): NMSSound { - override val bukkitSound: Sound? - get() = BUKKIT_SOUNDS[handle] -} \ No newline at end of file diff --git a/nms/v1_8_R3/build.gradle.kts b/nms/v1_8_R3/build.gradle.kts deleted file mode 100644 index 958dbb0a..00000000 --- a/nms/v1_8_R3/build.gradle.kts +++ /dev/null @@ -1,4 +0,0 @@ -dependencies { - compileOnly("org.bukkit:craftbukkit:1.8.4-R0.1-SNAPSHOT") - compileOnly(project(":api")) -} diff --git a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/BlockSoundDataImpl.java b/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/BlockSoundDataImpl.java deleted file mode 100644 index 87efe4dc..00000000 --- a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/BlockSoundDataImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_8_R3; - -import lombok.*; - -import net.minecraft.server.v1_8_R3.Block; -import net.techcable.sonarpet.nms.BlockSoundData; - -@RequiredArgsConstructor -public class BlockSoundDataImpl implements BlockSoundData { - private final Block.StepSound handle; - - @Override - public float getVolume() { - return handle.getVolume1(); - } - - @Override - public float getPitch() { - return handle.getVolume2(); - } - - @Override - public boolean equals(Object o) { // We need this!! - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - BlockSoundDataImpl that = (BlockSoundDataImpl) o; - - return handle.equals(that.handle); - } - - @Override - public int hashCode() { - return handle.hashCode(); - } -} - diff --git a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/DamageSourceImpl.java b/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/DamageSourceImpl.java deleted file mode 100644 index ca1970b0..00000000 --- a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/DamageSourceImpl.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_8_R3; - -import lombok.*; - -import net.minecraft.server.v1_8_R3.DamageSource; - -@RequiredArgsConstructor -public class DamageSourceImpl implements net.techcable.sonarpet.nms.DamageSource { - @Getter - private final DamageSource handle; -} diff --git a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/DataWatcherImpl.java b/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/DataWatcherImpl.java deleted file mode 100644 index a1e01476..00000000 --- a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/DataWatcherImpl.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_8_R3; - -import lombok.*; - -import net.minecraft.server.v1_8_R3.DataWatcher; - -@RequiredArgsConstructor -public class DataWatcherImpl implements net.techcable.sonarpet.nms.DataWatcher { - private final DataWatcher dataWatcher; - - // - // Deobfuscated methods - // - - @Override - public void setBoolean(int id, boolean value) { - dataWatcher.watch(id, (byte) (value ? 1 : 0)); - } - - @Override - public void setInteger(int id, int value) { - dataWatcher.watch(id, value); - } -} diff --git a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSEntityHorseImpl.java b/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSEntityHorseImpl.java deleted file mode 100644 index 741e8609..00000000 --- a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSEntityHorseImpl.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_8_R3; - -import com.dsh105.echopet.compat.api.entity.HorseType; -import com.dsh105.echopet.compat.api.entity.HorseTypeKt; - -import net.minecraft.server.v1_8_R3.EntityHorse; -import net.techcable.sonarpet.nms.NMSEntityHorse; - -import org.bukkit.entity.Horse; - -public class NMSEntityHorseImpl extends NMSEntityInsentientImpl implements NMSEntityHorse { - public NMSEntityHorseImpl(EntityHorse handle) { - super(handle); - } - - // - // !!!!! Highly version-dependent !!!!! - // Check these every minor update! - // - - @Override - public void setSaddled(boolean saddled) { - getHandle().q(saddled); // EntityHorse.setHorseSaddled - } - - @Override - public boolean isSaddled() { - return getHandle().cG(); // EntityHorse.isHorseSaddled - } - - // - // Breakage likely, check for bugs here - // - - @Override - public void setRearing(boolean b) { - // metadata flag with id 64 - getHandle().s(b); - } - - // Deobfuscated methods - - @Override - public void setStyle(Horse.Style bukkitStyle) { - getBukkitEntity().setStyle(bukkitStyle); - } - - @Override - public void setHorseType(HorseType t) { - getBukkitEntity().setVariant(t.getBukkitVariant()); - } - - @Override - public void setColor(Horse.Color color) { - getBukkitEntity().setColor(color); - } - - @Override - public HorseType getHorseType() { - return HorseTypeKt.getSonarType(getBukkitEntity().getVariant()); - } - - @Override - public void setCarryingChest(boolean flag) { - getBukkitEntity().setCarryingChest(flag); - } - - @Override - public EntityHorse getHandle() { - return (EntityHorse) super.getHandle(); - } - - @Override - public Horse getBukkitEntity() { - return (Horse) super.getBukkitEntity(); - } -} diff --git a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSEntityImpl.java b/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSEntityImpl.java deleted file mode 100644 index d46030b5..00000000 --- a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSEntityImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_8_R3; - -import lombok.*; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.server.v1_8_R3.DamageSource; -import net.minecraft.server.v1_8_R3.Entity; -import net.techcable.sonarpet.nms.INMS; -import net.techcable.sonarpet.nms.NMSEntity; - -import org.bukkit.entity.Player; - -@RequiredArgsConstructor -public class NMSEntityImpl implements NMSEntity { - @Getter - private final Entity handle; - - // - // Deobfuscated methods - // - - @Override - public boolean damageEntity(net.techcable.sonarpet.nms.DamageSource rawSource, float amount) { - DamageSource damageSource = ((DamageSourceImpl) rawSource).getHandle(); - return getHandle().damageEntity(damageSource, amount); - } - - @Override - public org.bukkit.entity.Entity getBukkitEntity() { - return handle.getBukkitEntity(); - } - - @Override - public ImmutableList getPassengers() { - if (handle.passenger != null) { - return ImmutableList.of(INMS.getInstance().wrapEntity(handle.passenger.getBukkitEntity())); - } else { - return ImmutableList.of(); - } - } - - @Override - public int hashCode() { - return handle.hashCode(); - } - - @Override - public boolean equals(Object obj) { - return obj != null && obj instanceof NMSEntityImpl && ((NMSEntityImpl) obj).handle.equals(this.handle); - } - - @Override - public String toString() { - if (getBukkitEntity() instanceof Player) { - return "NMSPlayer(" + getBukkitEntity().getName() + ")"; - } else { - StringBuilder builder = new StringBuilder("NMSEntity("); - builder.append(getBukkitEntity().getType()); - if (getBukkitEntity().getCustomName() != null) { - builder.append(":"); - builder.append(getBukkitEntity().getCustomName()); - } - builder.append(')'); - return builder.toString(); - } - } -} diff --git a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSEntityInsentientImpl.java b/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSEntityInsentientImpl.java deleted file mode 100644 index 7372ec61..00000000 --- a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSEntityInsentientImpl.java +++ /dev/null @@ -1,123 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_8_R3; - -import lombok.*; - -import java.lang.invoke.MethodHandle; -import java.util.List; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.server.v1_8_R3.EntityInsentient; -import net.minecraft.server.v1_8_R3.EntityLiving; -import net.minecraft.server.v1_8_R3.GenericAttributes; -import net.minecraft.server.v1_8_R3.Navigation; -import net.minecraft.server.v1_8_R3.PathfinderGoalSelector; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.pineapple.reflection.Reflection; -import net.techcable.sonarpet.nms.NMSInsentientEntity; -import net.techcable.sonarpet.nms.NMSSound; - -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftLivingEntity; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; - -public class NMSEntityInsentientImpl extends NMSLivingEntityImpl implements NMSInsentientEntity { - - // - // !!!!! Highly version-dependent !!!!! - // Check these every minor update! - // - - private static final MethodHandle GET_DEATH_SOUND_METHOD_HANDLE = Reflection.getMethod( - EntityLiving.class, - "bo" - ); - - - // - // Breakage likely, check for bugs here - // - - @Override - public float getVerticalFaceSpeed() { - return getHandle().bQ(); - } - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - @Override - public void clearGoals() { - PathfinderGoalSelector goalSelector = getHandle().goalSelector; - ImmutableList> fieldsToClear = PineappleField.findFieldsWithType(PathfinderGoalSelector.class, List.class); - if (fieldsToClear.size() != 2) { - throw new AssertionError("Unexpected number of fields to clear: " + fieldsToClear); - } - for (PineappleField field : fieldsToClear) { - field.get(goalSelector).clear(); - } - } - - @Override - public void lookAt(Entity other, float perTick, float verticalFaceSpeed) { - getHandle().getControllerLook().a(((CraftEntity) other).getHandle(), perTick, verticalFaceSpeed); - } - - @Override - public void jump() { - getHandle().getControllerJump().a(); - } - - @Override - public void setCanSwim(boolean b) { - ((Navigation) getHandle().getNavigation()).c(b); - } - - // - // Deobfuscated methods :) - // - - @Override - public void setFollowRange(double followRange) { - getHandle().getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(followRange); - } - - @Override - public LivingEntity getTarget() { - EntityLiving entity = getHandle().getGoalTarget(); - return entity != null ? (LivingEntity) entity.getBukkitEntity() : null; - } - - @Override - public void setTarget(LivingEntity target) { - getHandle().setGoalTarget(((CraftLivingEntity) target).getHandle()); - } - - @Override - public net.techcable.sonarpet.nms.Navigation getNavigation() { - return new NavigationImpl((Navigation) getHandle().getNavigation()); - } - - // - // Utility methods and wrappers - // - - @Override - public EntityInsentient getHandle() { - return (EntityInsentient) super.getHandle(); - } - - @Override - @SneakyThrows - public NMSSound getDeathSound() { - String soundEffect = (String) GET_DEATH_SOUND_METHOD_HANDLE.invoke(getHandle()); - return soundEffect != null ? new NMSSoundImpl(soundEffect) : null; - } - - public NMSEntityInsentientImpl(EntityInsentient handle) { - super(handle); - } -} diff --git a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSEntityRegistry.java b/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSEntityRegistry.java deleted file mode 100644 index 0abf89be..00000000 --- a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSEntityRegistry.java +++ /dev/null @@ -1,72 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_8_R3; - -import java.util.Map; -import java.util.Objects; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.server.v1_8_R3.EntityTypes; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.sonarpet.nms.EntityRegistry; - -public class NMSEntityRegistry implements EntityRegistry { - private static final PineappleField, String>> CLASS_TO_NAME_FIELD; - private static final PineappleField>> ID_TO_CLASS_FIELD; - private static final PineappleField, Integer>> CLASS_TO_ID_FIELD; - - static { - ImmutableList> mapFields = PineappleField.findFieldsWithType(EntityTypes.class, Map.class); - assert mapFields.size() == 6; - //noinspection unchecked - CLASS_TO_NAME_FIELD = (PineappleField) mapFields.get(1); - //noinspection unchecked - ID_TO_CLASS_FIELD = (PineappleField) mapFields.get(2); - //noinspection unchecked - CLASS_TO_ID_FIELD = (PineappleField) mapFields.get(3); - } - - @Override - public void registerEntityClass(Class entityClass, String name, int id) { - CLASS_TO_NAME_FIELD.getStatic().put(entityClass, name); - CLASS_TO_ID_FIELD.getStatic().put(entityClass, id); - } - - @Override - public void unregisterEntityClass(Class entityClass, String name, int id) { - String actualName = CLASS_TO_NAME_FIELD.getStatic().remove(entityClass); - Integer actualId = CLASS_TO_ID_FIELD.getStatic().remove(entityClass); - if (!Objects.equals(name, actualName)) { - throw new IllegalArgumentException("Expected name " + name + " didn't equal actual name " + Objects.toString(actualName)); - } else if (actualId == null || actualId != id) { - throw new IllegalArgumentException("Expected id " + id + " didn't equal actual id " + Objects.toString(actualId)); - } - } - - @Override - public Class getEntityClass(int id) { - return ID_TO_CLASS_FIELD.getStatic().get(id); - } - - @Override - public int getEntityId(Class entityClass) { - return CLASS_TO_ID_FIELD.getStatic().get(entityClass); - } - - @Override - public String getEntityName(Class entityClass) { - return CLASS_TO_NAME_FIELD.getStatic().get(entityClass); - } - - @Override - public void registerEntityId(int id, Class entityClass) { - ID_TO_CLASS_FIELD.getStatic().put(id, entityClass); - } - - @Override - public void unregisterEntityId(int id, Class entityClass) { - Class actualEntityClass = ID_TO_CLASS_FIELD.getStatic().remove(id); - if (!Objects.equals(actualEntityClass, entityClass)) { - throw new IllegalArgumentException("Expected entity class " + entityClass + " didn't equal actual entity class " + Objects.toString(actualEntityClass)); - } - } -} diff --git a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSImpl.java b/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSImpl.java deleted file mode 100644 index 0e189c8f..00000000 --- a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSImpl.java +++ /dev/null @@ -1,90 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_8_R3; - -import javax.annotation.Nullable; - -import net.minecraft.server.v1_8_R3.EntityHorse; -import net.minecraft.server.v1_8_R3.EntityInsentient; -import net.minecraft.server.v1_8_R3.EntityPlayer; -import net.techcable.sonarpet.nms.EntityRegistry; -import net.techcable.sonarpet.nms.INMS; -import com.google.common.collect.ImmutableMap; - -import net.minecraft.server.v1_8_R3.Block; -import net.minecraft.server.v1_8_R3.DamageSource; -import net.minecraft.server.v1_8_R3.EntityLiving; -import net.techcable.sonarpet.nms.BlockSoundData; -import net.techcable.sonarpet.nms.NMSEntity; -import net.techcable.sonarpet.nms.NMSInsentientEntity; -import net.techcable.sonarpet.nms.NMSSound; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.craftbukkit.v1_8_R3.CraftSound; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftLivingEntity; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.entity.CreatureSpawnEvent; - -public class NMSImpl implements INMS { - @Override - public boolean spawnEntity(NMSInsentientEntity wrapper, Location l) { - EntityLiving entity = ((NMSEntityInsentientImpl) wrapper).getHandle(); - entity.spawnIn(((CraftWorld) l.getWorld()).getHandle()); - entity.setLocation(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch()); - if (!l.getChunk().isLoaded()) { - l.getChunk().load(); - } - return entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); - } - - @Override - public net.techcable.sonarpet.nms.DamageSource mobAttackDamageSource(LivingEntity entity) { - return new DamageSourceImpl(DamageSource.mobAttack(((CraftLivingEntity) entity).getHandle())); - } - - @Override - public net.techcable.sonarpet.nms.DamageSource wrapDamageSource(Object handle) { - return new DamageSourceImpl((DamageSource) handle); - } - - @Override - public NMSEntity wrapEntity(Entity entity) { - net.minecraft.server.v1_8_R3.Entity handle = ((CraftEntity) entity).getHandle(); - if (handle instanceof EntityPlayer) { - return new NMSPlayerImpl((EntityPlayer) handle); - } else if (handle instanceof EntityHorse) { - return new NMSEntityHorseImpl((EntityHorse) handle); - } else if (handle instanceof EntityInsentient) { - return new NMSEntityInsentientImpl((EntityInsentient) handle); - } else if (handle instanceof EntityLiving) { - return new NMSLivingEntityImpl((EntityLiving) handle); - } else { - return new NMSEntityImpl(handle); - } - } - - @Override - @SuppressWarnings("deprecation") // I know about ur stupid magic value warning mom - public BlockSoundData getBlockSoundData(Material material) { - return new BlockSoundDataImpl(Block.getById(material.getId()).stepSound); - } - - @Override - @SuppressWarnings("deprecation") // I know about ur stupid magic value warning mom - public boolean isLiquid(Material block) { - return Block.getById(block.getId()).getMaterial().isLiquid(); - } - - @Override - public EntityRegistry createDefaultEntityRegistry() { - return new NMSEntityRegistry(); - } - - @Override - public NMSSound getNmsSound(Sound bukkitSound) { - return new NMSSoundImpl(NMSSoundImplKt.getInternalName(bukkitSound)); - } -} diff --git a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSLivingEntityImpl.java b/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSLivingEntityImpl.java deleted file mode 100644 index 30b2c7fe..00000000 --- a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSLivingEntityImpl.java +++ /dev/null @@ -1,178 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_8_R3; - -import net.minecraft.server.v1_8_R3.EntityHuman; -import net.minecraft.server.v1_8_R3.EntityLiving; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.sonarpet.nms.DataWatcher; -import net.techcable.sonarpet.nms.NMSLivingEntity; -import net.techcable.sonarpet.nms.NMSSound; - -import org.bukkit.Sound; -import org.bukkit.craftbukkit.v1_8_R3.CraftSound; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; - -public class NMSLivingEntityImpl extends NMSEntityImpl implements NMSLivingEntity { - - // - // !!!!! Highly version-dependent !!!!! - // Check these every minor update! - // - public static final String IS_JUMPING_FIELD_NAME = "aY"; - - public NMSLivingEntityImpl(EntityLiving handle) { - super(handle); - } - - /** - * Set the 'offsets' for pitch and yaw to the same value as the yaw itself. - * Apparently this is needed to set rotation. - * See EntityLiving.h(FF) for details (method profiler 'headTurn'). - * Note that EntityInsentient overrides h(FF) and delegates to 'EntityAIBodyControl'. - * 'EntityAIBodyControl' is what actually accesses/uses these fields and where the mappings should be fetched. - *

- * Also, these fields have the MCP names 'renderYawOffset' and 'rotationYawHead' - */ - @Override - public void correctYaw() { - getHandle().aK = getHandle().aI = getHandle().yaw; - } - - @Override - public boolean isInLava() { - return getHandle().ab(); - } - - // - // Breakage likely, check for bugs here - // - - @Override - public void setMoveSpeed(double rideSpeed) { - getHandle().k((float) rideSpeed); - } - - @Override - public void setStepHeight(float stepHeight) { - getHandle().S = stepHeight; - } - - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - @Override - public boolean isInWater() { - return getHandle().V(); - } - - @Override - public double distanceTo(Entity other) { - return getHandle().h(((CraftEntity) other).getHandle()); - } - - // - // Deobfuscated methods :) - // - - @Override - public void playSound(NMSSound sound, float volume, float pitch) { - getHandle().makeSound(((NMSSoundImpl) sound).getInternalName(), volume, pitch); - } - - @Override - public Player findNearbyPlayer(double range) { - EntityHuman player = getHandle().world.findNearbyPlayer(getHandle(), range); - return player == null ? null : (Player) player.getBukkitEntity(); - } - - @Override - public boolean isInvisible() { - return getHandle().isInvisible(); - } - - @Override - public boolean isSneaking() { - return getHandle().isSneaking(); - } - - @Override - public void setSneaking(boolean b) { - getHandle().setSneaking(b); - } - - @Override - public void setInvisible(boolean b) { - getHandle().setInvisible(b); - } - - @Override - public boolean isSprinting() { - return getHandle().isSprinting(); - } - - @Override - public void setSprinting(boolean b) { - getHandle().setSprinting(b); - } - - @Override - public void setYaw(float yaw) { - getHandle().yaw = yaw; - } - - @Override - public void setPitch(float pitch) { - getHandle().pitch = pitch; - } - - @Override - public void setNoClip(boolean b) { - getHandle().noclip = b; - } - - @Override - public void setUpwardsMotion(double motY) { - getHandle().motY = motY; - } - - @Override - public DataWatcher getDataWatcher() { - return new DataWatcherImpl(getHandle().getDataWatcher()); - } - - @Override - public double getWidth() { - return getHandle().width; - } - - @Override - public double getLength() { - return getHandle().length; - } - - // - // Utility methods and wrappers - // - - private static final PineappleField IS_JUMPING_FIELD = PineappleField.create(EntityLiving.class, IS_JUMPING_FIELD_NAME, boolean.class); - - @Override - public boolean isJumping() { - return IS_JUMPING_FIELD.getBoxed(getHandle()); - } - - @Override - public EntityLiving getHandle() { - return (EntityLiving) super.getHandle(); - } - - @Override - public LivingEntity getBukkitEntity() { - return (LivingEntity) getHandle().getBukkitEntity(); - } -} diff --git a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSPlayerImpl.java b/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSPlayerImpl.java deleted file mode 100644 index 725a1478..00000000 --- a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSPlayerImpl.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_8_R3; - -import net.minecraft.server.v1_8_R3.EntityPlayer; -import net.techcable.sonarpet.nms.NMSPlayer; - -import org.bukkit.entity.Player; - -public class NMSPlayerImpl extends NMSLivingEntityImpl implements NMSPlayer { - public NMSPlayerImpl(EntityPlayer handle) { - super(handle); - } - - @Override - public boolean isOnGround() { - return getHandle().onGround; - } - - @Override - public EntityPlayer getHandle() { - return (EntityPlayer) super.getHandle(); - } - - @Override - public Player getBukkitEntity() { - return (Player) super.getBukkitEntity(); - } -} diff --git a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NavigationImpl.java b/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NavigationImpl.java deleted file mode 100644 index ec66f9a8..00000000 --- a/nms/v1_8_R3/src/main/java/net/techcable/sonarpet/nms/versions/v1_8_R3/NavigationImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_8_R3; - -import lombok.*; - -import net.minecraft.server.v1_8_R3.Navigation; -import net.techcable.sonarpet.nms.PathEntity; - -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; -import org.bukkit.entity.Entity; - -@RequiredArgsConstructor -public class NavigationImpl implements net.techcable.sonarpet.nms.Navigation { - private final Navigation handle; - - // - // Breakage likely, check for bugs here - // - - @Override - public boolean canEnterDoors() { - return handle.g(); - } - - @Override - public void finish() { - handle.n(); - } - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - @Override - public PathEntity getPathToLocation(int blockX, int blockY, int blockZ) { - return new PathEntityImpl(handle.a(blockX, blockY, blockZ)); - } - - @Override - public PathEntity getPathTo(Entity other) { - return new PathEntityImpl(handle.a(((CraftEntity) other).getHandle())); - } - - @Override - public void navigateTo(PathEntity path, double speed) { - handle.a(((PathEntityImpl) path).handle, speed); - } - - @RequiredArgsConstructor - private static class PathEntityImpl implements PathEntity { - /* package */ final net.minecraft.server.v1_8_R3.PathEntity handle; - } -} diff --git a/nms/v1_8_R3/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSSoundImpl.kt b/nms/v1_8_R3/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSSoundImpl.kt deleted file mode 100644 index 2d2cf2ff..00000000 --- a/nms/v1_8_R3/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_8_R3/NMSSoundImpl.kt +++ /dev/null @@ -1,20 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_8_R3 - -import net.techcable.sonarpet.nms.NMSSound -import net.techcable.sonarpet.utils.buildImmutableMap -import org.bukkit.Sound -import org.bukkit.craftbukkit.v1_8_R3.CraftSound - -private val BUKKIT_SOUNDS = buildImmutableMap { - for (sound in enumValues()) { - put(sound.internalName, sound) - } -} - -val Sound.internalName: String - get() = CraftSound.getSound(this)!! - -class NMSSoundImpl(val internalName: String): NMSSound { - override val bukkitSound: Sound? - get() = BUKKIT_SOUNDS[internalName] -} \ No newline at end of file diff --git a/nms/v1_9_R1/build.gradle.kts b/nms/v1_9_R1/build.gradle.kts deleted file mode 100644 index 1feed895..00000000 --- a/nms/v1_9_R1/build.gradle.kts +++ /dev/null @@ -1,7 +0,0 @@ -dependencies { - compileOnly("org.bukkit:bukkit:1.9-R0.1-SNAPSHOT") // Override the version of bukkit - compileOnly("org.bukkit:craftbukkit:1.9-R0.1-SNAPSHOT") { - exclude(mapOf("module" to "bukkit")) - } - compileOnly(project(":api")) -} diff --git a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/BlockSoundDataImpl.java b/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/BlockSoundDataImpl.java deleted file mode 100644 index c72409a5..00000000 --- a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/BlockSoundDataImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R1; - -import lombok.*; - -import net.minecraft.server.v1_9_R1.SoundEffectType; -import net.techcable.sonarpet.nms.BlockSoundData; - -@RequiredArgsConstructor -public class BlockSoundDataImpl implements BlockSoundData { - private final SoundEffectType handle; - - @Override - public float getVolume() { - return handle.a(); - } - - @Override - public float getPitch() { - return handle.b(); - } - - @Override - public boolean equals(Object o) { // We need this!! - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - BlockSoundDataImpl that = (BlockSoundDataImpl) o; - - return handle.equals(that.handle); - } - - @Override - public int hashCode() { - return handle.hashCode(); - } -} - diff --git a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/DamageSourceImpl.java b/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/DamageSourceImpl.java deleted file mode 100644 index a6dd75fd..00000000 --- a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/DamageSourceImpl.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R1; - -import lombok.*; - -import net.minecraft.server.v1_9_R1.DamageSource; - -@RequiredArgsConstructor -public class DamageSourceImpl implements net.techcable.sonarpet.nms.DamageSource { - @Getter - private final DamageSource handle; -} diff --git a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/DataWatcherImpl.java b/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/DataWatcherImpl.java deleted file mode 100644 index 549b7cb7..00000000 --- a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/DataWatcherImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R1; - -import lombok.*; - -import net.minecraft.server.v1_9_R1.DataWatcher; -import net.minecraft.server.v1_9_R1.DataWatcherObject; -import net.minecraft.server.v1_9_R1.DataWatcherRegistry; -import net.minecraft.server.v1_9_R1.DataWatcherSerializer; - -@RequiredArgsConstructor -public class DataWatcherImpl implements net.techcable.sonarpet.nms.DataWatcher { - private final DataWatcher dataWatcher; - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - private static final DataWatcherSerializer BOOLEAN_SERIALIZER = DataWatcherRegistry.h; - private static final DataWatcherSerializer INTEGER_SERIALIZER = DataWatcherRegistry.b; - - // - // Deobfuscated methods - // - - @Override - public void setBoolean(int id, boolean value) { - dataWatcher.set(new DataWatcherObject<>(id, BOOLEAN_SERIALIZER), value); - } - - @Override - public void setInteger(int id, int value) { - dataWatcher.set(new DataWatcherObject<>(id, INTEGER_SERIALIZER), value); - } -} diff --git a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSEntityHorseImpl.java b/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSEntityHorseImpl.java deleted file mode 100644 index b83e0934..00000000 --- a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSEntityHorseImpl.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R1; - -import com.dsh105.echopet.compat.api.entity.HorseType; -import com.dsh105.echopet.compat.api.entity.HorseTypeKt; - -import net.minecraft.server.v1_9_R1.EntityHorse; -import net.techcable.sonarpet.nms.NMSEntityHorse; - -import org.bukkit.entity.Horse; - -public class NMSEntityHorseImpl extends NMSEntityInsentientImpl implements NMSEntityHorse { - public NMSEntityHorseImpl(EntityHorse handle) { - super(handle); - } - - // - // !!!!! Highly version-dependent !!!!! - // Check these every minor update! - // - - @Override - public void setSaddled(boolean saddled) { - getHandle().t(saddled); // EntityHorse.setHorseSaddled - } - - @Override - public boolean isSaddled() { - return getHandle().du(); // EntityHorse.isHorseSaddled - } - - // - // Breakage likely, check for bugs here - // - - @Override - public void setRearing(boolean b) { - // metadata flag with id 64 - getHandle().v(b); - } - - // Deobfuscated methods - - @Override - public void setStyle(Horse.Style bukkitStyle) { - getBukkitEntity().setStyle(bukkitStyle); - } - - @Override - public void setHorseType(HorseType t) { - getBukkitEntity().setVariant(t.getBukkitVariant()); - } - - @Override - public void setColor(Horse.Color color) { - getBukkitEntity().setColor(color); - } - - @Override - public HorseType getHorseType() { - return HorseTypeKt.getSonarType(getBukkitEntity().getVariant()); - } - - @Override - public void setCarryingChest(boolean flag) { - getBukkitEntity().setCarryingChest(flag); - } - - @Override - public EntityHorse getHandle() { - return (EntityHorse) super.getHandle(); - } - - @Override - public Horse getBukkitEntity() { - return (Horse) super.getBukkitEntity(); - } -} diff --git a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSEntityImpl.java b/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSEntityImpl.java deleted file mode 100644 index e31a1838..00000000 --- a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSEntityImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R1; - -import lombok.*; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.server.v1_9_R1.DamageSource; -import net.minecraft.server.v1_9_R1.Entity; -import net.techcable.sonarpet.nms.INMS; -import net.techcable.sonarpet.nms.NMSEntity; -import net.techcable.sonarpet.nms.NMSLivingEntity; - -import org.bukkit.entity.Player; - -@RequiredArgsConstructor -public class NMSEntityImpl implements NMSEntity { - @Getter - private final Entity handle; - - // - // Deobfuscated methods - // - - @Override - public boolean damageEntity(net.techcable.sonarpet.nms.DamageSource rawSource, float amount) { - DamageSource damageSource = ((DamageSourceImpl) rawSource).getHandle(); - return getHandle().damageEntity(damageSource, amount); - } - - @Override - public org.bukkit.entity.Entity getBukkitEntity() { - return handle.getBukkitEntity(); - } - - @Override - public ImmutableList getPassengers() { - return ImmutableList.copyOf(handle.passengers.stream() - .map(Entity::getBukkitEntity) - .map(INMS.getInstance()::wrapEntity) - .toArray(NMSEntity[]::new)); - } - - @Override - public int hashCode() { - return handle.hashCode(); - } - - @Override - public boolean equals(Object obj) { - return obj != null && obj instanceof NMSEntityImpl && ((NMSEntityImpl) obj).handle.equals(this.handle); - } - - @Override - public String toString() { - if (getBukkitEntity() instanceof Player) { - return "NMSPlayer(" + getBukkitEntity().getName() + ")"; - } else { - StringBuilder builder = new StringBuilder("NMSEntity("); - builder.append(getBukkitEntity().getType()); - if (getBukkitEntity().getCustomName() != null) { - builder.append(":"); - builder.append(getBukkitEntity().getCustomName()); - } - builder.append(')'); - return builder.toString(); - } - } -} diff --git a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSEntityInsentientImpl.java b/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSEntityInsentientImpl.java deleted file mode 100644 index 33b78058..00000000 --- a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSEntityInsentientImpl.java +++ /dev/null @@ -1,124 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R1; - -import lombok.*; - -import java.lang.invoke.MethodHandle; -import java.util.Set; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.server.v1_9_R1.EntityInsentient; -import net.minecraft.server.v1_9_R1.EntityLiving; -import net.minecraft.server.v1_9_R1.GenericAttributes; -import net.minecraft.server.v1_9_R1.Navigation; -import net.minecraft.server.v1_9_R1.PathfinderGoalSelector; -import net.minecraft.server.v1_9_R1.SoundEffect; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.pineapple.reflection.Reflection; -import net.techcable.sonarpet.nms.NMSInsentientEntity; -import net.techcable.sonarpet.nms.NMSSound; - -import org.bukkit.craftbukkit.v1_9_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_9_R1.entity.CraftLivingEntity; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; - -public class NMSEntityInsentientImpl extends NMSLivingEntityImpl implements NMSInsentientEntity { - - // - // !!!!! Highly version-dependent !!!!! - // Check these every minor update! - // - - private static final MethodHandle GET_DEATH_SOUND_METHOD_HANDLE = Reflection.getMethod( - EntityLiving.class, - "bS" - ); - - - // - // Breakage likely, check for bugs here - // - - @Override - public float getVerticalFaceSpeed() { - return getHandle().N(); - } - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - @Override - public void clearGoals() { - PathfinderGoalSelector goalSelector = getHandle().goalSelector; - ImmutableList> fieldsToClear = PineappleField.findFieldsWithType(PathfinderGoalSelector.class, Set.class); - if (fieldsToClear.size() != 2) { - throw new AssertionError("Unexpected number of fields to clear: " + fieldsToClear); - } - for (PineappleField field : fieldsToClear) { - field.get(goalSelector).clear(); - } - } - - @Override - public void lookAt(Entity other, float perTick, float verticalFaceSpeed) { - getHandle().getControllerLook().a(((CraftEntity) other).getHandle(), perTick, verticalFaceSpeed); - } - - @Override - public void jump() { - getHandle().getControllerJump().a(); - } - - @Override - public void setCanSwim(boolean b) { - ((Navigation) getHandle().getNavigation()).c(b); - } - - // - // Deobfuscated methods :) - // - - @Override - public void setFollowRange(double followRange) { - getHandle().getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(followRange); - } - - @Override - public LivingEntity getTarget() { - EntityLiving entity = getHandle().getGoalTarget(); - return entity != null ? (LivingEntity) entity.getBukkitEntity() : null; - } - - @Override - public void setTarget(LivingEntity target) { - getHandle().setGoalTarget(((CraftLivingEntity) target).getHandle()); - } - - @Override - public net.techcable.sonarpet.nms.Navigation getNavigation() { - return new NavigationImpl((Navigation) getHandle().getNavigation()); - } - - // - // Utility methods and wrappers - // - - @Override - public EntityInsentient getHandle() { - return (EntityInsentient) super.getHandle(); - } - - @Override - @SneakyThrows - public NMSSound getDeathSound() { - SoundEffect soundEffect = (SoundEffect) GET_DEATH_SOUND_METHOD_HANDLE.invoke(getHandle()); - return soundEffect != null ? new NMSSoundImpl(soundEffect) : null; - } - - public NMSEntityInsentientImpl(EntityInsentient handle) { - super(handle); - } -} diff --git a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSEntityRegistry.java b/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSEntityRegistry.java deleted file mode 100644 index fd9a12be..00000000 --- a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSEntityRegistry.java +++ /dev/null @@ -1,72 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R1; - -import java.util.Map; -import java.util.Objects; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.server.v1_9_R1.EntityTypes; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.sonarpet.nms.EntityRegistry; - -public class NMSEntityRegistry implements EntityRegistry { - private static final PineappleField, String>> CLASS_TO_NAME_FIELD; - private static final PineappleField>> ID_TO_CLASS_FIELD; - private static final PineappleField, Integer>> CLASS_TO_ID_FIELD; - - static { - ImmutableList> mapFields = PineappleField.findFieldsWithType(EntityTypes.class, Map.class); - assert mapFields.size() == 5; - //noinspection unchecked - CLASS_TO_NAME_FIELD = (PineappleField) mapFields.get(1); - //noinspection unchecked - ID_TO_CLASS_FIELD = (PineappleField) mapFields.get(2); - //noinspection unchecked - CLASS_TO_ID_FIELD = (PineappleField) mapFields.get(3); - } - - @Override - public void registerEntityClass(Class entityClass, String name, int id) { - CLASS_TO_NAME_FIELD.getStatic().put(entityClass, name); - CLASS_TO_ID_FIELD.getStatic().put(entityClass, id); - } - - @Override - public void unregisterEntityClass(Class entityClass, String name, int id) { - String actualName = CLASS_TO_NAME_FIELD.getStatic().remove(entityClass); - Integer actualId = CLASS_TO_ID_FIELD.getStatic().remove(entityClass); - if (!Objects.equals(name, actualName)) { - throw new IllegalArgumentException("Expected name " + name + " didn't equal actual name " + Objects.toString(actualName)); - } else if (actualId == null || actualId != id) { - throw new IllegalArgumentException("Expected id " + id + " didn't equal actual id " + Objects.toString(actualId)); - } - } - - @Override - public Class getEntityClass(int id) { - return ID_TO_CLASS_FIELD.getStatic().get(id); - } - - @Override - public int getEntityId(Class entityClass) { - return CLASS_TO_ID_FIELD.getStatic().get(entityClass); - } - - @Override - public String getEntityName(Class entityClass) { - return CLASS_TO_NAME_FIELD.getStatic().get(entityClass); - } - - @Override - public void registerEntityId(int id, Class entityClass) { - ID_TO_CLASS_FIELD.getStatic().put(id, entityClass); - } - - @Override - public void unregisterEntityId(int id, Class entityClass) { - Class actualEntityClass = ID_TO_CLASS_FIELD.getStatic().remove(id); - if (!Objects.equals(actualEntityClass, entityClass)) { - throw new IllegalArgumentException("Exepcted entity class " + entityClass + " didn't equal actual entity class " + Objects.toString(actualEntityClass)); - } - } -} diff --git a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSImpl.java b/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSImpl.java deleted file mode 100644 index 4e37f790..00000000 --- a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSImpl.java +++ /dev/null @@ -1,138 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R1; - -import net.minecraft.server.v1_9_R1.EntityHorse; -import net.minecraft.server.v1_9_R1.EntityInsentient; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.sonarpet.nms.DismountingBlocked; -import net.techcable.sonarpet.nms.EntityRegistry; -import net.techcable.sonarpet.nms.INMS; -import com.google.common.collect.ImmutableMap; - -import net.minecraft.server.v1_9_R1.Block; -import net.minecraft.server.v1_9_R1.DamageSource; -import net.minecraft.server.v1_9_R1.EntityHuman; -import net.minecraft.server.v1_9_R1.EntityLiving; -import net.minecraft.server.v1_9_R1.EntityPlayer; -import net.minecraft.server.v1_9_R1.Packet; -import net.minecraft.server.v1_9_R1.PacketPlayOutMount; -import net.minecraft.server.v1_9_R1.SoundEffect; -import net.minecraft.server.v1_9_R1.SoundEffectType; -import net.techcable.sonarpet.item.SpawnEggItemData; -import net.techcable.sonarpet.nms.BlockSoundData; -import net.techcable.sonarpet.nms.NMSEntity; -import net.techcable.sonarpet.nms.NMSInsentientEntity; -import net.techcable.sonarpet.nms.NMSSound; -import net.techcable.sonarpet.nms.versions.v1_9_R1.data.NMSSpawnEggItemData; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.craftbukkit.v1_9_R1.CraftSound; -import org.bukkit.craftbukkit.v1_9_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_9_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_9_R1.entity.CraftLivingEntity; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.material.SpawnEgg; - -import static com.google.common.base.Preconditions.*; - -public class NMSImpl implements INMS { - @Override - public SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta) { - checkNotNull(entityType, "Null entity type"); - checkNotNull(meta, "Null item meta"); - return new NMSSpawnEggItemData(new SpawnEgg(entityType).getData(), meta, entityType); // Pretend we use metadata to make the code happy - } - - @Override - public void mount(Entity bukkitRider, Entity bukkitVehicle) { - net.minecraft.server.v1_9_R1.Entity rider = ((CraftEntity) bukkitRider).getHandle(); - if (bukkitVehicle == null) { - net.minecraft.server.v1_9_R1.Entity vehicle = rider.getVehicle(); // This is how you *really* get the vehicle :/ - if (rider instanceof DismountingBlocked) { - ((DismountingBlocked) rider).reallyStopRiding(); - } else { - rider.stopRiding(); - } - if (vehicle != null) { - Packet packet = new PacketPlayOutMount(vehicle); - for (EntityHuman human : rider.world.players) { - ((EntityPlayer) human).playerConnection.sendPacket(packet); - } - } - } else { - checkArgument(bukkitRider.getWorld().equals(bukkitVehicle.getWorld()), "Rider is in world %s, while vehicle is in world %s", bukkitRider.getWorld().getName(), bukkitVehicle.getWorld().getName()); - net.minecraft.server.v1_9_R1.Entity vehicle = ((CraftEntity) bukkitVehicle).getHandle(); - rider.a(vehicle, true); // !! Obfuscated !! - Packet packet = new PacketPlayOutMount(vehicle); - for (EntityHuman human : rider.world.players) { - ((EntityPlayer) human).playerConnection.sendPacket(packet); - } - } - } - - @Override - public boolean spawnEntity(NMSInsentientEntity wrapper, Location l) { - EntityLiving entity = ((NMSEntityInsentientImpl) wrapper).getHandle(); - entity.spawnIn(((CraftWorld) l.getWorld()).getHandle()); - ((LivingEntity) entity.getBukkitEntity()).setCollidable(false); - entity.setLocation(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch()); - if (!l.getChunk().isLoaded()) { - l.getChunk().load(); - } - return entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); - } - - @Override - public net.techcable.sonarpet.nms.DamageSource mobAttackDamageSource(LivingEntity entity) { - return new DamageSourceImpl(DamageSource.mobAttack(((CraftLivingEntity) entity).getHandle())); - } - - @Override - public net.techcable.sonarpet.nms.DamageSource wrapDamageSource(Object handle) { - return new DamageSourceImpl((DamageSource) handle); - } - - @Override - public NMSEntity wrapEntity(Entity entity) { - net.minecraft.server.v1_9_R1.Entity handle = ((CraftEntity) entity).getHandle(); - if (handle instanceof EntityPlayer) { - return new NMSPlayerImpl((EntityPlayer) handle); - } else if (handle instanceof EntityHorse) { - return new NMSEntityHorseImpl((EntityHorse) handle); - } else if (handle instanceof EntityInsentient) { - return new NMSEntityInsentientImpl((EntityInsentient) handle); - } else if (handle instanceof EntityLiving) { - return new NMSLivingEntityImpl((EntityLiving) handle); - } else { - return new NMSEntityImpl(handle); - } - } - - private PineappleField STEP_SOUND_FIELD = PineappleField.create(Block.class, "stepSound", SoundEffectType.class); - @Override - @SuppressWarnings("deprecation") // I know about ur stupid magic value warning mom - public BlockSoundData getBlockSoundData(Material material) { - return new BlockSoundDataImpl(STEP_SOUND_FIELD.get(Block.getById(material.getId()))); - } - - @Override - @SuppressWarnings("deprecation") // I know about ur stupid magic value warning mom - public boolean isLiquid(Material block) { - return Block.getById(block.getId()).getBlockData().getMaterial().isLiquid(); - } - - @Override - public EntityRegistry createDefaultEntityRegistry() { - return new NMSEntityRegistry(); - } - - @Override - public NMSSound getNmsSound(Sound bukkitSound) { - return new NMSSoundImpl(NMSSoundImplKt.getSoundEffect(bukkitSound)); - } -} diff --git a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSLivingEntityImpl.java b/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSLivingEntityImpl.java deleted file mode 100644 index e39e8e5a..00000000 --- a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSLivingEntityImpl.java +++ /dev/null @@ -1,181 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R1; - -import net.minecraft.server.v1_9_R1.EntityHuman; -import net.minecraft.server.v1_9_R1.EntityLiving; -import net.minecraft.server.v1_9_R1.SoundEffect; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.sonarpet.nms.DataWatcher; -import net.techcable.sonarpet.nms.NMSLivingEntity; -import net.techcable.sonarpet.nms.NMSSound; - -import org.bukkit.Sound; -import org.bukkit.craftbukkit.v1_9_R1.CraftSound; -import org.bukkit.craftbukkit.v1_9_R1.entity.CraftEntity; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; - -public class NMSLivingEntityImpl extends NMSEntityImpl implements NMSLivingEntity { - - // - // !!!!! Highly version-dependent !!!!! - // Check these every minor update! - // - public static final String IS_JUMPING_FIELD_NAME = "bc"; - - public NMSLivingEntityImpl(EntityLiving handle) { - super(handle); - } - - /** - * Set the 'offsets' for pitch and yaw to the same value as the yaw itself. - * Apparently this is needed to set rotation. - * See EntityLiving.h(FF) for details (method profiler 'headTurn'). - * Note that EntityInsentient overrides h(FF) and delegates to 'EntityAIBodyControl'. - * 'EntityAIBodyControl' is what actually accesses/uses these fields and where the mappings should be fetched. - *

- * Also, these fields have the MCP names 'renderYawOffset' and 'rotationYawHead' - */ - @Override - public void correctYaw() { - getHandle().aM = getHandle().aO = getHandle().yaw; - } - - @Override - public boolean isInLava() { - return getHandle().an(); - } - - // - // Breakage likely, check for bugs here - // - - @Override - public void setMoveSpeed(double rideSpeed) { - getHandle().l((float) rideSpeed); - } - - @Override - public void setStepHeight(float stepHeight) { - getHandle().P = stepHeight; - } - - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - @Override - public void playSound(NMSSound sound, float volume, float pitch) { - getHandle().a(((NMSSoundImpl) sound).getHandle(), volume, pitch); - } - - @Override - public double distanceTo(Entity other) { - return getHandle().h(((CraftEntity) other).getHandle()); - } - - - // - // Deobfuscated methods :) - // - - @Override - public Player findNearbyPlayer(double range) { - EntityHuman player = getHandle().world.findNearbyPlayer(getHandle(), range); - return player == null ? null : (Player) player.getBukkitEntity(); - } - - @Override - public boolean isInvisible() { - return getHandle().isInvisible(); - } - - @Override - public boolean isSneaking() { - return getHandle().isSneaking(); - } - - @Override - public void setSneaking(boolean b) { - getHandle().setSneaking(b); - } - - @Override - public void setInvisible(boolean b) { - getHandle().setInvisible(b); - } - - @Override - public boolean isSprinting() { - return getHandle().isSprinting(); - } - - @Override - public void setSprinting(boolean b) { - getHandle().setSprinting(b); - } - - @Override - public void setYaw(float yaw) { - getHandle().yaw = yaw; - } - - @Override - public void setPitch(float pitch) { - getHandle().pitch = pitch; - } - - @Override - public void setNoClip(boolean b) { - getHandle().noclip = b; - } - - @Override - public boolean isInWater() { - return getHandle().isInWater(); - } - - - @Override - public void setUpwardsMotion(double motY) { - getHandle().motY = motY; - } - - @Override - public DataWatcher getDataWatcher() { - return new DataWatcherImpl(getHandle().getDataWatcher()); - } - - @Override - public double getWidth() { - return getHandle().width; - } - - @Override - public double getLength() { - return getHandle().length; - } - - // - // Utility methods and wrappers - // - - private static final PineappleField IS_JUMPING_FIELD = PineappleField.create(EntityLiving.class, IS_JUMPING_FIELD_NAME, boolean.class); - - @Override - public boolean isJumping() { - return IS_JUMPING_FIELD.getBoxed(getHandle()); - } - - @Override - public EntityLiving getHandle() { - return (EntityLiving) super.getHandle(); - } - - @Override - public LivingEntity getBukkitEntity() { - return (LivingEntity) getHandle().getBukkitEntity(); - } -} diff --git a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSPlayerImpl.java b/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSPlayerImpl.java deleted file mode 100644 index 7317fb43..00000000 --- a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSPlayerImpl.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R1; - -import net.minecraft.server.v1_9_R1.EntityPlayer; -import net.techcable.sonarpet.nms.NMSPlayer; - -import org.bukkit.entity.Player; - -public class NMSPlayerImpl extends NMSLivingEntityImpl implements NMSPlayer { - public NMSPlayerImpl(EntityPlayer handle) { - super(handle); - } - - @Override - public boolean isOnGround() { - return getHandle().onGround; - } - - @Override - public EntityPlayer getHandle() { - return (EntityPlayer) super.getHandle(); - } - - @Override - public Player getBukkitEntity() { - return (Player) super.getBukkitEntity(); - } -} diff --git a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NavigationImpl.java b/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NavigationImpl.java deleted file mode 100644 index 8d6320b5..00000000 --- a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/NavigationImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R1; - -import lombok.*; - -import net.minecraft.server.v1_9_R1.Navigation; -import net.techcable.sonarpet.nms.PathEntity; - -import org.bukkit.craftbukkit.v1_9_R1.entity.CraftEntity; -import org.bukkit.entity.Entity; - -@RequiredArgsConstructor -public class NavigationImpl implements net.techcable.sonarpet.nms.Navigation { - private final Navigation handle; - - // - // Breakage likely, check for bugs here - // - - @Override - public boolean canEnterDoors() { - return handle.f(); - } - - @Override - public void finish() { - handle.n(); - } - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - @Override - public PathEntity getPathToLocation(int blockX, int blockY, int blockZ) { - return new PathEntityImpl(handle.a(blockX, blockY, blockZ)); - } - - @Override - public PathEntity getPathTo(Entity other) { - return new PathEntityImpl(handle.a(((CraftEntity) other).getHandle())); - } - - @Override - public void navigateTo(PathEntity path, double speed) { - handle.a(((PathEntityImpl) path).handle, speed); - } - - @RequiredArgsConstructor - private static class PathEntityImpl implements PathEntity { - /* package */ final net.minecraft.server.v1_9_R1.PathEntity handle; - } -} diff --git a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/data/NMSSpawnEggItemData.java b/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/data/NMSSpawnEggItemData.java deleted file mode 100644 index 151425b7..00000000 --- a/nms/v1_9_R1/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R1/data/NMSSpawnEggItemData.java +++ /dev/null @@ -1,86 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R1.data; - -import java.util.Optional; - -import com.google.common.base.Preconditions; - -import net.minecraft.server.v1_9_R1.EntityTypes; -import net.minecraft.server.v1_9_R1.Item; -import net.minecraft.server.v1_9_R1.ItemStack; -import net.minecraft.server.v1_9_R1.NBTTagCompound; -import net.techcable.sonarpet.item.SpawnEggItemData; - -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.craftbukkit.v1_9_R1.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_9_R1.util.CraftMagicNumbers; -import org.bukkit.entity.EntityType; -import org.bukkit.inventory.meta.ItemMeta; - -public class NMSSpawnEggItemData extends SpawnEggItemData { - public NMSSpawnEggItemData(byte rawData, ItemMeta meta) { - this(rawData, meta, SpawnEggItemData.DEFAULT_TYPE); - } - - public NMSSpawnEggItemData(byte rawData, ItemMeta meta, EntityType type) { - super(Material.MONSTER_EGG, rawData, createMetaWithEntityType(meta, type)); - } - - @Override - public EntityType getSpawnedType() { - return getSpawnEggEntityType(this.getMeta()); - } - - public static EntityType getSpawnEggEntityType(ItemMeta meta) { - Preconditions.checkNotNull(meta, "Null meta"); - NBTTagCompound tag = getTagFromMeta(Material.MONSTER_EGG, meta); - Preconditions.checkState(tag != null, "No nbt tag"); - Preconditions.checkState(tag.hasKeyOfType("EntityTag", 10), "No entity tag"); - NBTTagCompound entityTag = tag.getCompound("EntityTag"); - Preconditions.checkState(entityTag.hasKeyOfType("id", 8), "No internal name"); - String internalName = entityTag.getString("id"); - int id = EntityTypes.a(internalName); - EntityType type = EntityType.fromId(id); - if (type == null) - throw new IllegalStateException("No entity found with internal name " + internalName + " and id " + id); - return type; - } - - public static Optional getSpawnEggEntityTypeIfPresent(ItemMeta meta) { - try { - return Optional.of(getSpawnEggEntityType(meta)); - } catch (IllegalArgumentException | IllegalStateException e) { - return Optional.empty(); - } - } - - public static ItemMeta createMetaWithEntityType(ItemMeta meta, EntityType entityType) { - NBTTagCompound entityTag = new NBTTagCompound(); - String internalName = EntityTypes.getName(EntityTypes.a(entityType.getTypeId())); - if (internalName == null) throw new AssertionError("Couldn't find internal name for type: " + entityType); - entityTag.setString("id", internalName); - NBTTagCompound tag = getTagFromMeta(Material.MONSTER_EGG, Preconditions.checkNotNull(meta, "Null meta")); - if (tag == null) tag = new NBTTagCompound(); - tag.set("EntityTag", entityTag); - return createMetaFromTag(Material.MONSTER_EGG, tag); - } - - - public static ItemMeta createMetaFromTag(Material type, NBTTagCompound tag) { - Item item = CraftMagicNumbers.getItem(Preconditions.checkNotNull(type, "Null type")); - ItemStack stack = new ItemStack(item); - stack.setTag(Preconditions.checkNotNull(tag, "Null nbt tag")); - return CraftItemStack.getItemMeta(stack); - } - - public static NBTTagCompound getTagFromMeta(Material type, ItemMeta meta) { - Preconditions.checkNotNull(meta, "Null meta"); - Preconditions.checkNotNull(type, "Null type"); - Preconditions.checkArgument(Bukkit.getItemFactory().isApplicable(meta, type), "Meta %s isn't applicable to %s", meta, type); - Item item = CraftMagicNumbers.getItem(type); - ItemStack stack = new ItemStack(item); - boolean worked = CraftItemStack.setItemMeta(stack, meta); - if (!worked) throw new RuntimeException("Didn't work"); - return stack.getTag(); - } -} diff --git a/nms/v1_9_R1/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSSoundImpl.kt b/nms/v1_9_R1/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSSoundImpl.kt deleted file mode 100644 index 08d6e7d8..00000000 --- a/nms/v1_9_R1/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_9_R1/NMSSoundImpl.kt +++ /dev/null @@ -1,21 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R1 - -import net.minecraft.server.v1_9_R1.SoundEffect -import net.techcable.sonarpet.nms.NMSSound -import net.techcable.sonarpet.utils.buildImmutableMap -import org.bukkit.Sound -import org.bukkit.craftbukkit.v1_9_R1.CraftSound - -private val BUKKIT_SOUNDS = buildImmutableMap { - for (sound in enumValues()) { - put(sound.soundEffect, sound) - } -} - -val Sound.soundEffect: SoundEffect - get() = CraftSound.getSoundEffect(CraftSound.getSound(this))!! - -class NMSSoundImpl(val handle: SoundEffect): NMSSound { - override val bukkitSound: Sound? - get() = BUKKIT_SOUNDS[handle] -} \ No newline at end of file diff --git a/nms/v1_9_R2/build.gradle.kts b/nms/v1_9_R2/build.gradle.kts deleted file mode 100644 index c4931980..00000000 --- a/nms/v1_9_R2/build.gradle.kts +++ /dev/null @@ -1,4 +0,0 @@ -dependencies { - compileOnly("org.bukkit:craftbukkit:1.9.4-R0.1-SNAPSHOT") - compileOnly(project(":api")) -} diff --git a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/BlockSoundDataImpl.java b/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/BlockSoundDataImpl.java deleted file mode 100644 index 9911fba3..00000000 --- a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/BlockSoundDataImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R2; - -import lombok.*; - -import net.minecraft.server.v1_9_R2.SoundEffectType; -import net.techcable.sonarpet.nms.BlockSoundData; - -@RequiredArgsConstructor -public class BlockSoundDataImpl implements BlockSoundData { - private final SoundEffectType handle; - - @Override - public float getVolume() { - return handle.a(); - } - - @Override - public float getPitch() { - return handle.b(); - } - - @Override - public boolean equals(Object o) { // We need this!! - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - BlockSoundDataImpl that = (BlockSoundDataImpl) o; - - return handle.equals(that.handle); - } - - @Override - public int hashCode() { - return handle.hashCode(); - } -} - diff --git a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/DamageSourceImpl.java b/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/DamageSourceImpl.java deleted file mode 100644 index d5225549..00000000 --- a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/DamageSourceImpl.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R2; - -import lombok.*; - -import net.minecraft.server.v1_9_R2.DamageSource; - -@RequiredArgsConstructor -public class DamageSourceImpl implements net.techcable.sonarpet.nms.DamageSource { - @Getter - private final DamageSource handle; -} diff --git a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/DataWatcherImpl.java b/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/DataWatcherImpl.java deleted file mode 100644 index 167fc525..00000000 --- a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/DataWatcherImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R2; - -import lombok.*; - -import net.minecraft.server.v1_9_R2.DataWatcher; -import net.minecraft.server.v1_9_R2.DataWatcherObject; -import net.minecraft.server.v1_9_R2.DataWatcherRegistry; -import net.minecraft.server.v1_9_R2.DataWatcherSerializer; - -@RequiredArgsConstructor -public class DataWatcherImpl implements net.techcable.sonarpet.nms.DataWatcher { - private final DataWatcher dataWatcher; - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - private static final DataWatcherSerializer BOOLEAN_SERIALIZER = DataWatcherRegistry.h; - private static final DataWatcherSerializer INTEGER_SERIALIZER = DataWatcherRegistry.b; - - // - // Deobfuscated methods - // - - @Override - public void setBoolean(int id, boolean value) { - dataWatcher.set(new DataWatcherObject<>(id, BOOLEAN_SERIALIZER), value); - } - - @Override - public void setInteger(int id, int value) { - dataWatcher.set(new DataWatcherObject<>(id, INTEGER_SERIALIZER), value); - } -} diff --git a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSEntityHorseImpl.java b/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSEntityHorseImpl.java deleted file mode 100644 index 9c70d1bd..00000000 --- a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSEntityHorseImpl.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R2; - -import com.dsh105.echopet.compat.api.entity.HorseType; -import com.dsh105.echopet.compat.api.entity.HorseTypeKt; - -import net.minecraft.server.v1_9_R2.EntityHorse; -import net.techcable.sonarpet.nms.NMSEntityHorse; - -import org.bukkit.entity.Horse; - -public class NMSEntityHorseImpl extends NMSEntityInsentientImpl implements NMSEntityHorse { - public NMSEntityHorseImpl(EntityHorse handle) { - super(handle); - } - - // - // !!!!! Highly version-dependent !!!!! - // Check these every minor update! - // - - @Override - public void setSaddled(boolean saddled) { - getHandle().t(saddled); // EntityHorse.setHorseSaddled - } - - @Override - public boolean isSaddled() { - return getHandle().dv(); // EntityHorse.isHorseSaddled - } - - // - // Breakage likely, check for bugs here - // - - @Override - public void setRearing(boolean b) { - // metadata flag with id 64 - getHandle().v(b); - } - - // Deobfuscated methods - - @Override - public void setStyle(Horse.Style bukkitStyle) { - getBukkitEntity().setStyle(bukkitStyle); - } - - @Override - public void setHorseType(HorseType t) { - getBukkitEntity().setVariant(t.getBukkitVariant()); - } - - @Override - public void setColor(Horse.Color color) { - getBukkitEntity().setColor(color); - } - - @Override - public HorseType getHorseType() { - return HorseTypeKt.getSonarType(getBukkitEntity().getVariant()); - } - - @Override - public void setCarryingChest(boolean flag) { - getBukkitEntity().setCarryingChest(flag); - } - - @Override - public EntityHorse getHandle() { - return (EntityHorse) super.getHandle(); - } - - @Override - public Horse getBukkitEntity() { - return (Horse) super.getBukkitEntity(); - } -} diff --git a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSEntityImpl.java b/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSEntityImpl.java deleted file mode 100644 index dc28bc7a..00000000 --- a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSEntityImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R2; - -import lombok.*; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.server.v1_9_R2.DamageSource; -import net.minecraft.server.v1_9_R2.Entity; -import net.techcable.sonarpet.nms.INMS; -import net.techcable.sonarpet.nms.NMSEntity; -import net.techcable.sonarpet.nms.NMSLivingEntity; - -import org.bukkit.entity.Player; - -@RequiredArgsConstructor -public class NMSEntityImpl implements NMSEntity { - @Getter - private final Entity handle; - - // - // Deobfuscated methods - // - - @Override - public boolean damageEntity(net.techcable.sonarpet.nms.DamageSource rawSource, float amount) { - DamageSource damageSource = ((DamageSourceImpl) rawSource).getHandle(); - return getHandle().damageEntity(damageSource, amount); - } - - @Override - public org.bukkit.entity.Entity getBukkitEntity() { - return handle.getBukkitEntity(); - } - - @Override - public ImmutableList getPassengers() { - return ImmutableList.copyOf(handle.passengers.stream() - .map(Entity::getBukkitEntity) - .map(INMS.getInstance()::wrapEntity) - .toArray(NMSEntity[]::new)); - } - - @Override - public int hashCode() { - return handle.hashCode(); - } - - @Override - public boolean equals(Object obj) { - return obj != null && obj instanceof NMSEntityImpl && ((NMSEntityImpl) obj).handle.equals(this.handle); - } - - @Override - public String toString() { - if (getBukkitEntity() instanceof Player) { - return "NMSPlayer(" + getBukkitEntity().getName() + ")"; - } else { - StringBuilder builder = new StringBuilder("NMSEntity("); - builder.append(getBukkitEntity().getType()); - if (getBukkitEntity().getCustomName() != null) { - builder.append(":"); - builder.append(getBukkitEntity().getCustomName()); - } - builder.append(')'); - return builder.toString(); - } - } -} diff --git a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSEntityInsentientImpl.java b/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSEntityInsentientImpl.java deleted file mode 100644 index 39058dc7..00000000 --- a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSEntityInsentientImpl.java +++ /dev/null @@ -1,124 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R2; - -import lombok.*; - -import java.lang.invoke.MethodHandle; -import java.util.Set; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.server.v1_9_R2.EntityInsentient; -import net.minecraft.server.v1_9_R2.EntityLiving; -import net.minecraft.server.v1_9_R2.GenericAttributes; -import net.minecraft.server.v1_9_R2.Navigation; -import net.minecraft.server.v1_9_R2.PathfinderGoalSelector; -import net.minecraft.server.v1_9_R2.SoundEffect; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.pineapple.reflection.Reflection; -import net.techcable.sonarpet.nms.NMSInsentientEntity; -import net.techcable.sonarpet.nms.NMSSound; - -import org.bukkit.craftbukkit.v1_9_R2.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_9_R2.entity.CraftLivingEntity; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; - -public class NMSEntityInsentientImpl extends NMSLivingEntityImpl implements NMSInsentientEntity { - - // - // !!!!! Highly version-dependent !!!!! - // Check these every minor update! - // - - private static final MethodHandle GET_DEATH_SOUND_METHOD_HANDLE = Reflection.getMethod( - EntityLiving.class, - "bT" - ); - - - // - // Breakage likely, check for bugs here - // - - @Override - public float getVerticalFaceSpeed() { - return getHandle().N(); - } - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - @Override - public void clearGoals() { - PathfinderGoalSelector goalSelector = getHandle().goalSelector; - ImmutableList> fieldsToClear = PineappleField.findFieldsWithType(PathfinderGoalSelector.class, Set.class); - if (fieldsToClear.size() != 2) { - throw new AssertionError("Unexpected number of fields to clear: " + fieldsToClear); - } - for (PineappleField field : fieldsToClear) { - field.get(goalSelector).clear(); - } - } - - @Override - public void lookAt(Entity other, float perTick, float verticalFaceSpeed) { - getHandle().getControllerLook().a(((CraftEntity) other).getHandle(), perTick, verticalFaceSpeed); - } - - @Override - public void jump() { - getHandle().getControllerJump().a(); - } - - @Override - public void setCanSwim(boolean b) { - ((Navigation) getHandle().getNavigation()).c(b); - } - - // - // Deobfuscated methods :) - // - - @Override - public void setFollowRange(double followRange) { - getHandle().getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(followRange); - } - - @Override - public LivingEntity getTarget() { - EntityLiving entity = getHandle().getGoalTarget(); - return entity != null ? (LivingEntity) entity.getBukkitEntity() : null; - } - - @Override - public void setTarget(LivingEntity target) { - getHandle().setGoalTarget(((CraftLivingEntity) target).getHandle()); - } - - @Override - public net.techcable.sonarpet.nms.Navigation getNavigation() { - return new NavigationImpl((Navigation) getHandle().getNavigation()); - } - - // - // Utility methods and wrappers - // - - @Override - public EntityInsentient getHandle() { - return (EntityInsentient) super.getHandle(); - } - - @Override - @SneakyThrows - public NMSSound getDeathSound() { - SoundEffect soundEffect = (SoundEffect) GET_DEATH_SOUND_METHOD_HANDLE.invoke(getHandle()); - return soundEffect != null ? new NMSSoundImpl(soundEffect) : null; - } - - public NMSEntityInsentientImpl(EntityInsentient handle) { - super(handle); - } -} diff --git a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSEntityRegistry.java b/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSEntityRegistry.java deleted file mode 100644 index 7ab27c99..00000000 --- a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSEntityRegistry.java +++ /dev/null @@ -1,72 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R2; - -import java.util.Map; -import java.util.Objects; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.server.v1_9_R2.EntityTypes; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.sonarpet.nms.EntityRegistry; - -public class NMSEntityRegistry implements EntityRegistry { - private static final PineappleField, String>> CLASS_TO_NAME_FIELD; - private static final PineappleField>> ID_TO_CLASS_FIELD; - private static final PineappleField, Integer>> CLASS_TO_ID_FIELD; - - static { - ImmutableList> mapFields = PineappleField.findFieldsWithType(EntityTypes.class, Map.class); - assert mapFields.size() == 5; - //noinspection unchecked - CLASS_TO_NAME_FIELD = (PineappleField) mapFields.get(1); - //noinspection unchecked - ID_TO_CLASS_FIELD = (PineappleField) mapFields.get(2); - //noinspection unchecked - CLASS_TO_ID_FIELD = (PineappleField) mapFields.get(3); - } - - @Override - public void registerEntityClass(Class entityClass, String name, int id) { - CLASS_TO_NAME_FIELD.getStatic().put(entityClass, name); - CLASS_TO_ID_FIELD.getStatic().put(entityClass, id); - } - - @Override - public void unregisterEntityClass(Class entityClass, String name, int id) { - String actualName = CLASS_TO_NAME_FIELD.getStatic().remove(entityClass); - Integer actualId = CLASS_TO_ID_FIELD.getStatic().remove(entityClass); - if (!Objects.equals(name, actualName)) { - throw new IllegalArgumentException("Expected name " + name + " didn't equal actual name " + Objects.toString(actualName)); - } else if (actualId == null || actualId != id) { - throw new IllegalArgumentException("Expected id " + id + " didn't equal actual id " + Objects.toString(actualId)); - } - } - - @Override - public Class getEntityClass(int id) { - return ID_TO_CLASS_FIELD.getStatic().get(id); - } - - @Override - public int getEntityId(Class entityClass) { - return CLASS_TO_ID_FIELD.getStatic().get(entityClass); - } - - @Override - public String getEntityName(Class entityClass) { - return CLASS_TO_NAME_FIELD.getStatic().get(entityClass); - } - - @Override - public void registerEntityId(int id, Class entityClass) { - ID_TO_CLASS_FIELD.getStatic().put(id, entityClass); - } - - @Override - public void unregisterEntityId(int id, Class entityClass) { - Class actualEntityClass = ID_TO_CLASS_FIELD.getStatic().remove(id); - if (!Objects.equals(actualEntityClass, entityClass)) { - throw new IllegalArgumentException("Exepcted entity class " + entityClass + " didn't equal actual entity class " + Objects.toString(actualEntityClass)); - } - } -} diff --git a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSImpl.java b/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSImpl.java deleted file mode 100644 index 434b2793..00000000 --- a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSImpl.java +++ /dev/null @@ -1,138 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R2; - -import net.minecraft.server.v1_9_R2.EntityHorse; -import net.minecraft.server.v1_9_R2.EntityInsentient; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.sonarpet.nms.DismountingBlocked; -import net.techcable.sonarpet.nms.EntityRegistry; -import net.techcable.sonarpet.nms.INMS; -import com.google.common.collect.ImmutableMap; - -import net.minecraft.server.v1_9_R2.Block; -import net.minecraft.server.v1_9_R2.DamageSource; -import net.minecraft.server.v1_9_R2.EntityHuman; -import net.minecraft.server.v1_9_R2.EntityLiving; -import net.minecraft.server.v1_9_R2.EntityPlayer; -import net.minecraft.server.v1_9_R2.Packet; -import net.minecraft.server.v1_9_R2.PacketPlayOutMount; -import net.minecraft.server.v1_9_R2.SoundEffect; -import net.minecraft.server.v1_9_R2.SoundEffectType; -import net.techcable.sonarpet.item.SpawnEggItemData; -import net.techcable.sonarpet.nms.BlockSoundData; -import net.techcable.sonarpet.nms.NMSEntity; -import net.techcable.sonarpet.nms.NMSInsentientEntity; -import net.techcable.sonarpet.nms.NMSSound; -import net.techcable.sonarpet.nms.versions.v1_9_R2.data.NMSSpawnEggItemData; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.craftbukkit.v1_9_R2.CraftSound; -import org.bukkit.craftbukkit.v1_9_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_9_R2.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_9_R2.entity.CraftLivingEntity; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.material.SpawnEgg; - -import static com.google.common.base.Preconditions.*; - -public class NMSImpl implements INMS { - @Override - public SpawnEggItemData createSpawnEggData(EntityType entityType, ItemMeta meta) { - checkNotNull(entityType, "Null entity type"); - checkNotNull(meta, "Null item meta"); - return new NMSSpawnEggItemData(new SpawnEgg(entityType).getData(), meta, entityType); // Pretend we use metadata to make the code happy - } - - @Override - public void mount(Entity bukkitRider, Entity bukkitVehicle) { - net.minecraft.server.v1_9_R2.Entity rider = ((CraftEntity) bukkitRider).getHandle(); - if (bukkitVehicle == null) { - net.minecraft.server.v1_9_R2.Entity vehicle = rider.getVehicle(); // This is how you *really* get the vehicle :/ - if (rider instanceof DismountingBlocked) { - ((DismountingBlocked) rider).reallyStopRiding(); - } else { - rider.stopRiding(); - } - if (vehicle != null) { - Packet packet = new PacketPlayOutMount(vehicle); - for (EntityHuman human : rider.world.players) { - ((EntityPlayer) human).playerConnection.sendPacket(packet); - } - } - } else { - checkArgument(bukkitRider.getWorld().equals(bukkitVehicle.getWorld()), "Rider is in world %s, while vehicle is in world %s", bukkitRider.getWorld().getName(), bukkitVehicle.getWorld().getName()); - net.minecraft.server.v1_9_R2.Entity vehicle = ((CraftEntity) bukkitVehicle).getHandle(); - rider.a(vehicle, true); // !! Obfuscated !! - Packet packet = new PacketPlayOutMount(vehicle); - for (EntityHuman human : rider.world.players) { - ((EntityPlayer) human).playerConnection.sendPacket(packet); - } - } - } - - @Override - public boolean spawnEntity(NMSInsentientEntity wrapper, Location l) { - EntityLiving entity = ((NMSEntityInsentientImpl) wrapper).getHandle(); - entity.spawnIn(((CraftWorld) l.getWorld()).getHandle()); - ((LivingEntity) entity.getBukkitEntity()).setCollidable(false); - entity.setLocation(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch()); - if (!l.getChunk().isLoaded()) { - l.getChunk().load(); - } - return entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); - } - - @Override - public net.techcable.sonarpet.nms.DamageSource mobAttackDamageSource(LivingEntity entity) { - return new DamageSourceImpl(DamageSource.mobAttack(((CraftLivingEntity) entity).getHandle())); - } - - @Override - public net.techcable.sonarpet.nms.DamageSource wrapDamageSource(Object handle) { - return new DamageSourceImpl((DamageSource) handle); - } - - @Override - public NMSEntity wrapEntity(Entity entity) { - net.minecraft.server.v1_9_R2.Entity handle = ((CraftEntity) entity).getHandle(); - if (handle instanceof EntityPlayer) { - return new NMSPlayerImpl((EntityPlayer) handle); - } else if (handle instanceof EntityHorse) { - return new NMSEntityHorseImpl((EntityHorse) handle); - } else if (handle instanceof EntityInsentient) { - return new NMSEntityInsentientImpl((EntityInsentient) handle); - } else if (handle instanceof EntityLiving) { - return new NMSLivingEntityImpl((EntityLiving) handle); - } else { - return new NMSEntityImpl(handle); - } - } - - private PineappleField STEP_SOUND_FIELD = PineappleField.create(Block.class, "stepSound", SoundEffectType.class); - @Override - @SuppressWarnings("deprecation") // I know about ur stupid magic value warning mom - public BlockSoundData getBlockSoundData(Material material) { - return new BlockSoundDataImpl(STEP_SOUND_FIELD.get(Block.getById(material.getId()))); - } - - @Override - @SuppressWarnings("deprecation") // I know about ur stupid magic value warning mom - public boolean isLiquid(Material block) { - return Block.getById(block.getId()).getBlockData().getMaterial().isLiquid(); - } - - @Override - public EntityRegistry createDefaultEntityRegistry() { - return new NMSEntityRegistry(); - } - - @Override - public NMSSound getNmsSound(Sound bukkitSound) { - return new NMSSoundImpl(NMSSoundImplKt.getSoundEffect(bukkitSound)); - } -} diff --git a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSLivingEntityImpl.java b/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSLivingEntityImpl.java deleted file mode 100644 index 8af2f34f..00000000 --- a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSLivingEntityImpl.java +++ /dev/null @@ -1,181 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R2; - -import net.minecraft.server.v1_9_R2.EntityHuman; -import net.minecraft.server.v1_9_R2.EntityLiving; -import net.minecraft.server.v1_9_R2.SoundEffect; -import net.techcable.pineapple.reflection.PineappleField; -import net.techcable.sonarpet.nms.DataWatcher; -import net.techcable.sonarpet.nms.NMSLivingEntity; -import net.techcable.sonarpet.nms.NMSSound; - -import org.bukkit.Sound; -import org.bukkit.craftbukkit.v1_9_R2.CraftSound; -import org.bukkit.craftbukkit.v1_9_R2.entity.CraftEntity; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; - -public class NMSLivingEntityImpl extends NMSEntityImpl implements NMSLivingEntity { - - // - // !!!!! Highly version-dependent !!!!! - // Check these every minor update! - // - public static final String IS_JUMPING_FIELD_NAME = "bd"; - - public NMSLivingEntityImpl(EntityLiving handle) { - super(handle); - } - - /** - * Set the 'offsets' for pitch and yaw to the same value as the yaw itself. - * Apparently this is needed to set rotation. - * See EntityLiving.h(FF) for details (method profiler 'headTurn'). - * Note that EntityInsentient overrides h(FF) and delegates to 'EntityAIBodyControl'. - * 'EntityAIBodyControl' is what actually accesses/uses these fields and where the mappings should be fetched. - *

- * Also, these fields have the MCP names 'renderYawOffset' and 'rotationYawHead' - */ - @Override - public void correctYaw() { - getHandle().aN = getHandle().aP = getHandle().yaw; - } - - @Override - public boolean isInLava() { - return getHandle().an(); - } - - // - // Breakage likely, check for bugs here - // - - @Override - public void setMoveSpeed(double rideSpeed) { - getHandle().l((float) rideSpeed); - } - - @Override - public void setStepHeight(float stepHeight) { - getHandle().P = stepHeight; - } - - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - @Override - public void playSound(NMSSound sound, float volume, float pitch) { - getHandle().a(((NMSSoundImpl) sound).getHandle(), volume, pitch); - } - - @Override - public double distanceTo(Entity other) { - return getHandle().h(((CraftEntity) other).getHandle()); - } - - - // - // Deobfuscated methods :) - // - - @Override - public Player findNearbyPlayer(double range) { - EntityHuman player = getHandle().world.findNearbyPlayer(getHandle(), range); - return player == null ? null : (Player) player.getBukkitEntity(); - } - - @Override - public boolean isInvisible() { - return getHandle().isInvisible(); - } - - @Override - public boolean isSneaking() { - return getHandle().isSneaking(); - } - - @Override - public void setSneaking(boolean b) { - getHandle().setSneaking(b); - } - - @Override - public void setInvisible(boolean b) { - getHandle().setInvisible(b); - } - - @Override - public boolean isSprinting() { - return getHandle().isSprinting(); - } - - @Override - public void setSprinting(boolean b) { - getHandle().setSprinting(b); - } - - @Override - public void setYaw(float yaw) { - getHandle().yaw = yaw; - } - - @Override - public void setPitch(float pitch) { - getHandle().pitch = pitch; - } - - @Override - public void setNoClip(boolean b) { - getHandle().noclip = b; - } - - @Override - public boolean isInWater() { - return getHandle().isInWater(); - } - - - @Override - public void setUpwardsMotion(double motY) { - getHandle().motY = motY; - } - - @Override - public DataWatcher getDataWatcher() { - return new DataWatcherImpl(getHandle().getDataWatcher()); - } - - @Override - public double getWidth() { - return getHandle().width; - } - - @Override - public double getLength() { - return getHandle().length; - } - - // - // Utility methods and wrappers - // - - private static final PineappleField IS_JUMPING_FIELD = PineappleField.create(EntityLiving.class, IS_JUMPING_FIELD_NAME, boolean.class); - - @Override - public boolean isJumping() { - return IS_JUMPING_FIELD.getBoxed(getHandle()); - } - - @Override - public EntityLiving getHandle() { - return (EntityLiving) super.getHandle(); - } - - @Override - public LivingEntity getBukkitEntity() { - return (LivingEntity) getHandle().getBukkitEntity(); - } -} diff --git a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSPlayerImpl.java b/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSPlayerImpl.java deleted file mode 100644 index 38acd3b8..00000000 --- a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSPlayerImpl.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R2; - -import net.minecraft.server.v1_9_R2.EntityPlayer; -import net.techcable.sonarpet.nms.NMSPlayer; - -import org.bukkit.entity.Player; - -public class NMSPlayerImpl extends NMSLivingEntityImpl implements NMSPlayer { - public NMSPlayerImpl(EntityPlayer handle) { - super(handle); - } - - @Override - public boolean isOnGround() { - return getHandle().onGround; - } - - @Override - public EntityPlayer getHandle() { - return (EntityPlayer) super.getHandle(); - } - - @Override - public Player getBukkitEntity() { - return (Player) super.getBukkitEntity(); - } -} diff --git a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NavigationImpl.java b/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NavigationImpl.java deleted file mode 100644 index 01973fe6..00000000 --- a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/NavigationImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R2; - -import lombok.*; - -import net.minecraft.server.v1_9_R2.Navigation; -import net.techcable.sonarpet.nms.PathEntity; - -import org.bukkit.craftbukkit.v1_9_R2.entity.CraftEntity; -import org.bukkit.entity.Entity; - -@RequiredArgsConstructor -public class NavigationImpl implements net.techcable.sonarpet.nms.Navigation { - private final Navigation handle; - - // - // Breakage likely, check for bugs here - // - - @Override - public boolean canEnterDoors() { - return handle.f(); - } - - @Override - public void finish() { - handle.n(); - } - - // - // Unlikely to break, even across major versions - // IE: never broken yet ^_^ - // - - @Override - public PathEntity getPathToLocation(int blockX, int blockY, int blockZ) { - return new PathEntityImpl(handle.a(blockX, blockY, blockZ)); - } - - @Override - public PathEntity getPathTo(Entity other) { - return new PathEntityImpl(handle.a(((CraftEntity) other).getHandle())); - } - - @Override - public void navigateTo(PathEntity path, double speed) { - handle.a(((PathEntityImpl) path).handle, speed); - } - - @RequiredArgsConstructor - private static class PathEntityImpl implements PathEntity { - /* package */ final net.minecraft.server.v1_9_R2.PathEntity handle; - } -} diff --git a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/data/NMSSpawnEggItemData.java b/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/data/NMSSpawnEggItemData.java deleted file mode 100644 index f24119d2..00000000 --- a/nms/v1_9_R2/src/main/java/net/techcable/sonarpet/nms/versions/v1_9_R2/data/NMSSpawnEggItemData.java +++ /dev/null @@ -1,86 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R2.data; - -import java.util.Optional; - -import com.google.common.base.Preconditions; - -import net.minecraft.server.v1_9_R2.EntityTypes; -import net.minecraft.server.v1_9_R2.Item; -import net.minecraft.server.v1_9_R2.ItemStack; -import net.minecraft.server.v1_9_R2.NBTTagCompound; -import net.techcable.sonarpet.item.SpawnEggItemData; - -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.craftbukkit.v1_9_R2.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_9_R2.util.CraftMagicNumbers; -import org.bukkit.entity.EntityType; -import org.bukkit.inventory.meta.ItemMeta; - -public class NMSSpawnEggItemData extends SpawnEggItemData { - public NMSSpawnEggItemData(byte rawData, ItemMeta meta) { - this(rawData, meta, SpawnEggItemData.DEFAULT_TYPE); - } - - public NMSSpawnEggItemData(byte rawData, ItemMeta meta, EntityType type) { - super(Material.MONSTER_EGG, rawData, createMetaWithEntityType(meta, type)); - } - - @Override - public EntityType getSpawnedType() { - return getSpawnEggEntityType(this.getMeta()); - } - - public static EntityType getSpawnEggEntityType(ItemMeta meta) { - Preconditions.checkNotNull(meta, "Null meta"); - NBTTagCompound tag = getTagFromMeta(Material.MONSTER_EGG, meta); - Preconditions.checkState(tag != null, "No nbt tag"); - Preconditions.checkState(tag.hasKeyOfType("EntityTag", 10), "No entity tag"); - NBTTagCompound entityTag = tag.getCompound("EntityTag"); - Preconditions.checkState(entityTag.hasKeyOfType("id", 8), "No internal name"); - String internalName = entityTag.getString("id"); - int id = EntityTypes.a(internalName); - EntityType type = EntityType.fromId(id); - if (type == null) - throw new IllegalStateException("No entity found with internal name " + internalName + " and id " + id); - return type; - } - - public static Optional getSpawnEggEntityTypeIfPresent(ItemMeta meta) { - try { - return Optional.of(getSpawnEggEntityType(meta)); - } catch (IllegalArgumentException | IllegalStateException e) { - return Optional.empty(); - } - } - - public static ItemMeta createMetaWithEntityType(ItemMeta meta, EntityType entityType) { - NBTTagCompound entityTag = new NBTTagCompound(); - String internalName = EntityTypes.getName(EntityTypes.a(entityType.getTypeId())); - if (internalName == null) throw new AssertionError("Couldn't find internal name for type: " + entityType); - entityTag.setString("id", internalName); - NBTTagCompound tag = getTagFromMeta(Material.MONSTER_EGG, Preconditions.checkNotNull(meta, "Null meta")); - if (tag == null) tag = new NBTTagCompound(); - tag.set("EntityTag", entityTag); - return createMetaFromTag(Material.MONSTER_EGG, tag); - } - - - public static ItemMeta createMetaFromTag(Material type, NBTTagCompound tag) { - Item item = CraftMagicNumbers.getItem(Preconditions.checkNotNull(type, "Null type")); - ItemStack stack = new ItemStack(item); - stack.setTag(Preconditions.checkNotNull(tag, "Null nbt tag")); - return CraftItemStack.getItemMeta(stack); - } - - public static NBTTagCompound getTagFromMeta(Material type, ItemMeta meta) { - Preconditions.checkNotNull(meta, "Null meta"); - Preconditions.checkNotNull(type, "Null type"); - Preconditions.checkArgument(Bukkit.getItemFactory().isApplicable(meta, type), "Meta %s isn't applicable to %s", meta, type); - Item item = CraftMagicNumbers.getItem(type); - ItemStack stack = new ItemStack(item); - boolean worked = CraftItemStack.setItemMeta(stack, meta); - if (!worked) throw new RuntimeException("Didn't work"); - return stack.getTag(); - } -} diff --git a/nms/v1_9_R2/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSSoundImpl.kt b/nms/v1_9_R2/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSSoundImpl.kt deleted file mode 100644 index f0e02c6a..00000000 --- a/nms/v1_9_R2/src/main/kotlin/net/techcable/sonarpet/nms/versions/v1_9_R2/NMSSoundImpl.kt +++ /dev/null @@ -1,21 +0,0 @@ -package net.techcable.sonarpet.nms.versions.v1_9_R2 - -import net.minecraft.server.v1_9_R2.SoundEffect -import net.techcable.sonarpet.nms.NMSSound -import net.techcable.sonarpet.utils.buildImmutableMap -import org.bukkit.Sound -import org.bukkit.craftbukkit.v1_9_R2.CraftSound - -private val BUKKIT_SOUNDS = buildImmutableMap { - for (sound in enumValues()) { - put(sound.soundEffect, sound) - } -} - -val Sound.soundEffect: SoundEffect - get() = CraftSound.getSoundEffect(CraftSound.getSound(this))!! - -class NMSSoundImpl(val handle: SoundEffect): NMSSound { - override val bukkitSound: Sound? - get() = BUKKIT_SOUNDS[handle] -} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 8f8271cc..7021e124 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,7 +1,7 @@ rootProject.name = 'SonarPet' rootProject.buildFileName = "build.gradle.kts" include 'api' -List nmsVersions = ["v1_8_R3", "v1_9_R1", "v1_9_R2", "v1_10_R1", "v1_11_R1", "v1_12_R1", "v1_13_R2"] +List nmsVersions = ["v1_12_R1", "v1_13_R2"] for (version in nmsVersions) { include "nms-$version" project(":nms-$version").projectDir = "$rootDir/nms/$version" as File From ca124d4669d1a5754aa72639e1632014636d3d43 Mon Sep 17 00:00:00 2001 From: Techcable Date: Wed, 10 Jun 2020 15:39:09 -0700 Subject: [PATCH 8/8] Now that we require modern guava, we can delete GuavaCompatibility What was I thinking with 1.8.8 support????? --- .../sonarpet/utils/compat/AncientGuava.java | 36 ----------- .../sonarpet/utils/compat/GuavaVersion.java | 24 ------- .../sonarpet/utils/compat/ModernGuava.java | 62 ------------------- .../utils/compat/GuavaCompatibility.kt | 3 - 4 files changed, 125 deletions(-) delete mode 100644 api/src/main/java/net/techcable/sonarpet/utils/compat/AncientGuava.java delete mode 100644 api/src/main/java/net/techcable/sonarpet/utils/compat/GuavaVersion.java delete mode 100644 api/src/main/java/net/techcable/sonarpet/utils/compat/ModernGuava.java delete mode 100644 api/src/main/kotlin/net/techcable/sonarpet/utils/compat/GuavaCompatibility.kt diff --git a/api/src/main/java/net/techcable/sonarpet/utils/compat/AncientGuava.java b/api/src/main/java/net/techcable/sonarpet/utils/compat/AncientGuava.java deleted file mode 100644 index 94001603..00000000 --- a/api/src/main/java/net/techcable/sonarpet/utils/compat/AncientGuava.java +++ /dev/null @@ -1,36 +0,0 @@ -package net.techcable.sonarpet.utils.compat; - -import java.util.concurrent.Executor; -import java.util.stream.Collector; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.util.concurrent.MoreExecutors; - -public class AncientGuava implements GuavaVersion { - /* package */ AncientGuava() {} - @Override - public Collector> immutableListCollector() { - return Collector., ImmutableList>of( - ImmutableList::builder, - ImmutableList.Builder::add, - (first, second) -> first.addAll(second.build()), - ImmutableList.Builder::build - ); - } - - @Override - public Collector> immutableSetCollector() { - return Collector., ImmutableSet>of( - ImmutableSet::builder, - ImmutableSet.Builder::add, - (first, second) -> first.addAll(second.build()), - ImmutableSet.Builder::build - ); - } - - @Override - public Executor directExecutor() { - return MoreExecutors.sameThreadExecutor(); - } -} diff --git a/api/src/main/java/net/techcable/sonarpet/utils/compat/GuavaVersion.java b/api/src/main/java/net/techcable/sonarpet/utils/compat/GuavaVersion.java deleted file mode 100644 index b53e059c..00000000 --- a/api/src/main/java/net/techcable/sonarpet/utils/compat/GuavaVersion.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.techcable.sonarpet.utils.compat; - -import java.util.concurrent.Executor; -import java.util.stream.Collector; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; - -public interface GuavaVersion { - Collector> immutableListCollector(); - Collector> immutableSetCollector(); - Executor directExecutor(); - - GuavaVersion INSTANCE = acquireInstance(); - static GuavaVersion acquireInstance() { - if (INSTANCE != null) return INSTANCE; - try { - ImmutableList.class.getMethod("toImmutableList"); - return new ModernGuava(); - } catch (NoSuchMethodException e) { - return new AncientGuava(); - } - } -} diff --git a/api/src/main/java/net/techcable/sonarpet/utils/compat/ModernGuava.java b/api/src/main/java/net/techcable/sonarpet/utils/compat/ModernGuava.java deleted file mode 100644 index 89e3c0d8..00000000 --- a/api/src/main/java/net/techcable/sonarpet/utils/compat/ModernGuava.java +++ /dev/null @@ -1,62 +0,0 @@ -package net.techcable.sonarpet.utils.compat; - -import lombok.*; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.util.concurrent.Executor; -import java.util.stream.Collector; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.util.concurrent.MoreExecutors; - -public class ModernGuava implements GuavaVersion { - /* package */ ModernGuava() {} - - private static final MethodHandle IMMUTABLE_LIST_COLLECTOR_METHOD; - private static final MethodHandle IMMUTABLE_SET_COLLECTOR_METHOD; - private static final MethodHandle DIRECT_EXECUTOR_METHOD; - static { - MethodType collectorType = MethodType.methodType(Collector.class); - try { - IMMUTABLE_LIST_COLLECTOR_METHOD = MethodHandles.publicLookup().findStatic( - ImmutableList.class, - "toImmutableList", - collectorType - ); - IMMUTABLE_SET_COLLECTOR_METHOD = MethodHandles.publicLookup().findStatic( - ImmutableSet.class, - "toImmutableSet", - collectorType - ); - DIRECT_EXECUTOR_METHOD = MethodHandles.publicLookup().findStatic( - MoreExecutors.class, - "directExecutor", - MethodType.methodType(Executor.class) - ); - } catch (NoSuchMethodException | IllegalAccessException e) { - throw new AssertionError("Unable to find modern guava methods", e); - } - } - @Override - @SuppressWarnings("unchecked") - @SneakyThrows - public Collector> immutableListCollector() { - return (Collector>) IMMUTABLE_LIST_COLLECTOR_METHOD.invokeExact(); - } - - @SuppressWarnings("unchecked") - @Override - @SneakyThrows - public Collector> immutableSetCollector() { - return (Collector>) IMMUTABLE_SET_COLLECTOR_METHOD.invokeExact(); - } - - @Override - @SneakyThrows - public Executor directExecutor() { - return (Executor) DIRECT_EXECUTOR_METHOD.invokeExact(); - } -} diff --git a/api/src/main/kotlin/net/techcable/sonarpet/utils/compat/GuavaCompatibility.kt b/api/src/main/kotlin/net/techcable/sonarpet/utils/compat/GuavaCompatibility.kt deleted file mode 100644 index 6a7c3796..00000000 --- a/api/src/main/kotlin/net/techcable/sonarpet/utils/compat/GuavaCompatibility.kt +++ /dev/null @@ -1,3 +0,0 @@ -package net.techcable.sonarpet.utils.compat - -object GuavaCompatibility: GuavaVersion by GuavaVersion.INSTANCE \ No newline at end of file