#1393: Improve field rename handling and centralize conversion between bukkit and string more

By: DerFrZocker <derrieple@gmail.com>
This commit is contained in:
CraftBukkit/Spigot
2024-05-04 08:19:07 +10:00
parent f91094ddfd
commit acdb83379e
17 changed files with 313 additions and 90 deletions

View File

@@ -1,9 +1,14 @@
package org.bukkit.craftbukkit.legacy;
import java.util.function.BiFunction;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.Particle;
import org.bukkit.Registry;
import org.bukkit.attribute.Attribute;
import org.bukkit.block.Biome;
import org.bukkit.block.banner.PatternType;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.craftbukkit.legacy.fieldrename.FieldRenameData;
import org.bukkit.craftbukkit.legacy.reroute.DoNotReroute;
import org.bukkit.craftbukkit.legacy.reroute.InjectPluginVersion;
@@ -36,13 +41,23 @@ public class FieldRename {
case "org/bukkit/MusicInstrument" -> convertMusicInstrumentName(apiVersion, from);
case "org/bukkit/Particle" -> convertParticleName(apiVersion, from);
case "org/bukkit/loot/LootTables" -> convertLootTablesName(apiVersion, from);
case "org/bukkit/attribute/Attribute" -> convertAttributeName(apiVersion, from);
case "org/bukkit/attribute/Attribute" -> convertAttributeName(apiVersion, from).replace('.', '_');
case "org/bukkit/map/MapCursor$Type" -> convertMapCursorTypeName(apiVersion, from);
case "org/bukkit/inventory/ItemFlag" -> convertItemFlagName(apiVersion, from);
default -> from;
};
}
@RerouteStatic("java/lang/Enum")
public static <T extends Enum<T>> T valueOf(Class<T> enumClass, String name, @InjectPluginVersion ApiVersion apiVersion) {
return Enum.valueOf(enumClass, rename(apiVersion, enumClass.getName().replace('.', '/'), name));
}
public static <T extends Keyed> T get(Registry<T> registry, NamespacedKey namespacedKey) {
// We don't have version-specific changes, so just use current, and don't inject a version
return CraftRegistry.get(registry, namespacedKey, ApiVersion.CURRENT);
}
// PatternType
private static final FieldRenameData PATTERN_TYPE_DATA = FieldRenameData.Builder.newBuilder()
.forVersionsBefore(ApiVersion.FIELD_NAME_PARITY)
@@ -82,17 +97,20 @@ public class FieldRename {
.change("DAMAGE_UNDEAD", "SMITE")
.change("DAMAGE_ARTHROPODS", "BANE_OF_ARTHROPODS")
.change("LOOT_BONUS_MOBS", "LOOTING")
.change("SWEEPING_EDGE", "SWEEPING")
.change("DIG_SPEED", "EFFICIENCY")
.change("DURABILITY", "UNBREAKING")
.change("LOOT_BONUS_BLOCKS", "FORTUNE")
.change("ARROW_DAMAGE", "POWER")
.change("ARROW_KNOCKBACK", "PUNCH")
.change("ARROW_FIRE", "FLAME")
.change("ARROW_INFINITY", "INFINITY")
.change("ARROW_INFINITE", "INFINITY")
.change("LUCK", "LUCK_OF_THE_SEA")
.withKeyRename()
.change("SWEEPING", "SWEEPING_EDGE")
.build();
public static final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> ENCHANTMENT_RENAME = ENCHANTMENT_DATA::getReplacement;
@DoNotReroute
public static String convertEnchantmentName(ApiVersion version, String from) {
return ENCHANTMENT_DATA.getReplacement(version, from);
@@ -108,6 +126,7 @@ public class FieldRename {
// Biome
private static final FieldRenameData BIOME_DATA = FieldRenameData.Builder.newBuilder()
.forAllVersions()
.withKeyRename()
.change("NETHER", "NETHER_WASTES")
.change("TALL_BIRCH_FOREST", "OLD_GROWTH_BIRCH_FOREST")
.change("GIANT_TREE_TAIGA", "OLD_GROWTH_PINE_TAIGA")
@@ -122,6 +141,8 @@ public class FieldRename {
.change("WOODED_BADLANDS_PLATEAU", "WOODED_BADLANDS")
.build();
public static final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> BIOME_RENAME = BIOME_DATA::getReplacement;
@DoNotReroute
public static String convertBiomeName(ApiVersion version, String from) {
return BIOME_DATA.getReplacement(version, from);
@@ -134,23 +155,9 @@ public class FieldRename {
return Biome.valueOf(convertBiomeName(ApiVersion.CURRENT, name));
}
// EntityType
private static final FieldRenameData ENTITY_TYPE_DATA = FieldRenameData.Builder.newBuilder()
.forAllVersions()
.change("XP_ORB", "EXPERIENCE_ORB")
.change("EYE_OF_ENDER_SIGNAL", "EYE_OF_ENDER")
.change("XP_BOTTLE", "EXPERIENCE_BOTTLE")
.change("FIREWORKS_ROCKET", "FIREWORK_ROCKET")
.change("EVOCATION_FANGS", "EVOKER_FANGS")
.change("EVOCATION_ILLAGER", "EVOKER")
.change("VINDICATION_ILLAGER", "VINDICATOR")
.change("ILLUSION_ILLAGER", "ILLUSIONER")
.change("COMMANDBLOCK_MINECART", "COMMAND_BLOCK_MINECART")
.change("SNOWMAN", "SNOW_GOLEM")
.change("VILLAGER_GOLEM", "IRON_GOLEM")
.change("ENDER_CRYSTAL", "END_CRYSTAL")
.change("ZOMBIE_PIGMAN", "ZOMBIFIED_PIGLIN")
.change("PIG_ZOMBIE", "ZOMBIFIED_PIGLIN")
.change("DROPPED_ITEM", "ITEM")
.change("LEASH_HITCH", "LEASH_KNOT")
@@ -167,11 +174,26 @@ public class FieldRename {
.change("MINECART_MOB_SPAWNER", "SPAWNER_MINECART")
.change("MUSHROOM_COW", "MOOSHROOM")
.change("SNOWMAN", "SNOW_GOLEM")
.change("ENDER_CRYSTAL", "END_CRYSTAL")
.change("FISHING_HOOK", "FISHING_BOBBER")
.change("LIGHTNING", "LIGHTNING_BOLT")
.withKeyRename()
.change("XP_ORB", "EXPERIENCE_ORB")
.change("EYE_OF_ENDER_SIGNAL", "EYE_OF_ENDER")
.change("XP_BOTTLE", "EXPERIENCE_BOTTLE")
.change("FIREWORKS_ROCKET", "FIREWORK_ROCKET")
.change("EVOCATION_FANGS", "EVOKER_FANGS")
.change("EVOCATION_ILLAGER", "EVOKER")
.change("VINDICATION_ILLAGER", "VINDICATOR")
.change("ILLUSION_ILLAGER", "ILLUSIONER")
.change("COMMANDBLOCK_MINECART", "COMMAND_BLOCK_MINECART")
.change("SNOWMAN", "SNOW_GOLEM")
.change("VILLAGER_GOLEM", "IRON_GOLEM")
.change("ENDER_CRYSTAL", "END_CRYSTAL")
.change("ZOMBIE_PIGMAN", "ZOMBIFIED_PIGLIN")
.build();
public static final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> ENTITY_TYPE_RENAME = ENTITY_TYPE_DATA::getReplacement;
@DoNotReroute
public static String convertEntityTypeName(ApiVersion version, String from) {
return ENTITY_TYPE_DATA.getReplacement(version, from);
@@ -220,7 +242,6 @@ public class FieldRename {
// PotionType
private static final FieldRenameData POTION_TYPE_DATA = FieldRenameData.Builder.newBuilder()
.forAllVersions()
.change("UNCRAFTABLE", "EMPTY")
.change("JUMP", "LEAPING")
.change("SPEED", "SWIFTNESS")
.change("INSTANT_HEAL", "HEALING")
@@ -292,8 +313,12 @@ public class FieldRename {
.change("WATER_DROP", "RAIN")
.change("MOB_APPEARANCE", "ELDER_GUARDIAN")
.change("TOTEM", "TOTEM_OF_UNDYING")
.withKeyRename()
.change("GUST_EMITTER", "GUST_EMITTER_LARGE")
.build();
public static final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> PARTICLE_TYPE_RENAME = PARTICLE_DATA::getReplacement;
@DoNotReroute
public static String convertParticleName(ApiVersion version, String from) {
return PARTICLE_DATA.getReplacement(version, from);
@@ -327,9 +352,12 @@ public class FieldRename {
// Attribute
private static final FieldRenameData ATTRIBUTE_DATA = FieldRenameData.Builder.newBuilder()
.forAllVersions()
.change("HORSE_JUMP_STRENGTH", "GENERIC_JUMP_STRENGTH")
.withKeyRename()
.change("HORSE.JUMP_STRENGTH", "GENERIC.JUMP_STRENGTH")
.build();
public static final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> ATTRIBUTE_RENAME = ATTRIBUTE_DATA::getReplacement;
@DoNotReroute
public static String convertAttributeName(ApiVersion version, String from) {
return ATTRIBUTE_DATA.getReplacement(version, from);
@@ -339,7 +367,7 @@ public class FieldRename {
@RerouteStatic("org/bukkit/attribute/Attribute")
public static Attribute valueOf_Attribute(String name) {
// We don't have version-specific changes, so just use current, and don't inject a version
return Attribute.valueOf(convertAttributeName(ApiVersion.CURRENT, name));
return Attribute.valueOf(convertAttributeName(ApiVersion.CURRENT, name).replace('.', '_'));
}
// MapCursor Type

View File

@@ -5,9 +5,10 @@ import java.util.Locale;
import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;
import org.bukkit.NamespacedKey;
import org.bukkit.craftbukkit.util.ApiVersion;
public record FieldRenameData(NavigableMap<ApiVersion, Map<String, String>> versionData, Map<String, String> data) {
public record FieldRenameData(RenameData<String> renameData, RenameData<NamespacedKey> keyRenameData) {
public String getReplacement(ApiVersion apiVersion, String from) {
if (from == null) {
@@ -15,24 +16,25 @@ public record FieldRenameData(NavigableMap<ApiVersion, Map<String, String>> vers
}
from = from.toUpperCase(Locale.ROOT);
from = data.getOrDefault(from, from);
return renameData.getReplacement(apiVersion, from);
}
for (Map.Entry<ApiVersion, Map<String, String>> entry : versionData.entrySet()) {
if (apiVersion.isNewerThanOrSameAs(entry.getKey())) {
continue;
}
from = entry.getValue().getOrDefault(from, from);
public NamespacedKey getReplacement(NamespacedKey from, ApiVersion apiVersion) {
if (from == null) {
return null;
}
return from;
return keyRenameData.getReplacement(apiVersion, from);
}
public static class Builder {
private final Map<String, String> data = new HashMap<>();
private final NavigableMap<ApiVersion, Map<String, String>> versionData = new TreeMap<>();
private final Map<NamespacedKey, NamespacedKey> keyData = new HashMap<>();
private final NavigableMap<ApiVersion, Map<NamespacedKey, NamespacedKey>> versionKeyData = new TreeMap<>();
private ApiVersion currentVersion;
private boolean keyRename = false;
public static Builder newBuilder() {
return new Builder();
@@ -40,25 +42,58 @@ public record FieldRenameData(NavigableMap<ApiVersion, Map<String, String>> vers
public Builder forVersionsBefore(ApiVersion apiVersion) {
this.currentVersion = apiVersion;
this.keyRename = false;
return this;
}
public Builder forAllVersions() {
this.currentVersion = null;
this.keyRename = false;
return this;
}
public Builder withKeyRename() {
this.keyRename = true;
return this;
}
public Builder change(String from, String to) {
if (currentVersion != null) {
versionData.computeIfAbsent(currentVersion, d -> new HashMap<>()).put(from, to);
versionData.computeIfAbsent(currentVersion, d -> new HashMap<>()).put(from.replace('.', '_'), to);
} else {
data.put(from, to);
data.put(from.replace('.', '_'), to);
}
if (keyRename) {
NamespacedKey fromKey = NamespacedKey.minecraft(from.toLowerCase(Locale.ROOT));
NamespacedKey toKey = NamespacedKey.minecraft(to.toLowerCase(Locale.ROOT));
if (currentVersion != null) {
versionKeyData.computeIfAbsent(currentVersion, d -> new HashMap<>()).put(fromKey, toKey);
} else {
keyData.put(fromKey, toKey);
}
}
return this;
}
public FieldRenameData build() {
return new FieldRenameData(versionData, data);
return new FieldRenameData(new RenameData<>(versionData, data), new RenameData<>(versionKeyData, keyData));
}
}
private record RenameData<T>(NavigableMap<ApiVersion, Map<T, T>> versionData, Map<T, T> data) {
public T getReplacement(ApiVersion apiVersion, T from) {
from = data.getOrDefault(from, from);
for (Map.Entry<ApiVersion, Map<T, T>> entry : versionData.entrySet()) {
if (apiVersion.isNewerThanOrSameAs(entry.getKey())) {
continue;
}
from = entry.getValue().getOrDefault(from, from);
}
return from;
}
}
}