Add IExtensibleEnum, fix DimensionType create method

This commit is contained in:
tterrag 2019-02-07 16:36:30 -05:00
parent 9245975955
commit 79c17cb542
7 changed files with 102 additions and 14 deletions

View file

@ -1,5 +1,14 @@
--- a/net/minecraft/enchantment/EnumEnchantmentType.java
+++ b/net/minecraft/enchantment/EnumEnchantmentType.java
@@ -13,7 +13,7 @@
import net.minecraft.item.ItemTool;
import net.minecraft.item.ItemTrident;
-public enum EnumEnchantmentType {
+public enum EnumEnchantmentType implements net.minecraftforge.common.IExtensibleEnum {
ALL {
public boolean func_77557_a(Item p_77557_1_) {
for(EnumEnchantmentType enumenchantmenttype : EnumEnchantmentType.values()) {
@@ -90,5 +90,16 @@
private EnumEnchantmentType() {
}
@ -11,7 +20,7 @@
+ }
+
+ public static EnumEnchantmentType create(String name, java.util.function.Predicate<Item> delegate) {
+ return null;
+ throw new IllegalStateException("Enum not extended");
+ }
+
+ public boolean func_77557_a(Item p_77557_1_) {

View file

@ -1,11 +1,20 @@
--- a/net/minecraft/entity/EnumCreatureType.java
+++ b/net/minecraft/entity/EnumCreatureType.java
@@ -6,7 +6,7 @@
import net.minecraft.entity.passive.EntityWaterMob;
import net.minecraft.entity.passive.IAnimal;
-public enum EnumCreatureType {
+public enum EnumCreatureType implements net.minecraftforge.common.IExtensibleEnum {
MONSTER(IMob.class, 70, false, false),
CREATURE(EntityAnimal.class, 10, true, true),
AMBIENT(EntityAmbientCreature.class, 15, true, false),
@@ -39,4 +39,8 @@
public boolean func_82705_e() {
return this.field_82707_i;
}
+
+ public static EnumCreatureType create(String name, Class<? extends IAnimal> p_i47849_3_, int p_i47849_4_, boolean p_i47849_5_, boolean p_i47849_6_) {
+ return null;
+ throw new IllegalStateException("Enum not extended");
+ }
}

View file

@ -1,5 +1,14 @@
--- a/net/minecraft/entity/passive/HorseArmorType.java
+++ b/net/minecraft/entity/passive/HorseArmorType.java
@@ -7,7 +7,7 @@
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
-public enum HorseArmorType {
+public enum HorseArmorType implements net.minecraftforge.common.IExtensibleEnum {
NONE(0),
IRON(5, "iron", "meo"),
GOLD(7, "gold", "goo"),
@@ -16,6 +16,7 @@
private final String field_188586_e;
private final String field_188587_f;
@ -18,7 +27,7 @@
+ }
+
+ public static HorseArmorType create(String name, int strength, String texture, String hash, Item item) {
+ return null;
+ throw new IllegalStateException("Enum not extended");
+ }
+
public int func_188579_a() {

View file

@ -1,11 +1,20 @@
--- a/net/minecraft/item/ArmorMaterial.java
+++ b/net/minecraft/item/ArmorMaterial.java
@@ -10,7 +10,7 @@
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
-public enum ArmorMaterial implements IArmorMaterial {
+public enum ArmorMaterial implements IArmorMaterial, net.minecraftforge.common.IExtensibleEnum {
LEATHER("leather", 5, new int[]{1, 2, 3, 1}, 15, SoundEvents.field_187728_s, 0.0F, () -> {
return Ingredient.func_199804_a(Items.field_151116_aA);
}),
@@ -77,4 +77,8 @@
public float func_200901_e() {
return this.field_189417_k;
}
+
+ public static ArmorMaterial create(String name, String p_i48533_3_, int p_i48533_4_, int[] p_i48533_5_, int p_i48533_6_, SoundEvent p_i48533_7_, float p_i48533_8_, Supplier<Ingredient> p_i48533_9_) {
+ return null;
+ throw new IllegalStateException("Enum not extended");
+ }
}
+}

View file

@ -1,5 +1,14 @@
--- a/net/minecraft/world/dimension/DimensionType.java
+++ b/net/minecraft/world/dimension/DimensionType.java
@@ -2,7 +2,7 @@
import java.util.function.Supplier;
-public enum DimensionType {
+public enum DimensionType implements net.minecraftforge.common.IExtensibleEnum {
OVERWORLD(0, "overworld", "", OverworldDimension::new),
NETHER(-1, "the_nether", "_nether", NetherDimension::new),
THE_END(1, "the_end", "_end", EndDimension::new);
@@ -11,12 +11,19 @@
private final String field_186075_e;
private final String field_186076_f;
@ -20,15 +29,14 @@
}
public int func_186068_a() {
@@ -54,4 +61,11 @@
@@ -54,4 +61,10 @@
throw new IllegalArgumentException("Invalid dimension " + p_193417_0_);
}
+
+ public boolean shouldLoadSpawn(){ return this.shouldLoadSpawn; }
+
+ public static DimensionType create(int id, String name, String suffix, Supplier<? extends Dimension> provider, boolean shouldLoadSpawn)
+ {
+ return null;
+ public static DimensionType create(String enumName, int id, String name, String suffix, Supplier<? extends Dimension> provider, boolean shouldLoadSpawn) {
+ throw new IllegalStateException("Enum not extended");
+ }
}

View file

@ -20,6 +20,8 @@
package net.minecraftforge.common.asm;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Collectors;
import net.minecraftforge.fml.loading.AdvancedLogMessageAdapter;
import org.apache.logging.log4j.LogManager;
@ -43,6 +45,7 @@ public class RuntimeEnumExtender implements ILaunchPluginService {
private static final Logger LOGGER = LogManager.getLogger();
private final Type STRING = Type.getType(String.class);
private final Type ENUM = Type.getType(Enum.class);
private final Type MARKER_IFACE = Type.getType("Lnet/minecraftforge/common/IExtensibleEnum;");
private final Type ARRAY_UTILS = Type.getType("Lorg/apache/commons/lang3/ArrayUtils;"); //Don't directly reference this to prevent class loading.
private final String ADD_DESC = Type.getMethodDescriptor(Type.getType(Object[].class), Type.getType(Object[].class), Type.getType(Object.class));
private final Type UNSAFE_HACKS = Type.getType("Lnet/minecraftforge/fml/UnsafeHacks;"); //Again, not direct reference to prevent class loading.
@ -75,13 +78,28 @@ public class RuntimeEnumExtender implements ILaunchPluginService {
final int flags = Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC;
FieldNode values = classNode.fields.stream().filter(f -> f.desc.contentEquals(array.getDescriptor()) && ((f.access & flags) == flags)).findFirst().orElse(null);
if (!classNode.interfaces.contains(MARKER_IFACE.getInternalName())) {
return classNode;
}
//Static methods named "create", with first argument as a string, and returning this type
classNode.methods.stream().filter(m -> ((m.access & Opcodes.ACC_STATIC) != 0) && m.name.equals("create") && Type.getReturnType(m.desc).equals(classType)).forEach(mtd ->
List<MethodNode> candidates = classNode.methods.stream()
.filter(m -> ((m.access & Opcodes.ACC_STATIC) != 0) && m.name.equals("create") && Type.getReturnType(m.desc).equals(classType))
.collect(Collectors.toList());
candidates.forEach(mtd ->
{
Type[] args = Type.getArgumentTypes(mtd.desc);
if (args.length == 0 || !args[0].equals(STRING))
return;
if (args.length == 0 || !args[0].equals(STRING)) {
LOGGER.fatal(()->new AdvancedLogMessageAdapter(sb-> {
sb.append("Enum has create method without String as first parameter:\n");
sb.append(" Enum: " + classType.getDescriptor()).append("\n");
sb.append(" Target: ").append(mtd.name + mtd.desc).append("\n");
}));
throw new IllegalStateException("Enum has create method without String as first parameter: " + mtd.name + mtd.desc);
}
Type[] ctrArgs = new Type[args.length + 1];
ctrArgs[0] = STRING;
ctrArgs[1] = Type.INT_TYPE;
@ -95,7 +113,8 @@ public class RuntimeEnumExtender implements ILaunchPluginService {
{
LOGGER.fatal(()->new AdvancedLogMessageAdapter(sb-> {
sb.append("Enum has create method with no matching constructor:\n");
sb.append(" Enum: " + classType.getDescriptor()).append("\n");
sb.append(" Enum: ").append(classType.getDescriptor()).append("\n");
sb.append(" Candidate: ").append(mtd.desc).append("\n");
sb.append(" Target: ").append(desc).append("\n");
classNode.methods.stream().filter(m -> m.name.equals("<init>")).forEach(m -> sb.append(" : ").append(m.desc).append("\n"));
}));

View file

@ -0,0 +1,25 @@
package net.minecraftforge.common;
/**
* To be implemented on vanilla enums that should be enhanced with ASM to be
* extensible. If this is implemented on a class, the class must define a static
* method called "create" which takes a String (enum name), and the rest of the
* parameters matching a constructor.
* <p>
* For example, an enum with the constructor {@code MyEnum(Object foo)} would
* require the method:
*
* <pre>
* public static MyEnum create(String name, Object foo)
* {
* throw new IllegalStateException("Enum not extended");
* }
* </pre>
*
* The method contents will be replaced with ASM at runtime. Multiple
* {@code create} methods <strong>can</strong> be defined as long as each
* matches a constructor.
*/
public interface IExtensibleEnum
{
}