Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package net.minecraft.src;
- import java.lang.reflect.*;
- import java.util.*;
- public class mod_Test extends BaseMod {
- /*
- * Found at: http://niceideas.ch/roller2/badtrash/entry/java_create_enum_instances_dynamically
- * Updated to compile properly in eclipse/Java 1.6/1.7
- */
- private static enum TestEnum {
- a,
- b,
- c;
- };
- @Override
- public String getVersion() {
- return "Test";
- }
- @Override
- public void load() {
- addEnum(TestEnum.class, "d");
- addEnum(TestEnum.class, "e");
- addEnum(TestEnum.class, "f");
- EnumArmorMaterial armor = addArmorMaterial("Piggy", 1337, new int[]{1, 3, 2, 1}, 1000);
- EnumToolMaterial tool = addToolMaterial("Piggy", 0, 59, 2.0F, 0, 15);
- System.out.println(Arrays.deepToString(TestEnum.values()));
- System.out.println(Arrays.deepToString(EnumArmorMaterial.values()));
- System.out.println(Arrays.deepToString(EnumToolMaterial.values()));
- }
- public EnumArmorMaterial addArmorMaterial(String name, int durability, int[] reductionAmounts, int enchantability)
- {
- if (!isSetup)
- {
- setup();
- }
- if (isJad)
- {
- return addEnum(EnumArmorMaterial.class, name,
- new Class[] { String.class, int.class, int.class, int[].class, int.class },
- new Object[]{ name, 0, durability, reductionAmounts, enchantability });
- }
- else
- {
- return addEnum(EnumArmorMaterial.class, name,
- new Class[] { int.class, int[].class, int.class },
- new Object[]{ durability, reductionAmounts, enchantability });
- }
- }
- public EnumToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, int damage, int enchantability)
- {
- if (!isSetup)
- {
- setup();
- }
- if (isJad)
- {
- return addEnum(EnumToolMaterial.class, name,
- new Class[] { String.class, int.class, int.class, int.class, float.class, int.class, int.class },
- new Object[]{ name, 0, harvestLevel, maxUses, efficiency, damage, enchantability });
- }
- else
- {
- return addEnum(EnumToolMaterial.class, name,
- new Class[] { int.class, int.class, float.class, int.class, int.class },
- new Object[]{ harvestLevel, maxUses, efficiency, damage, enchantability });
- }
- }
- private Object reflectionFactory = null;
- private Method newConstructorAccessor = null;
- private Method newInstance = null;
- private Method newFieldAccessor = null;
- private Method fieldAccessorSet = null;
- private boolean isJad = false;
- private boolean isSetup = false;
- private void setup()
- {
- if (isSetup)
- {
- return;
- }
- try {
- //Jad is stupid, decompiles the enums wrong, so it has redundant String,int params.
- EnumArmorMaterial.class.getDeclaredConstructor(String.class, int.class, String.class, int.class, int.class, int[].class, int.class);
- isJad = true;
- }
- catch (Exception e)
- {
- //Nom nom nom
- }
- try {
- Method getReflectionFactory = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("getReflectionFactory");
- reflectionFactory = getReflectionFactory.invoke(null);
- newConstructorAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newConstructorAccessor", Constructor.class);
- newInstance = Class.forName("sun.reflect.ConstructorAccessor").getDeclaredMethod("newInstance", Object[].class);
- newFieldAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newFieldAccessor", Field.class, boolean.class);
- fieldAccessorSet = Class.forName("sun.reflect.FieldAccessor").getDeclaredMethod("set", Object.class, Object.class);
- } catch (Exception e) {
- e.printStackTrace();
- }
- isSetup = true;
- }
- private Object getConstructorAccessor(Class<?> enumClass, Class<?>[] additionalParameterTypes) throws Exception {
- Class<?>[] parameterTypes = new Class[additionalParameterTypes.length + 2];
- parameterTypes[0] = String.class;
- parameterTypes[1] = int.class;
- System.arraycopy(additionalParameterTypes, 0, parameterTypes, 2, additionalParameterTypes.length);
- return newConstructorAccessor.invoke(reflectionFactory, enumClass.getDeclaredConstructor(parameterTypes));
- }
- private <T extends Enum<?>> T makeEnum(Class<T> enumClass, String value, int ordinal, Class<?>[] additionalTypes, Object[] additionalValues) throws Exception {
- Object[] parms = new Object[additionalValues.length + 2];
- parms[0] = value;
- parms[1] = Integer.valueOf(ordinal);
- System.arraycopy(additionalValues, 0, parms, 2, additionalValues.length);
- return enumClass.cast(newInstance.invoke(getConstructorAccessor(enumClass, additionalTypes), new Object[]{parms}));
- }
- private void setFailsafeFieldValue(Field field, Object target, Object value) throws Exception {
- field.setAccessible(true);
- Field modifiersField = Field.class.getDeclaredField("modifiers");
- modifiersField.setAccessible(true);
- modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
- Object fieldAccessor = newFieldAccessor.invoke(reflectionFactory, field, false);
- fieldAccessorSet.invoke(fieldAccessor, target, value);
- }
- private void blankField(Class<?> enumClass, String fieldName) throws Exception {
- for (Field field : Class.class.getDeclaredFields()) {
- if (field.getName().contains(fieldName)) {
- field.setAccessible(true);
- setFailsafeFieldValue(field, enumClass, null);
- break;
- }
- }
- }
- private void cleanEnumCache(Class<?> enumClass) throws Exception {
- blankField(enumClass, "enumConstantDirectory");
- blankField(enumClass, "enumConstants");
- }
- public <T extends Enum<?>> T addEnum(Class<T> enumType, String enumName) {
- return addEnum(enumType, enumName, new Class<?>[]{}, new Object[]{});
- }
- @SuppressWarnings("unchecked")
- public <T extends Enum<?>> T addEnum(Class<T> enumType, String enumName, Class<?>[] paramTypes, Object[] paramValues) {
- if (!isSetup)
- {
- setup();
- }
- Field valuesField = null;
- Field[] fields = enumType.getDeclaredFields();
- for (Field field : fields) {
- if (field.getName().contains("$VALUES")) {
- valuesField = field;
- break;
- }
- }
- valuesField.setAccessible(true);
- try {
- T[] previousValues = (T[])valuesField.get(enumType);
- List<T> values = new ArrayList<T>(Arrays.asList(previousValues));
- T newValue = (T)makeEnum(enumType, enumName, values.size(), paramTypes, paramValues);
- values.add(newValue);
- setFailsafeFieldValue(valuesField, null, values.toArray((T[]) Array.newInstance(enumType, 0)));
- cleanEnumCache(enumType);
- return newValue;
- } catch (Exception e) {
- e.printStackTrace();
- throw new RuntimeException(e.getMessage(), e);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment