geforkt von Mirrors/FastAsyncWorldEdit
Fix some issues with java 9 / reflection
Dieser Commit ist enthalten in:
Ursprung
8de1fff263
Commit
2172ebba83
@ -231,9 +231,8 @@ public class BukkitChunk_All extends IntFaweChunk<Chunk, BukkitQueue_All> {
|
|||||||
int xx = bx + x;
|
int xx = bx + x;
|
||||||
|
|
||||||
BlockTypes type = BlockTypes.getFromStateId(combined);
|
BlockTypes type = BlockTypes.getFromStateId(combined);
|
||||||
|
if (type == BlockTypes.__RESERVED__) continue;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case __RESERVED__:
|
|
||||||
continue;
|
|
||||||
case AIR:
|
case AIR:
|
||||||
case CAVE_AIR:
|
case CAVE_AIR:
|
||||||
case VOID_AIR:
|
case VOID_AIR:
|
||||||
@ -280,9 +279,8 @@ public class BukkitChunk_All extends IntFaweChunk<Chunk, BukkitQueue_All> {
|
|||||||
int j = place ? index : 4095 - index;
|
int j = place ? index : 4095 - index;
|
||||||
int combined = newArray[j];
|
int combined = newArray[j];
|
||||||
BlockTypes type = BlockTypes.getFromStateId(combined);
|
BlockTypes type = BlockTypes.getFromStateId(combined);
|
||||||
|
if (type == BlockTypes.__RESERVED__) continue;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case __RESERVED__:
|
|
||||||
continue;
|
|
||||||
case AIR:
|
case AIR:
|
||||||
case CAVE_AIR:
|
case CAVE_AIR:
|
||||||
case VOID_AIR:
|
case VOID_AIR:
|
||||||
|
@ -130,6 +130,19 @@ public class AsyncChunk implements Chunk {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState[] getTileEntities(boolean b) {
|
||||||
|
if (!isLoaded()) {
|
||||||
|
return new BlockState[0];
|
||||||
|
}
|
||||||
|
return TaskManager.IMP.sync(new RunnableVal<BlockState[]>() {
|
||||||
|
@Override
|
||||||
|
public void run(BlockState[] value) {
|
||||||
|
this.value = world.getChunkAt(x, z).getTileEntities(b);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLoaded() {
|
public boolean isLoaded() {
|
||||||
return world.isChunkLoaded(x, z);
|
return world.isChunkLoaded(x, z);
|
||||||
|
@ -6,11 +6,8 @@ import com.sk89q.worldedit.extension.input.InputParseException;
|
|||||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||||
import com.sk89q.worldedit.util.command.Dispatcher;
|
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||||
import java.util.AbstractMap;
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public abstract class FaweParser<T> extends InputParser<T> {
|
public abstract class FaweParser<T> extends InputParser<T> {
|
||||||
protected FaweParser(WorldEdit worldEdit) {
|
protected FaweParser(WorldEdit worldEdit) {
|
||||||
@ -98,6 +95,7 @@ public abstract class FaweParser<T> extends InputParser<T> {
|
|||||||
args.add(arg);
|
args.add(arg);
|
||||||
command = full.substring(0, startPos);
|
command = full.substring(0, startPos);
|
||||||
}
|
}
|
||||||
|
Collections.reverse(args);
|
||||||
ParseEntry entry = new ParseEntry(full, command, i > 0 ? and.get(i - 1) : false);
|
ParseEntry entry = new ParseEntry(full, command, i > 0 ? and.get(i - 1) : false);
|
||||||
keys.add(new AbstractMap.SimpleEntry<>(entry, args));
|
keys.add(new AbstractMap.SimpleEntry<>(entry, args));
|
||||||
}
|
}
|
||||||
|
@ -449,8 +449,10 @@ public class Config {
|
|||||||
*/
|
*/
|
||||||
private void setAccessible(Field field) throws NoSuchFieldException, IllegalAccessException {
|
private void setAccessible(Field field) throws NoSuchFieldException, IllegalAccessException {
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
|
if (Modifier.isFinal(field.getModifiers())) {
|
||||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||||
modifiersField.setAccessible(true);
|
modifiersField.setAccessible(true);
|
||||||
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
|
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,11 @@ public class ReflectionUtils {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T extends Enum<?>> T addEnum(Class<T> enumType, String enumName) {
|
public static <T extends Enum<?>> T addEnum(Class<T> enumType, String enumName) {
|
||||||
return addEnum(enumType, enumName, new Class<?>[]{} , new Object[]{});
|
try {
|
||||||
|
return addEnum(enumType, enumName, new Class<?>[]{}, new Object[]{});
|
||||||
|
} catch (Throwable ignore) {
|
||||||
|
return ReflectionUtils9.addEnum(enumType, enumName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends Enum<?>> T addEnum(Class<T> enumType, String enumName, Class<?>[] additionalTypes, Object[] additionalValues) {
|
public static <T extends Enum<?>> T addEnum(Class<T> enumType, String enumName, Class<?>[] additionalTypes, Object[] additionalValues) {
|
||||||
@ -145,6 +149,7 @@ public class ReflectionUtils {
|
|||||||
// next we change the modifier in the Field instance to
|
// next we change the modifier in the Field instance to
|
||||||
// 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())) {
|
||||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||||
modifiersField.setAccessible(true);
|
modifiersField.setAccessible(true);
|
||||||
int modifiers = modifiersField.getInt(field);
|
int modifiers = modifiersField.getInt(field);
|
||||||
@ -152,6 +157,7 @@ public class ReflectionUtils {
|
|||||||
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FieldAccessor fa = ReflectionFactory.getReflectionFactory().newFieldAccessor(field, false);
|
FieldAccessor fa = ReflectionFactory.getReflectionFactory().newFieldAccessor(field, false);
|
||||||
|
147
worldedit-core/src/main/java/com/boydti/fawe/util/ReflectionUtils9.java
Normale Datei
147
worldedit-core/src/main/java/com/boydti/fawe/util/ReflectionUtils9.java
Normale Datei
@ -0,0 +1,147 @@
|
|||||||
|
package com.boydti.fawe.util;
|
||||||
|
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
|
import java.lang.reflect.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ReflectionUtils9 {
|
||||||
|
public static <T extends Enum<?>> T addEnum(Class<T> enumType, String enumName) {
|
||||||
|
|
||||||
|
// 0. Sanity checks
|
||||||
|
if (!Enum.class.isAssignableFrom(enumType)) {
|
||||||
|
throw new RuntimeException("class " + enumType + " is not an instance of Enum");
|
||||||
|
}
|
||||||
|
// 1. Lookup "$VALUES" holder in enum class and get previous enum instances
|
||||||
|
Field valuesField = null;
|
||||||
|
Field[] fields = enumType.getDeclaredFields();
|
||||||
|
for (Field field : fields) {
|
||||||
|
if (field.getName().contains("$VALUES")) {
|
||||||
|
valuesField = field;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AccessibleObject.setAccessible(new Field[]{valuesField}, true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// 2. Copy it
|
||||||
|
T[] previousValues = (T[]) valuesField.get(enumType);
|
||||||
|
List values = new ArrayList(Arrays.asList(previousValues));
|
||||||
|
|
||||||
|
// 3. build new enum
|
||||||
|
T newValue = (T) makeEnum(enumType, // The target enum class
|
||||||
|
enumName, // THE NEW ENUM INSTANCE TO BE DYNAMICALLY ADDED
|
||||||
|
values.size()); // can be used to pass values to the enum constuctor
|
||||||
|
|
||||||
|
// 4. add new value
|
||||||
|
values.add(newValue);
|
||||||
|
|
||||||
|
// 5. Set new values field
|
||||||
|
try {
|
||||||
|
setFailsafeFieldValue(valuesField, null,
|
||||||
|
values.toArray((T[]) Array.newInstance(enumType, 0)));
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Field ordinalField = Enum.class.getDeclaredField("ordinal");
|
||||||
|
setFailsafeFieldValue(ordinalField, newValue, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. Clean enum cache
|
||||||
|
cleanEnumCache(enumType);
|
||||||
|
return newValue;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Enum<?>> void clearEnum(Class<T> enumType) {
|
||||||
|
// 0. Sanity checks
|
||||||
|
if (!Enum.class.isAssignableFrom(enumType)) {
|
||||||
|
throw new RuntimeException("class " + enumType + " is not an instance of Enum");
|
||||||
|
}
|
||||||
|
// 1. Lookup "$VALUES" holder in enum class and get previous enum instances
|
||||||
|
Field valuesField = null;
|
||||||
|
Field[] fields = enumType.getDeclaredFields();
|
||||||
|
for (Field field : fields) {
|
||||||
|
if (field.getName().contains("$VALUES")) {
|
||||||
|
valuesField = field;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AccessibleObject.setAccessible(new Field[]{valuesField}, true);
|
||||||
|
try {
|
||||||
|
setFailsafeFieldValue(valuesField, null, Array.newInstance(enumType, 0));
|
||||||
|
// 6. Clean enum cache
|
||||||
|
cleanEnumCache(enumType);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object makeEnum(Class<?> enumClass, String value, int ordinal) throws Exception {
|
||||||
|
Constructor<?> constructor = Unsafe.class.getDeclaredConstructors()[0];
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
Unsafe unsafe = (Unsafe) constructor.newInstance();
|
||||||
|
Object instance = unsafe.allocateInstance(enumClass);
|
||||||
|
|
||||||
|
Field ordinalField = Enum.class.getDeclaredField("ordinal");
|
||||||
|
setFailsafeFieldValue(ordinalField, instance, 0);
|
||||||
|
|
||||||
|
Field nameField = Enum.class.getDeclaredField("name");
|
||||||
|
setFailsafeFieldValue(nameField, instance, value);
|
||||||
|
|
||||||
|
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 {
|
||||||
|
System.out.println("Target " + target + " | " + field.getName());
|
||||||
|
if (target == null) field.set(null, value);
|
||||||
|
else field.set(target, value);
|
||||||
|
|
||||||
|
// FieldAccessor fa = ReflectionFactory.getReflectionFactory().newFieldAccessor(field, false);
|
||||||
|
// fa.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
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,7 @@ public class SolidBlockMask extends BlockTypeMask {
|
|||||||
public static boolean[] getTypes() {
|
public static boolean[] getTypes() {
|
||||||
boolean[] types = new boolean[BlockTypes.size()];
|
boolean[] types = new boolean[BlockTypes.size()];
|
||||||
for (BlockTypes type : BlockTypes.values) {
|
for (BlockTypes type : BlockTypes.values) {
|
||||||
types[type.ordinal()] = type.getMaterial().isSolid();
|
types[type.getInternalId()] = type.getMaterial().isSolid();
|
||||||
}
|
}
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
@ -652,57 +652,29 @@ public enum BlockTypes implements BlockType {
|
|||||||
Instance
|
Instance
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
private final static class Settings {
|
||||||
|
private final int internalId;
|
||||||
private final ItemTypes itemType;
|
private final ItemTypes itemType;
|
||||||
|
|
||||||
private final String id;
|
|
||||||
private final BlockState defaultState;
|
private final BlockState defaultState;
|
||||||
|
|
||||||
private final AbstractProperty[] propertiesMapArr;
|
private final AbstractProperty[] propertiesMapArr;
|
||||||
private final AbstractProperty[] propertiesArr;
|
private final AbstractProperty[] propertiesArr;
|
||||||
|
|
||||||
private final List<AbstractProperty> propertiesList;
|
private final List<AbstractProperty> propertiesList;
|
||||||
private final Map<String, AbstractProperty> propertiesMap;
|
private final Map<String, AbstractProperty> propertiesMap;
|
||||||
private final Set<AbstractProperty> propertiesSet;
|
private final Set<AbstractProperty> propertiesSet;
|
||||||
|
|
||||||
private final BlockMaterial blockMaterial;
|
private final BlockMaterial blockMaterial;
|
||||||
private final int permutations;
|
private final int permutations;
|
||||||
|
|
||||||
@Deprecated public static final int BIT_OFFSET; // Used internally
|
|
||||||
@Deprecated public static final int BIT_MASK; // Used internally
|
|
||||||
|
|
||||||
private BlockState[] states;
|
private BlockState[] states;
|
||||||
|
|
||||||
BlockTypes() {
|
Settings(BlockTypes type, String id, int internalId) {
|
||||||
id = "minecraft:" + name().toLowerCase();
|
this.internalId = internalId;
|
||||||
itemType = null;
|
|
||||||
defaultState = null;
|
|
||||||
propertiesMapArr = null;
|
|
||||||
propertiesArr = null;
|
|
||||||
propertiesList = null;
|
|
||||||
propertiesMap = null;
|
|
||||||
propertiesSet = null;
|
|
||||||
blockMaterial = null;
|
|
||||||
permutations = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockTypes(String id) {
|
|
||||||
if (id == null) id = "minecraft:" + name().toLowerCase();
|
|
||||||
// If it has no namespace, assume minecraft.
|
|
||||||
else if (!id.contains(":")) {
|
|
||||||
id = "minecraft:" + id;
|
|
||||||
}
|
|
||||||
String propertyString = null;
|
String propertyString = null;
|
||||||
int propI = id.indexOf('[');
|
int propI = id.indexOf('[');
|
||||||
if (propI != -1) {
|
if (propI != -1) {
|
||||||
propertyString = id.substring(propI + 1, id.length() - 1);
|
propertyString = id.substring(propI + 1, id.length() - 1);
|
||||||
id = id.substring(0, propI);
|
|
||||||
}
|
}
|
||||||
this.id = id;
|
|
||||||
|
|
||||||
int maxInternalStateId = 0;
|
int maxInternalStateId = 0;
|
||||||
Map<String, ? extends Property> properties = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getProperties(this);
|
Map<String, ? extends Property> properties = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getProperties(type);
|
||||||
if (!properties.isEmpty()) {
|
if (!properties.isEmpty()) {
|
||||||
// Ensure the properties are registered
|
// Ensure the properties are registered
|
||||||
int maxOrdinal = 0;
|
int maxOrdinal = 0;
|
||||||
@ -737,24 +709,54 @@ public enum BlockTypes implements BlockType {
|
|||||||
}
|
}
|
||||||
this.permutations = maxInternalStateId;
|
this.permutations = maxInternalStateId;
|
||||||
|
|
||||||
this.blockMaterial = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(this);
|
this.blockMaterial = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(type);
|
||||||
this.itemType = ItemTypes.get(this);
|
this.itemType = ItemTypes.get(type);
|
||||||
|
|
||||||
if (propertyString != null) {
|
if (propertyString != null) {
|
||||||
this.defaultState = new BlockState(parseProperties(propertyString));
|
this.defaultState = new BlockState(parseProperties(propertyString, propertiesMap));
|
||||||
} else {
|
} else {
|
||||||
this.defaultState = new BlockState(this.getInternalId());
|
this.defaultState = new BlockState(internalId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int parseProperties(String properties, Map<String, AbstractProperty> propertyMap) {
|
||||||
|
int id = internalId;
|
||||||
|
for (String keyPair : properties.split(",")) {
|
||||||
|
String[] split = keyPair.split("=");
|
||||||
|
String name = split[0];
|
||||||
|
String value = split[1];
|
||||||
|
AbstractProperty btp = propertyMap.get(name);
|
||||||
|
id = btp.modify(id, btp.getValueFor(value));
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String id;
|
||||||
|
private final Settings settings;
|
||||||
|
|
||||||
|
BlockTypes() {
|
||||||
|
if (name().indexOf(':') == -1) id = "minecraft:" + name().toLowerCase();
|
||||||
|
else id = name().toLowerCase();
|
||||||
|
settings = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(String id, int internalId) {
|
||||||
|
try {
|
||||||
|
ReflectionUtils.setFailsafeFieldValue(BlockTypes.class.getDeclaredField("settings"), this, new Settings(this, id, internalId));
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockState withPropertyId(int propertyId) {
|
public BlockState withPropertyId(int propertyId) {
|
||||||
if (propertiesArr.length == 0) return defaultState;
|
if (settings.propertiesArr.length == 0) return settings.defaultState;
|
||||||
BlockState[] tmp = states;
|
BlockState[] tmp = settings.states;
|
||||||
if (tmp == null) {
|
if (tmp == null) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if ((tmp = states) == null) {
|
if ((tmp = settings.states) == null) {
|
||||||
tmp = states = new BlockState[getMaxStateId() + 1];
|
tmp = settings.states = new BlockState[getMaxStateId() + 1];
|
||||||
tmp[defaultState.getInternalPropertiesId()] = defaultState;
|
tmp[settings.defaultState.getInternalPropertiesId()] = settings.defaultState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -771,12 +773,12 @@ public enum BlockTypes implements BlockType {
|
|||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public int getMaxStateId() {
|
public int getMaxStateId() {
|
||||||
return permutations;
|
return settings.permutations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Extent extent, Vector get, Vector set) throws WorldEditException {
|
public boolean apply(Extent extent, Vector get, Vector set) throws WorldEditException {
|
||||||
return extent.setBlock(set, this.defaultState);
|
return extent.setBlock(set, this.settings.defaultState);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mask toMask(Extent extent) {
|
public Mask toMask(Extent extent) {
|
||||||
@ -817,7 +819,15 @@ public enum BlockTypes implements BlockType {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public BlockState withProperties(String properties) {
|
public BlockState withProperties(String properties) {
|
||||||
return withStateId(parseProperties(properties));
|
int id = getInternalId();
|
||||||
|
for (String keyPair : properties.split(",")) {
|
||||||
|
String[] split = keyPair.split("=");
|
||||||
|
String name = split[0];
|
||||||
|
String value = split[1];
|
||||||
|
AbstractProperty btp = settings.propertiesMap.get(name);
|
||||||
|
id = btp.modify(id, btp.getValueFor(value));
|
||||||
|
}
|
||||||
|
return withStateId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -827,7 +837,7 @@ public enum BlockTypes implements BlockType {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Map<String, ? extends Property> getPropertyMap() {
|
public Map<String, ? extends Property> getPropertyMap() {
|
||||||
return this.propertiesMap;
|
return this.settings.propertiesMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -837,12 +847,12 @@ public enum BlockTypes implements BlockType {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public List<? extends Property> getProperties() {
|
public List<? extends Property> getProperties() {
|
||||||
return this.propertiesList;
|
return this.settings.propertiesList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Set<? extends Property> getPropertiesSet() {
|
public Set<? extends Property> getPropertiesSet() {
|
||||||
return this.propertiesSet;
|
return this.settings.propertiesSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -853,17 +863,17 @@ public enum BlockTypes implements BlockType {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public <V> Property<V> getProperty(String name) {
|
public <V> Property<V> getProperty(String name) {
|
||||||
return this.propertiesMap.get(name);
|
return this.settings.propertiesMap.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasProperty(PropertyKey key) {
|
public boolean hasProperty(PropertyKey key) {
|
||||||
int ordinal = key.ordinal();
|
int ordinal = key.ordinal();
|
||||||
return this.propertiesMapArr.length > ordinal ? this.propertiesMapArr[ordinal] != null : false;
|
return this.settings.propertiesMapArr.length > ordinal ? this.settings.propertiesMapArr[ordinal] != null : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <V> Property<V> getProperty(PropertyKey key) {
|
public <V> Property<V> getProperty(PropertyKey key) {
|
||||||
try {
|
try {
|
||||||
return this.propertiesMapArr[key.ordinal()];
|
return this.settings.propertiesMapArr[key.ordinal()];
|
||||||
} catch (IndexOutOfBoundsException ignore) {
|
} catch (IndexOutOfBoundsException ignore) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -875,7 +885,7 @@ public enum BlockTypes implements BlockType {
|
|||||||
* @return The default state
|
* @return The default state
|
||||||
*/
|
*/
|
||||||
public BlockState getDefaultState() {
|
public BlockState getDefaultState() {
|
||||||
return this.defaultState;
|
return this.settings.defaultState;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -894,7 +904,7 @@ public enum BlockTypes implements BlockType {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public ItemType getItemType() {
|
public ItemType getItemType() {
|
||||||
return itemType;
|
return settings.itemType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -903,19 +913,7 @@ public enum BlockTypes implements BlockType {
|
|||||||
* @return The material
|
* @return The material
|
||||||
*/
|
*/
|
||||||
public BlockMaterial getMaterial() {
|
public BlockMaterial getMaterial() {
|
||||||
return this.blockMaterial;
|
return this.settings.blockMaterial;
|
||||||
}
|
|
||||||
|
|
||||||
protected int parseProperties(String properties) {
|
|
||||||
int id = this.getInternalId();
|
|
||||||
for (String keyPair : properties.split(",")) {
|
|
||||||
String[] split = keyPair.split("=");
|
|
||||||
String name = split[0];
|
|
||||||
String value = split[1];
|
|
||||||
AbstractProperty btp = (AbstractProperty) getProperty(name);
|
|
||||||
id = btp.modify(id, btp.getValueFor(value));
|
|
||||||
}
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -926,7 +924,7 @@ public enum BlockTypes implements BlockType {
|
|||||||
* @return internal id
|
* @return internal id
|
||||||
*/
|
*/
|
||||||
public int getInternalId() {
|
public int getInternalId() {
|
||||||
return this.ordinal();
|
return this.settings.internalId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -939,7 +937,12 @@ public enum BlockTypes implements BlockType {
|
|||||||
Static Initializer
|
Static Initializer
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@Deprecated public static final int BIT_OFFSET; // Used internally
|
||||||
|
@Deprecated public static final int BIT_MASK; // Used internally
|
||||||
|
|
||||||
private static final Map<String, BlockTypes> $REGISTRY = new HashMap<>();
|
private static final Map<String, BlockTypes> $REGISTRY = new HashMap<>();
|
||||||
|
private static int $LENGTH;
|
||||||
public static final BlockTypes[] values;
|
public static final BlockTypes[] values;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -948,6 +951,7 @@ public enum BlockTypes implements BlockType {
|
|||||||
Map<String, String> blockMap = blocks.stream().collect(Collectors.toMap(item -> item.charAt(item.length() - 1) == ']' ? item.substring(0, item.indexOf('[')) : item, item -> item));
|
Map<String, String> blockMap = blocks.stream().collect(Collectors.toMap(item -> item.charAt(item.length() - 1) == ']' ? item.substring(0, item.indexOf('[')) : item, item -> item));
|
||||||
|
|
||||||
BlockTypes[] oldValues = BlockTypes.values();
|
BlockTypes[] oldValues = BlockTypes.values();
|
||||||
|
$LENGTH = oldValues.length;
|
||||||
int size = blockMap.size();
|
int size = blockMap.size();
|
||||||
for (BlockTypes type : oldValues) {
|
for (BlockTypes type : oldValues) {
|
||||||
if (!blockMap.containsKey(type.getId())) size++;
|
if (!blockMap.containsKey(type.getId())) size++;
|
||||||
@ -959,12 +963,14 @@ public enum BlockTypes implements BlockType {
|
|||||||
BIT_OFFSET = MathMan.log2nlz(size);
|
BIT_OFFSET = MathMan.log2nlz(size);
|
||||||
BIT_MASK = ((1 << BIT_OFFSET) - 1);
|
BIT_MASK = ((1 << BIT_OFFSET) - 1);
|
||||||
|
|
||||||
|
LinkedHashSet<BlockTypes> newValues = new LinkedHashSet<>(Arrays.asList(oldValues));
|
||||||
for (BlockTypes type : oldValues) {
|
for (BlockTypes type : oldValues) {
|
||||||
String block = blockMap.getOrDefault(type.getId(), type.getId());
|
String block = blockMap.getOrDefault(type.getId(), type.getId());
|
||||||
register(block);
|
BlockTypes registered = register(block);
|
||||||
|
if (!newValues.contains(registered)) newValues.add(registered);
|
||||||
}
|
}
|
||||||
// Cache the values
|
// Cache the values
|
||||||
values = values();
|
values = newValues.toArray(new BlockTypes[newValues.size()]);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
@ -995,17 +1001,14 @@ public enum BlockTypes implements BlockType {
|
|||||||
try {
|
try {
|
||||||
existing = valueOf(enumName.toUpperCase());
|
existing = valueOf(enumName.toUpperCase());
|
||||||
} catch (IllegalArgumentException ignore) {}
|
} catch (IllegalArgumentException ignore) {}
|
||||||
|
if (existing == null) {
|
||||||
Class[] paramTypes = new Class[]{String.class};
|
existing = ReflectionUtils.addEnum(BlockTypes.class, enumName);
|
||||||
Object[] args = new Object[]{id};
|
|
||||||
|
|
||||||
if (existing != null) {
|
|
||||||
// Load values
|
|
||||||
ReflectionUtils.copyEnum(existing, enumName, paramTypes, args);
|
|
||||||
} else {
|
|
||||||
// Create it
|
|
||||||
existing = ReflectionUtils.addEnum(BlockTypes.class, enumName, paramTypes, args);
|
|
||||||
}
|
}
|
||||||
|
int internalId = existing.ordinal();
|
||||||
|
if (internalId == 0 && existing != __RESERVED__) {
|
||||||
|
internalId = $LENGTH++;
|
||||||
|
}
|
||||||
|
existing.init(id, internalId);
|
||||||
if (typeName.startsWith("minecraft:")) $REGISTRY.put(typeName.substring(10), existing);
|
if (typeName.startsWith("minecraft:")) $REGISTRY.put(typeName.substring(10), existing);
|
||||||
$REGISTRY.put(typeName, existing);
|
$REGISTRY.put(typeName, existing);
|
||||||
return existing;
|
return existing;
|
||||||
|
@ -32,4 +32,7 @@ public interface EntityType {
|
|||||||
default String getName() {
|
default String getName() {
|
||||||
return getId();
|
return getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public int getInternalId();
|
||||||
}
|
}
|
||||||
|
@ -30,9 +30,7 @@ import com.sk89q.worldedit.world.item.ItemType;
|
|||||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public enum EntityTypes implements EntityType {
|
public enum EntityTypes implements EntityType {
|
||||||
/*
|
/*
|
||||||
@ -40,6 +38,7 @@ public enum EntityTypes implements EntityType {
|
|||||||
Replaced at runtime by the entity registry
|
Replaced at runtime by the entity registry
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
__RESERVED__,
|
||||||
AREA_EFFECT_CLOUD,
|
AREA_EFFECT_CLOUD,
|
||||||
ARMOR_STAND,
|
ARMOR_STAND,
|
||||||
ARROW,
|
ARROW,
|
||||||
@ -139,6 +138,7 @@ public enum EntityTypes implements EntityType {
|
|||||||
;
|
;
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
|
private int internalId;
|
||||||
|
|
||||||
EntityTypes() {
|
EntityTypes() {
|
||||||
this(null);
|
this(null);
|
||||||
@ -151,6 +151,7 @@ public enum EntityTypes implements EntityType {
|
|||||||
id = "minecraft:" + id;
|
id = "minecraft:" + id;
|
||||||
}
|
}
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
this.internalId = ordinal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -163,6 +164,11 @@ public enum EntityTypes implements EntityType {
|
|||||||
return getId();
|
return getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInternalId() {
|
||||||
|
return internalId;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
Static Initializer
|
Static Initializer
|
||||||
@ -237,19 +243,23 @@ public enum EntityTypes implements EntityType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final Map<String, EntityTypes> $REGISTRY = new HashMap<>();
|
private static final Map<String, EntityTypes> $REGISTRY = new HashMap<>();
|
||||||
|
private static int $LENGTH;
|
||||||
public static final EntityTypes[] values;
|
public static final EntityTypes[] values;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
Collection<String> ents = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getEntityRegistry().registerEntities();
|
Collection<String> ents = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getEntityRegistry().registerEntities();
|
||||||
|
EntityTypes[] oldValues = values();
|
||||||
|
$LENGTH = oldValues.length;
|
||||||
|
LinkedHashSet<EntityTypes> newValues = new LinkedHashSet<>(Arrays.asList(oldValues));
|
||||||
if (!ents.isEmpty()) { // No types found - use defaults
|
if (!ents.isEmpty()) { // No types found - use defaults
|
||||||
for (String ent : ents) {
|
for (String ent : ents) {
|
||||||
register(ent);
|
EntityTypes registered = register(ent);
|
||||||
|
if (!newValues.contains(registered)) newValues.add(registered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Cache the values
|
// Cache the values
|
||||||
values = values();
|
values = newValues.toArray(new EntityTypes[newValues.size()]);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
@ -264,11 +274,12 @@ public enum EntityTypes implements EntityType {
|
|||||||
// Check existing
|
// Check existing
|
||||||
EntityTypes existing = null;
|
EntityTypes existing = null;
|
||||||
try { existing = valueOf(enumName.toUpperCase()); } catch (IllegalArgumentException ignore) {}
|
try { existing = valueOf(enumName.toUpperCase()); } catch (IllegalArgumentException ignore) {}
|
||||||
if (existing != null) {
|
if (existing == null) {
|
||||||
// TODO additional registration
|
existing = ReflectionUtils.addEnum(EntityTypes.class, enumName);
|
||||||
} else {
|
}
|
||||||
// Create it
|
int internalId = existing.ordinal();
|
||||||
existing = ReflectionUtils.addEnum(EntityTypes.class, enumName, new Class[]{String.class}, new Object[]{id});
|
if (internalId == 0 && existing != __RESERVED__) {
|
||||||
|
existing.internalId = $LENGTH++;
|
||||||
}
|
}
|
||||||
if (typeName.startsWith("minecraft:")) $REGISTRY.put(typeName.substring(10), existing);
|
if (typeName.startsWith("minecraft:")) $REGISTRY.put(typeName.substring(10), existing);
|
||||||
$REGISTRY.put(typeName, existing);
|
$REGISTRY.put(typeName, existing);
|
||||||
|
@ -34,9 +34,7 @@ import com.sk89q.worldedit.world.registry.LegacyMapper;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public enum ItemTypes implements ItemType {
|
public enum ItemTypes implements ItemType {
|
||||||
/*
|
/*
|
||||||
@ -45,6 +43,7 @@ public enum ItemTypes implements ItemType {
|
|||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
__RESERVED__,
|
||||||
ACACIA_BOAT,
|
ACACIA_BOAT,
|
||||||
ACACIA_BUTTON,
|
ACACIA_BUTTON,
|
||||||
ACACIA_DOOR,
|
ACACIA_DOOR,
|
||||||
@ -842,6 +841,7 @@ public enum ItemTypes implements ItemType {
|
|||||||
private BlockTypes blockType;
|
private BlockTypes blockType;
|
||||||
private final String id;
|
private final String id;
|
||||||
private final BaseItem defaultState;
|
private final BaseItem defaultState;
|
||||||
|
private int internalId;
|
||||||
|
|
||||||
ItemTypes() {
|
ItemTypes() {
|
||||||
this(null);
|
this(null);
|
||||||
@ -855,6 +855,7 @@ public enum ItemTypes implements ItemType {
|
|||||||
}
|
}
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.defaultState = new BaseItemStack(this, 1);
|
this.defaultState = new BaseItemStack(this, 1);
|
||||||
|
this.internalId = ordinal();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setBlockType(BlockTypes type) {
|
private void setBlockType(BlockTypes type) {
|
||||||
@ -872,7 +873,7 @@ public enum ItemTypes implements ItemType {
|
|||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public int getInternalId() {
|
public int getInternalId() {
|
||||||
return ordinal();
|
return this.internalId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -920,19 +921,23 @@ public enum ItemTypes implements ItemType {
|
|||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
*/
|
*/
|
||||||
private static final Map<String, ItemTypes> $REGISTRY = new HashMap<>();
|
private static final Map<String, ItemTypes> $REGISTRY = new HashMap<>();
|
||||||
|
private static int $LENGTH;
|
||||||
public static final ItemTypes[] values;
|
public static final ItemTypes[] values;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
Collection<String> items = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getItemRegistry().registerItems();
|
Collection<String> items = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getItemRegistry().registerItems();
|
||||||
|
ItemTypes[] oldValues = values();
|
||||||
|
$LENGTH = oldValues.length;
|
||||||
|
LinkedHashSet<ItemTypes> newValues = new LinkedHashSet<>(Arrays.asList(oldValues));
|
||||||
if (!items.isEmpty()) { // No types found - use defaults
|
if (!items.isEmpty()) { // No types found - use defaults
|
||||||
for (String item : items) {
|
for (String item : items) {
|
||||||
register(item);
|
ItemTypes registered = register(item);
|
||||||
|
if (!newValues.contains(registered)) newValues.add(registered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Cache the values
|
// Cache the values
|
||||||
values = values();
|
values = newValues.toArray(new ItemTypes[newValues.size()]);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
@ -964,11 +969,12 @@ public enum ItemTypes implements ItemType {
|
|||||||
// Check existing
|
// Check existing
|
||||||
ItemTypes existing = null;
|
ItemTypes existing = null;
|
||||||
try { existing = valueOf(enumName.toUpperCase()); } catch (IllegalArgumentException ignore) {}
|
try { existing = valueOf(enumName.toUpperCase()); } catch (IllegalArgumentException ignore) {}
|
||||||
if (existing != null) {
|
if (existing == null) {
|
||||||
// TODO additional registration
|
existing = ReflectionUtils.addEnum(ItemTypes.class, enumName);
|
||||||
} else {
|
}
|
||||||
// Create it
|
int internalId = existing.ordinal();
|
||||||
existing = ReflectionUtils.addEnum(ItemTypes.class, enumName, new Class[]{String.class}, new Object[]{id});
|
if (internalId == 0 && existing != __RESERVED__) {
|
||||||
|
existing.internalId = $LENGTH++;
|
||||||
}
|
}
|
||||||
if (typeName.startsWith("minecraft:")) $REGISTRY.put(typeName.substring(10), existing);
|
if (typeName.startsWith("minecraft:")) $REGISTRY.put(typeName.substring(10), existing);
|
||||||
$REGISTRY.put(typeName, existing);
|
$REGISTRY.put(typeName, existing);
|
||||||
|
BIN
worldedit-core/src/main/resources/darwin/x86_64/liblz4-java.dylib
Normale Datei
BIN
worldedit-core/src/main/resources/darwin/x86_64/liblz4-java.dylib
Normale Datei
Binäre Datei nicht angezeigt.
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren