diff --git a/build.gradle b/build.gradle index 6c10fff34..7fbe76787 100644 --- a/build.gradle +++ b/build.gradle @@ -266,7 +266,7 @@ project(':cleanroom') { environment 'FORGE_GROUP', project.group environment 'FORGE_VERSION', props.new_forge_version - jvmArgs '-Djava.library.path=' + project.file('build/natives') + ' -Dmixin.debug=true' + jvmArgs jvm_arguments + ' -Djava.library.path=' + project.file('build/natives') + ' -Dmixin.debug=true' // jvmArgs jvm_arguments // Lazily supply the Mappings target, createSrg2Mcp.getMappings() doesn't get populated until later @@ -1122,7 +1122,7 @@ project(':cleanroom') { } test { - jvmArgs jvm_arguments + jvmArgs jvm_arguments + compiler_jvm_arguments } } diff --git a/gradle.properties b/gradle.properties index 841d46f5e..e5f75ebb4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,8 +26,8 @@ installer_tools_version = 1.3.0 # Libraries asm_version = 9.6 asm_deprecated = 7.1 -bouncepad_version = 0.4 -lwjgl_version = 3.3.2-21-CLEANROOM +bouncepad_version = 0.4.1-kappa +lwjgl_version = 3.3.2-22-CLEANROOM # Sets default memory used for Gradle commands. Can be overridden by user or command line properties. # This is required to provide enough memory for the Minecraft decompilation process. diff --git a/src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java b/src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java index ea72ece58..993df1ed6 100644 --- a/src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java +++ b/src/main/java/com/cleanroommc/hackery/enums/EnumHackery.java @@ -3,6 +3,7 @@ import com.cleanroommc.hackery.ReflectionHackery; import jdk.internal.reflect.ReflectionFactory; import org.apache.commons.lang3.ArrayUtils; +import org.lwjgl.lwjgl3ify.UnsafeHacks; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; @@ -13,12 +14,12 @@ public final class EnumHackery { - private static final ReflectionFactory factory = ReflectionFactory.getReflectionFactory(); + public static final ReflectionFactory factory = ReflectionFactory.getReflectionFactory(); private static final Field class$enumConstants, class$enumConstantDirectory, class$enumVars; private static final Method constructorAccessor$newInstance; - private static final Class[] head = {String.class, int.class}; + private static final Class[] prefix = {String.class, int.class}; static { Field constructorAccessor; @@ -59,15 +60,61 @@ public static > T addEnumEntry(Class enumClass, String enum if (parameterTypes.length != parameterValues.length) { throw new IllegalArgumentException("The amount of parameter types must be the same as the parameter values."); } + try { - Constructor constructor = enumClass.getDeclaredConstructor(ArrayUtils.addAll(head, parameterTypes)); + Constructor constructor = enumClass.getDeclaredConstructor(ArrayUtils.addAll(prefix, parameterTypes)); constructor.setAccessible(true); MethodHandle handle = MethodHandles.lookup().unreflectConstructor(constructor); Method m = enumClass.getMethod("values"); Object o = m.invoke(enumClass); - //System.out.println(Arrays.toString(parameterValues)); - return (T) handle.invokeWithArguments(ArrayUtils.addAll(new Object[]{enumName, ((Object[])o).length}, parameterValues)); + handle.invokeWithArguments(ArrayUtils.addAll(new Object[]{enumName, ((Object[])o).length}, parameterValues)); + + T instance = UnsafeHacks.newInstance(enumClass); + //System.out.println(Arrays.toString(Enum.class.getDeclaredFields())); + + Field nameField = Enum.class.getDeclaredField("name"); + nameField.setAccessible(true); + nameField.set(instance, enumName); + + Field valuesField = enumClass.getDeclaredField("$VALUES"); + valuesField.setAccessible(true); + + Field ordinalField = Enum.class.getDeclaredField("ordinal"); + ordinalField.setAccessible(true); + + // we get the current Enum[] + T[] values = (T[]) valuesField.get(null); + for (int i = 0; i < values.length; i++) { + T value = values[i]; + if (value.name().equals(enumName)) { + //setOrdinal(enumName, value.ordinal()); + ordinalField.set(enumName, value.ordinal()); + values[i] = instance; + Field[] fields = enumClass.getDeclaredFields(); + for (Field field : fields) { + if (field.getName().equals(enumName)) { + UnsafeHacks.setField(field, null,instance); + } + } + return instance; + } + } + + // we did not find it in the existing array, thus + // append it to the array + T[] newValues = Arrays.copyOf(values, values.length + 1); + newValues[newValues.length - 1] = instance; + UnsafeHacks.setField(valuesField, null, newValues); + + int ordinal = newValues.length - 1; + ordinalField.set(instance, ordinal); + //addSwitchCase(); + + + return instance; + } catch (Throwable e) { + System.out.println(e); throw new RuntimeException(e); }/* try { @@ -95,7 +142,7 @@ public static > T addEnumEntry(Class enumClass, String enum }*/ } - private static > void resetEnumRelatedCaches(Class enumClass) throws ReflectiveOperationException { + public static > void resetEnumRelatedCaches(Class enumClass) throws ReflectiveOperationException { class$enumConstants.set(enumClass, null); class$enumConstantDirectory.set(enumClass, null); if (class$enumVars != null) { diff --git a/src/main/java/net/minecraftforge/common/util/EnumHelper.java b/src/main/java/net/minecraftforge/common/util/EnumHelper.java index 86dbb2455..0148e259f 100644 --- a/src/main/java/net/minecraftforge/common/util/EnumHelper.java +++ b/src/main/java/net/minecraftforge/common/util/EnumHelper.java @@ -179,7 +179,7 @@ public static HorseArmorType addHorseArmor(String name, String textureLocation, public static void setFailsafeFieldValue(Field field, @Nullable Object target, @Nullable Object value) throws Exception { - ReflectionHackery.unsafe.putObject(ReflectionHackery.unsafe.staticFieldBase(field), ReflectionHackery.unsafe.staticFieldOffset(field), value); + ReflectionHackery.unsafe.putReference(ReflectionHackery.unsafe.staticFieldBase(field), ReflectionHackery.unsafe.staticFieldOffset(field), value); /* field.setAccessible(true); ReflectionHackery.stripFieldOfFinalModifier(field);