Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-11-20 01:40:06 +01:00
Merge pull request #291 from KennyTV/1.15
Fix Java 12+ compatibility
Dieser Commit ist enthalten in:
Commit
cb6c346323
@ -7,6 +7,7 @@ import com.boydti.fawe.bukkit.adapter.NMSAdapter;
|
|||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.collection.BitArray4096;
|
import com.boydti.fawe.object.collection.BitArray4096;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
|
import com.boydti.fawe.util.ReflectionUtils;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
@ -83,11 +84,7 @@ public final class BukkitAdapter_1_13 extends NMSAdapter {
|
|||||||
} catch (NoSuchFieldException paper) {
|
} catch (NoSuchFieldException paper) {
|
||||||
tmp = DataPaletteBlock.class.getDeclaredField("j");
|
tmp = DataPaletteBlock.class.getDeclaredField("j");
|
||||||
}
|
}
|
||||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
ReflectionUtils.setAccessibleNonFinal(tmp);
|
||||||
modifiersField.setAccessible(true);
|
|
||||||
int modifiers = modifiersField.getInt(tmp);
|
|
||||||
int newModifiers = modifiers & (~Modifier.FINAL);
|
|
||||||
if (newModifiers != modifiers) modifiersField.setInt(tmp, newModifiers);
|
|
||||||
fieldLock = tmp;
|
fieldLock = tmp;
|
||||||
fieldLock.setAccessible(true);
|
fieldLock.setAccessible(true);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
|||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.collection.BitArray4096;
|
import com.boydti.fawe.object.collection.BitArray4096;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
|
import com.boydti.fawe.util.ReflectionUtils;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
@ -83,11 +84,7 @@ public final class BukkitAdapter_1_14 extends NMSAdapter {
|
|||||||
} catch (NoSuchFieldException paper) {
|
} catch (NoSuchFieldException paper) {
|
||||||
tmp = DataPaletteBlock.class.getDeclaredField("j");
|
tmp = DataPaletteBlock.class.getDeclaredField("j");
|
||||||
}
|
}
|
||||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
ReflectionUtils.setAccessibleNonFinal(tmp);
|
||||||
modifiersField.setAccessible(true);
|
|
||||||
int modifiers = modifiersField.getInt(tmp);
|
|
||||||
int newModifiers = modifiers & (~Modifier.FINAL);
|
|
||||||
if (newModifiers != modifiers) modifiersField.setInt(tmp, newModifiers);
|
|
||||||
fieldLock = tmp;
|
fieldLock = tmp;
|
||||||
fieldLock.setAccessible(true);
|
fieldLock.setAccessible(true);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import com.boydti.fawe.bukkit.adapter.NMSAdapter;
|
|||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.collection.BitArray4096;
|
import com.boydti.fawe.object.collection.BitArray4096;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
|
import com.boydti.fawe.util.ReflectionUtils;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
@ -18,7 +19,6 @@ import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
|
|||||||
import sun.misc.Unsafe;
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
@ -66,11 +66,7 @@ public final class BukkitAdapter_1_15 extends NMSAdapter {
|
|||||||
fieldDirtyBits.setAccessible(true);
|
fieldDirtyBits.setAccessible(true);
|
||||||
|
|
||||||
Field tmp = DataPaletteBlock.class.getDeclaredField("j");
|
Field tmp = DataPaletteBlock.class.getDeclaredField("j");
|
||||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
ReflectionUtils.setAccessibleNonFinal(tmp);
|
||||||
modifiersField.setAccessible(true);
|
|
||||||
int modifiers = modifiersField.getInt(tmp);
|
|
||||||
int newModifiers = modifiers & (~Modifier.FINAL);
|
|
||||||
if (newModifiers != modifiers) modifiersField.setInt(tmp, newModifiers);
|
|
||||||
fieldLock = tmp;
|
fieldLock = tmp;
|
||||||
fieldLock.setAccessible(true);
|
fieldLock.setAccessible(true);
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ public class LocalBlockVector2DSet implements Set<BlockVector2> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] toArray() {
|
public Object[] toArray() {
|
||||||
return toArray(null);
|
return toArray((Object[]) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -160,7 +160,7 @@ public class LocalBlockVectorSet implements Set<BlockVector3> {
|
|||||||
|
|
||||||
@NotNull @Override
|
@NotNull @Override
|
||||||
public Object[] toArray() {
|
public Object[] toArray() {
|
||||||
return toArray(null);
|
return toArray((Object[]) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull @Override
|
@NotNull @Override
|
||||||
|
@ -78,7 +78,7 @@ public class ReflectionUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Object makeEnum(Class<?> enumClass, String value, int ordinal,
|
public static Object makeEnum(Class<?> enumClass, String value, int ordinal,
|
||||||
Class<?>[] additionalTypes, Object[] additionalValues) throws Exception {
|
Class<?>[] additionalTypes, Object[] additionalValues) throws Exception {
|
||||||
Object[] parms = new Object[additionalValues.length + 2];
|
Object[] parms = new Object[additionalValues.length + 2];
|
||||||
parms[0] = value;
|
parms[0] = value;
|
||||||
parms[1] = ordinal;
|
parms[1] = ordinal;
|
||||||
@ -96,9 +96,8 @@ public class ReflectionUtils {
|
|||||||
return ReflectionFactory.getReflectionFactory().newConstructorAccessor(enumClass.getDeclaredConstructor(parameterTypes));
|
return ReflectionFactory.getReflectionFactory().newConstructorAccessor(enumClass.getDeclaredConstructor(parameterTypes));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setFailsafeFieldValue(Field field, Object target, Object value)
|
public static void setAccessibleNonFinal(Field field)
|
||||||
throws NoSuchFieldException, IllegalAccessException {
|
throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
|
||||||
|
|
||||||
// let's make the field accessible
|
// let's make the field accessible
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
|
|
||||||
@ -106,15 +105,35 @@ public class ReflectionUtils {
|
|||||||
// not be final anymore, thus tricking reflection into
|
// not be final anymore, thus tricking reflection into
|
||||||
// letting us modify the static final field
|
// letting us modify the static final field
|
||||||
if (Modifier.isFinal(field.getModifiers())) {
|
if (Modifier.isFinal(field.getModifiers())) {
|
||||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
try {
|
||||||
modifiersField.setAccessible(true);
|
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||||
int modifiers = modifiersField.getInt(field);
|
modifiersField.setAccessible(true);
|
||||||
|
int modifiers = modifiersField.getInt(field);
|
||||||
|
|
||||||
// blank out the final bit in the modifiers int
|
// blank out the final bit in the modifiers int
|
||||||
modifiers &= ~Modifier.FINAL;
|
modifiers &= ~Modifier.FINAL;
|
||||||
modifiersField.setInt(field, modifiers);
|
modifiersField.setInt(field, modifiers);
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
// Java 12+ compatibility - search fields with hidden method for modifiers
|
||||||
|
// same concept as above, just with a more hacky way of getting to the modifiers
|
||||||
|
Method getDeclaredFields0 = Class.class.getDeclaredMethod("getDeclaredFields0", boolean.class);
|
||||||
|
getDeclaredFields0.setAccessible(true);
|
||||||
|
Field[] fields = (Field[]) getDeclaredFields0.invoke(Field.class, false);
|
||||||
|
for (Field classField : fields) {
|
||||||
|
if ("modifiers".equals(classField.getName())) {
|
||||||
|
classField.setAccessible(true);
|
||||||
|
classField.set(field, field.getModifiers() & ~Modifier.FINAL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setFailsafeFieldValue(Field field, Object target, Object value)
|
||||||
|
throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
|
||||||
|
|
||||||
|
setAccessibleNonFinal(field);
|
||||||
try {
|
try {
|
||||||
FieldAccessor fa = ReflectionFactory.getReflectionFactory().newFieldAccessor(field, false);
|
FieldAccessor fa = ReflectionFactory.getReflectionFactory().newFieldAccessor(field, false);
|
||||||
fa.set(target, value);
|
fa.set(target, value);
|
||||||
@ -124,7 +143,7 @@ public class ReflectionUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void blankField(Class<?> enumClass, String fieldName)
|
private static void blankField(Class<?> enumClass, String fieldName)
|
||||||
throws NoSuchFieldException, IllegalAccessException {
|
throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
|
||||||
for (Field field : Class.class.getDeclaredFields()) {
|
for (Field field : Class.class.getDeclaredFields()) {
|
||||||
if (field.getName().contains(fieldName)) {
|
if (field.getName().contains(fieldName)) {
|
||||||
AccessibleObject.setAccessible(new Field[]{field}, true);
|
AccessibleObject.setAccessible(new Field[]{field}, true);
|
||||||
@ -134,8 +153,8 @@ public class ReflectionUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void cleanEnumCache(Class<?> enumClass)
|
static void cleanEnumCache(Class<?> enumClass)
|
||||||
throws NoSuchFieldException, IllegalAccessException {
|
throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
|
||||||
blankField(enumClass, "enumConstantDirectory"); // Sun (Oracle?!?) JDK 1.5/6
|
blankField(enumClass, "enumConstantDirectory"); // Sun (Oracle?!?) JDK 1.5/6
|
||||||
blankField(enumClass, "enumConstants"); // IBM JDK
|
blankField(enumClass, "enumConstants"); // IBM JDK
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,10 @@ package com.boydti.fawe.util;
|
|||||||
|
|
||||||
import sun.misc.Unsafe;
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.AccessibleObject;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -41,15 +44,15 @@ public class ReflectionUtils9 {
|
|||||||
|
|
||||||
// 5. Set new values field
|
// 5. Set new values field
|
||||||
try {
|
try {
|
||||||
setFailsafeFieldValue(valuesField, null,
|
ReflectionUtils.setFailsafeFieldValue(valuesField, null,
|
||||||
values.toArray((T[]) Array.newInstance(enumType, 0)));
|
values.toArray((T[]) Array.newInstance(enumType, 0)));
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Field ordinalField = Enum.class.getDeclaredField("ordinal");
|
Field ordinalField = Enum.class.getDeclaredField("ordinal");
|
||||||
setFailsafeFieldValue(ordinalField, newValue, 0);
|
ReflectionUtils.setFailsafeFieldValue(ordinalField, newValue, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Clean enum cache
|
// 6. Clean enum cache
|
||||||
cleanEnumCache(enumType);
|
ReflectionUtils.cleanEnumCache(enumType);
|
||||||
return newValue;
|
return newValue;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -64,55 +67,11 @@ public class ReflectionUtils9 {
|
|||||||
Object instance = unsafe.allocateInstance(enumClass);
|
Object instance = unsafe.allocateInstance(enumClass);
|
||||||
|
|
||||||
Field ordinalField = Enum.class.getDeclaredField("ordinal");
|
Field ordinalField = Enum.class.getDeclaredField("ordinal");
|
||||||
setFailsafeFieldValue(ordinalField, instance, 0);
|
ReflectionUtils.setFailsafeFieldValue(ordinalField, instance, 0);
|
||||||
|
|
||||||
Field nameField = Enum.class.getDeclaredField("name");
|
Field nameField = Enum.class.getDeclaredField("name");
|
||||||
setFailsafeFieldValue(nameField, instance, value);
|
ReflectionUtils.setFailsafeFieldValue(nameField, instance, value);
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setFailsafeFieldValue(Field field, Object target, Object value)
|
|
||||||
throws NoSuchFieldException, IllegalAccessException {
|
|
||||||
|
|
||||||
// let's make the field accessible
|
|
||||||
field.setAccessible(true);
|
|
||||||
|
|
||||||
// next we change the modifier in the Field instance to
|
|
||||||
// not be final anymore, thus tricking reflection into
|
|
||||||
// letting us modify the static final field
|
|
||||||
if (Modifier.isFinal(field.getModifiers())) {
|
|
||||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
|
||||||
modifiersField.setAccessible(true);
|
|
||||||
int modifiers = modifiersField.getInt(field);
|
|
||||||
|
|
||||||
// blank out the final bit in the modifiers int
|
|
||||||
modifiers &= ~Modifier.FINAL;
|
|
||||||
modifiersField.setInt(field, modifiers);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (target == null) field.set(null, value);
|
|
||||||
else field.set(target, value);
|
|
||||||
} catch (NoSuchMethodError error) {
|
|
||||||
field.set(target, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void blankField(Class<?> enumClass, String fieldName)
|
|
||||||
throws NoSuchFieldException, IllegalAccessException {
|
|
||||||
for (Field field : Class.class.getDeclaredFields()) {
|
|
||||||
if (field.getName().contains(fieldName)) {
|
|
||||||
AccessibleObject.setAccessible(new Field[]{field}, true);
|
|
||||||
setFailsafeFieldValue(field, enumClass, null);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void cleanEnumCache(Class<?> enumClass)
|
|
||||||
throws NoSuchFieldException, IllegalAccessException {
|
|
||||||
blankField(enumClass, "enumConstantDirectory"); // Sun (Oracle?!?) JDK 1.5/6
|
|
||||||
blankField(enumClass, "enumConstants"); // IBM JDK
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren