diff --git a/arclight-common/build.gradle b/arclight-common/build.gradle index 083948c3..603aafa8 100644 --- a/arclight-common/build.gradle +++ b/arclight-common/build.gradle @@ -30,6 +30,7 @@ arclight { bukkitVersion = 'v1_15_R1' wipeVersion = true reobfVersion = false + accessTransformer = project.file('bukkit.at') } sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' diff --git a/arclight-common/bukkit.at b/arclight-common/bukkit.at new file mode 100644 index 00000000..00e00561 --- /dev/null +++ b/arclight-common/bukkit.at @@ -0,0 +1,28 @@ +public org/bukkit/craftbukkit/v/inventory/CraftMetaItem +public org/bukkit/craftbukkit/v/inventory/CraftMetaItem/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaArmorStand/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaBanner/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaBlockState/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;Lorg/bukkit/Material;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaBook/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaBookSigned +public org/bukkit/craftbukkit/v/inventory/CraftMetaBookSigned/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaSkull +public org/bukkit/craftbukkit/v/inventory/CraftMetaSkull/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaLeatherArmor +public org/bukkit/craftbukkit/v/inventory/CraftMetaLeatherArmor/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaMap +public org/bukkit/craftbukkit/v/inventory/CraftMetaMap/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaPotion +public org/bukkit/craftbukkit/v/inventory/CraftMetaPotion/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaSpawnEgg/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaEnchantedBook +public org/bukkit/craftbukkit/v/inventory/CraftMetaEnchantedBook/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaFirework +public org/bukkit/craftbukkit/v/inventory/CraftMetaFirework/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaCharge +public org/bukkit/craftbukkit/v/inventory/CraftMetaCharge/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaKnowledgeBook/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaTropicalFishBucket +public org/bukkit/craftbukkit/v/inventory/CraftMetaTropicalFishBucket/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaCrossbow/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V +public org/bukkit/craftbukkit/v/inventory/CraftMetaSuspiciousStew/(Lorg/bukkit/craftbukkit/v/inventory/CraftMetaItem;)V \ No newline at end of file diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/bukkit/MaterialBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/bukkit/MaterialBridge.java index c54edea1..5e1cae3a 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/bukkit/MaterialBridge.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/bukkit/MaterialBridge.java @@ -15,4 +15,6 @@ public interface MaterialBridge { @Nullable MaterialPropertySpec bridge$getSpec(); + + MaterialPropertySpec.MaterialType bridge$getType(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftItemFactoryMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftItemFactoryMixin.java new file mode 100644 index 00000000..e67934e4 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftItemFactoryMixin.java @@ -0,0 +1,113 @@ +package io.izzel.arclight.common.mixin.bukkit; + +import com.google.common.collect.ImmutableMap; +import io.izzel.arclight.common.bridge.bukkit.MaterialBridge; +import io.izzel.arclight.common.mod.ArclightMod; +import io.izzel.arclight.i18n.conf.MaterialPropertySpec; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v.inventory.CraftItemFactory; +import org.bukkit.craftbukkit.v.inventory.CraftMetaArmorStand; +import org.bukkit.craftbukkit.v.inventory.CraftMetaBanner; +import org.bukkit.craftbukkit.v.inventory.CraftMetaBlockState; +import org.bukkit.craftbukkit.v.inventory.CraftMetaBook; +import org.bukkit.craftbukkit.v.inventory.CraftMetaBookSigned; +import org.bukkit.craftbukkit.v.inventory.CraftMetaCharge; +import org.bukkit.craftbukkit.v.inventory.CraftMetaCrossbow; +import org.bukkit.craftbukkit.v.inventory.CraftMetaEnchantedBook; +import org.bukkit.craftbukkit.v.inventory.CraftMetaFirework; +import org.bukkit.craftbukkit.v.inventory.CraftMetaItem; +import org.bukkit.craftbukkit.v.inventory.CraftMetaKnowledgeBook; +import org.bukkit.craftbukkit.v.inventory.CraftMetaLeatherArmor; +import org.bukkit.craftbukkit.v.inventory.CraftMetaMap; +import org.bukkit.craftbukkit.v.inventory.CraftMetaPotion; +import org.bukkit.craftbukkit.v.inventory.CraftMetaSkull; +import org.bukkit.craftbukkit.v.inventory.CraftMetaSpawnEgg; +import org.bukkit.craftbukkit.v.inventory.CraftMetaSuspiciousStew; +import org.bukkit.craftbukkit.v.inventory.CraftMetaTropicalFishBucket; +import org.bukkit.craftbukkit.v.util.CraftLegacy; +import org.bukkit.inventory.meta.ItemMeta; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.lang.reflect.Constructor; +import java.util.Map; +import java.util.function.BiFunction; + +@Mixin(value = CraftItemFactory.class, remap = false) +public class CraftItemFactoryMixin { + + private static final Map> TYPES = ImmutableMap + .>builder() + .put("ARMOR_STAND", (a, b) -> new CraftMetaArmorStand(b)) + .put("BANNER", (a, b) -> new CraftMetaBanner(b)) + .put("TILE_ENTITY", (a, b) -> new CraftMetaBlockState(b, a)) + .put("BOOK", (a, b) -> new CraftMetaBook(b)) + .put("BOOK_SIGNED", (a, b) -> new CraftMetaBookSigned(b)) + .put("SKULL", (a, b) -> new CraftMetaSkull(b)) + .put("LEATHER_ARMOR", (a, b) -> new CraftMetaLeatherArmor(b)) + .put("MAP", (a, b) -> new CraftMetaMap(b)) + .put("POTION", (a, b) -> new CraftMetaPotion(b)) + .put("SPAWN_EGG", (a, b) -> new CraftMetaSpawnEgg(b)) + .put("ENCHANTED", (a, b) -> new CraftMetaEnchantedBook(b)) + .put("FIREWORK", (a, b) -> new CraftMetaFirework(b)) + .put("FIREWORK_EFFECT", (a, b) -> new CraftMetaCharge(b)) + .put("KNOWLEDGE_BOOK", (a, b) -> new CraftMetaKnowledgeBook(b)) + .put("TROPICAL_FISH_BUCKET", (a, b) -> new CraftMetaTropicalFishBucket(b)) + .put("CROSSBOW", (a, b) -> new CraftMetaCrossbow(b)) + .put("SUSPICIOUS_STEW", (a, b) -> new CraftMetaSuspiciousStew(b)) + .put("UNSPECIFIC", (a, b) -> new CraftMetaItem(b)) + .build(); + + @SuppressWarnings("AmbiguousMixinReference") + @Inject(method = "getItemMeta*", require = 0, expect = 0, cancellable = true, at = @At("HEAD")) + private void arclight$getItemMeta(Material material, CraftMetaItem meta, CallbackInfoReturnable cir) { + MaterialBridge bridge = (MaterialBridge) (Object) CraftLegacy.fromLegacy(material); + if (bridge.bridge$getType() != MaterialPropertySpec.MaterialType.VANILLA) { + MaterialPropertySpec spec = bridge.bridge$getSpec(); + BiFunction func; + if (spec == null || spec.itemMetaType == null) { + func = (a, b) -> new CraftMetaItem(b); + } else { + func = TYPES.get(spec.itemMetaType); + if (func == null) { + func = (a, b) -> dynamicCreate(spec.itemMetaType, a, b); + } + } + cir.setReturnValue(func.apply(material, meta)); + } + } + + private ItemMeta dynamicCreate(String type, Material material, CraftMetaItem meta) { + try { + Class cl = Class.forName(type); + if (!CraftMetaItem.class.isAssignableFrom(cl)) { + throw new IllegalArgumentException("" + cl + " is not assignable from " + CraftMetaItem.class); + } + for (Constructor constructor : cl.getDeclaredConstructors()) { + Class[] parameterTypes = constructor.getParameterTypes(); + if (parameterTypes.length == 1) { + if (parameterTypes[0] == Material.class) { + constructor.setAccessible(true); + return (ItemMeta) constructor.newInstance(material); + } else if (CraftMetaItem.class.isAssignableFrom(parameterTypes[0])) { + constructor.setAccessible(true); + return (ItemMeta) constructor.newInstance(meta); + } + } else if (parameterTypes.length == 2) { + if (parameterTypes[0] == Material.class && CraftMetaItem.class.isAssignableFrom(parameterTypes[1])) { + constructor.setAccessible(true); + return (ItemMeta) constructor.newInstance(material, meta); + } else if (parameterTypes[1] == Material.class && CraftMetaItem.class.isAssignableFrom(parameterTypes[0])) { + constructor.setAccessible(true); + return (ItemMeta) constructor.newInstance(meta, material); + } + } + } + } catch (Exception e) { + ArclightMod.LOGGER.warn("Bad itemMetaType {} for {}: {}", type, material, e); + } + return new CraftMetaItem(meta); + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/MaterialMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/MaterialMixin.java index f22cfa5c..fc09f8f2 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/MaterialMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/MaterialMixin.java @@ -154,6 +154,11 @@ public abstract class MaterialMixin implements MaterialBridge { return arclight$spec; } + @Override + public MaterialPropertySpec.MaterialType bridge$getType() { + return arclight$type; + } + @Override public void bridge$setupBlock(ResourceLocation key, Block block, MaterialPropertySpec spec) { this.arclight$spec = spec.clone(); diff --git a/arclight-common/src/main/resources/mixins.arclight.bukkit.json b/arclight-common/src/main/resources/mixins.arclight.bukkit.json index 518b0859..1acf0869 100644 --- a/arclight-common/src/main/resources/mixins.arclight.bukkit.json +++ b/arclight-common/src/main/resources/mixins.arclight.bukkit.json @@ -12,6 +12,7 @@ "CraftChunkMixin", "CraftConsoleCommandSenderMixin", "CraftEventFactoryMixin", + "CraftItemFactoryMixin", "CraftMagicNumbersMixin", "CraftServerMixin", "JavaPluginLoaderMixin", diff --git a/arclight-forge-1.14/build.gradle b/arclight-forge-1.14/build.gradle index e3114704..f1f34e26 100644 --- a/arclight-forge-1.14/build.gradle +++ b/arclight-forge-1.14/build.gradle @@ -30,6 +30,7 @@ arclight { bukkitVersion = 'v1_14_R1' wipeVersion = true reobfVersion = true + accessTransformer = project(':arclight-common').file('bukkit.at') } sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' diff --git a/arclight-forge-1.15/build.gradle b/arclight-forge-1.15/build.gradle index c58ca3c9..3b857e48 100644 --- a/arclight-forge-1.15/build.gradle +++ b/arclight-forge-1.15/build.gradle @@ -30,6 +30,7 @@ arclight { bukkitVersion = 'v1_15_R1' wipeVersion = true reobfVersion = true + accessTransformer = project(':arclight-common').file('bukkit.at') } sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' diff --git a/build.gradle b/build.gradle index 1b086538..c59aa10b 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ allprojects { version '1.0.0-SNAPSHOT' ext { - agpVersion = '1.6' + agpVersion = '1.7' } task cleanBuild { diff --git a/i18n-config/src/main/java/io/izzel/arclight/i18n/conf/MaterialPropertySpec.java b/i18n-config/src/main/java/io/izzel/arclight/i18n/conf/MaterialPropertySpec.java index e540a842..e6bc13f4 100644 --- a/i18n-config/src/main/java/io/izzel/arclight/i18n/conf/MaterialPropertySpec.java +++ b/i18n-config/src/main/java/io/izzel/arclight/i18n/conf/MaterialPropertySpec.java @@ -59,6 +59,9 @@ public class MaterialPropertySpec implements Cloneable { @Setting("craftingRemainingItem") public String craftingRemainingItem; + @Setting("itemMetaType") + public String itemMetaType; + @Override public MaterialPropertySpec clone() { try {