mirror of
https://github.com/PaperMC/Paper.git
synced 2026-11-04 17:00:09 -05:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd5c62850a |
No files matched your search
@@ -154,6 +154,9 @@ dependencies {
|
||||
testImplementation("org.ow2.asm:asm-tree:9.9.1")
|
||||
testImplementation("org.junit-pioneer:junit-pioneer:2.3.0") // CartesianTest
|
||||
|
||||
// Bytecode framework
|
||||
implementation("io.papermc:asm-utils:0.0.4-SNAPSHOT")
|
||||
|
||||
// Spark
|
||||
implementation("me.lucko:spark-api:0.1-20240720.200737-2")
|
||||
implementation("me.lucko:spark-paper:1.10.172")
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
package io.papermc.paper.plugin;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
import org.bukkit.craftbukkit.util.Versioning;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.spongepowered.configurate.serialize.ScalarSerializer;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
|
||||
@NullMarked
|
||||
public sealed interface ApiVersion extends io.papermc.asm.versioned.ApiVersion<ApiVersion> permits ApiVersion.Legacy, ApiVersion.Modern, ApiVersion.None {
|
||||
|
||||
Serializer SERIALIZER = new Serializer();
|
||||
|
||||
ApiVersion CURRENT = getOrCreateVersion(Versioning.getCurrentApiVersion());
|
||||
ApiVersion FLATTENING = getOrCreateVersion("1.13");
|
||||
ApiVersion FIELD_NAME_PARITY = getOrCreateVersion("1.20.5");
|
||||
ApiVersion ABSTRACT_COW = getOrCreateVersion("1.21.5");
|
||||
ApiVersion ABSTRACT_CUBE_MOB = getOrCreateVersion("26.2");
|
||||
ApiVersion NONE = getOrCreateVersion("none");
|
||||
|
||||
String getVersionString();
|
||||
|
||||
@Override
|
||||
default int compareTo(final ApiVersion o) {
|
||||
return switch (o) {
|
||||
case final Legacy oLegacy -> switch (this) {
|
||||
case final Legacy thisLegacy -> thisLegacy.compareSameType(oLegacy);
|
||||
case final Modern ignored -> 1;
|
||||
case final None ignored -> -1;
|
||||
};
|
||||
case final Modern oModern -> switch (this) {
|
||||
case final Legacy ignored -> -1;
|
||||
case final Modern thisModern -> thisModern.compareSameType(oModern);
|
||||
case final None ignored -> -1;
|
||||
};
|
||||
case final None ignored -> switch (this) {
|
||||
case final Legacy ignored2 -> 1;
|
||||
case final Modern ignored2 -> 1;
|
||||
case final None ignored2 -> 0;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
record Legacy(int major, int minor, int patch) implements ApiVersion {
|
||||
|
||||
private static final Comparator<Legacy> COMPARATOR = Comparator
|
||||
.comparingInt(Legacy::major)
|
||||
.thenComparingInt(Legacy::minor)
|
||||
.thenComparingInt(Legacy::patch);
|
||||
|
||||
int compareSameType(final Legacy other) {
|
||||
return COMPARATOR.compare(this, other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionString() {
|
||||
return this.major() + "." + this.minor() + "." + this.patch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getVersionString();
|
||||
}
|
||||
}
|
||||
|
||||
record Modern(int year, int drop, int hotfix) implements ApiVersion {
|
||||
|
||||
private static final Comparator<Modern> COMPARATOR = Comparator
|
||||
.comparingInt(Modern::year)
|
||||
.thenComparingInt(Modern::drop)
|
||||
.thenComparingInt(Modern::hotfix);
|
||||
|
||||
int compareSameType(final Modern other) {
|
||||
return COMPARATOR.compare(this, other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionString() {
|
||||
return this.year() + "." + this.drop() + "." + this.hotfix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getVersionString();
|
||||
}
|
||||
}
|
||||
|
||||
record None() implements ApiVersion {
|
||||
|
||||
private static final None INSTANCE = new None();
|
||||
|
||||
@Override
|
||||
public String getVersionString() {
|
||||
return "none";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getVersionString();
|
||||
}
|
||||
}
|
||||
|
||||
final class Serializer extends ScalarSerializer.Annotated<ApiVersion> {
|
||||
|
||||
Serializer() {
|
||||
super(ApiVersion.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiVersion deserialize(final AnnotatedType type, final Object obj) throws SerializationException {
|
||||
try {
|
||||
final ApiVersion version = getOrCreateVersion(obj.toString());
|
||||
final Minimum min = type.getAnnotation(Minimum.class);
|
||||
if (min != null) {
|
||||
final ApiVersion minVersion = getOrCreateVersion(min.value());
|
||||
if (version.isOlderThan(minVersion)) {
|
||||
throw new SerializationException(ApiVersion.class, version + " is too old for a paper plugin!");
|
||||
}
|
||||
}
|
||||
return version;
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
throw new SerializationException(ApiVersion.class, "Could not parse version string", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object serialize(final AnnotatedType type, final ApiVersion item, final Predicate<Class<?>> typeSupported) {
|
||||
return item.getVersionString();
|
||||
}
|
||||
}
|
||||
|
||||
static ApiVersion getOrCreateVersion(final @Nullable String versionString) {
|
||||
class Holder {
|
||||
private static final Map<String, ApiVersion> cache = new ConcurrentHashMap<>();
|
||||
}
|
||||
if (versionString == null || versionString.isBlank() || versionString.equalsIgnoreCase("none")) {
|
||||
return None.INSTANCE;
|
||||
}
|
||||
final ApiVersion parsed = parse(versionString);
|
||||
Holder.cache.putIfAbsent(parsed.getVersionString(), parsed);
|
||||
return Holder.cache.get(parsed.getVersionString());
|
||||
}
|
||||
|
||||
private static ApiVersion parse(final String versionString) {
|
||||
final String[] parts = versionString.split("\\.");
|
||||
|
||||
if (parts.length < 2 || parts.length > 3) {
|
||||
throw new IllegalArgumentException("Version string must have 2 or 3 numbers");
|
||||
}
|
||||
|
||||
final int first = Integer.parseInt(parts[0]);
|
||||
final int second = Integer.parseInt(parts[1]);
|
||||
final int third = parts.length == 3 ? Integer.parseInt(parts[2]) : 0;
|
||||
|
||||
if (first == 1) {
|
||||
if (second > 21) {
|
||||
throw new IllegalArgumentException("Legacy version string must be 1.21.xx or lower");
|
||||
}
|
||||
return new Legacy(first, second, third);
|
||||
} else {
|
||||
if (first < 26) {
|
||||
throw new IllegalArgumentException("Modern version string must be 26.x.x or higher");
|
||||
}
|
||||
return new Modern(first, second, third);
|
||||
}
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
@interface Minimum {
|
||||
String value();
|
||||
}
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
package io.papermc.paper.plugin.entrypoint.classloader;
|
||||
|
||||
import io.papermc.paper.plugin.configuration.PluginMeta;
|
||||
|
||||
// Stub, implement in future.
|
||||
public class PaperClassloaderBytecodeModifier implements ClassloaderBytecodeModifier {
|
||||
|
||||
@Override
|
||||
public byte[] modify(PluginMeta configuration, byte[] bytecode) {
|
||||
return bytecode;
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package io.papermc.paper.plugin.entrypoint.classloader.bytecode;
|
||||
|
||||
import com.google.common.collect.Iterators;
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import io.papermc.paper.plugin.configuration.PluginMeta;
|
||||
import io.papermc.paper.plugin.entrypoint.classloader.ClassloaderBytecodeModifier;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import net.minecraft.util.Util;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
public class PaperClassloaderBytecodeModifier implements ClassloaderBytecodeModifier {
|
||||
|
||||
private static final Map<ApiVersion, List<ModifierFactory>> MODIFIERS = Util.make(new LinkedHashMap<>(), map -> {
|
||||
});
|
||||
|
||||
private final Map<ApiVersion, List<VersionedClassloaderBytecodeModifier>> constructedModifiers = MODIFIERS.entrySet().stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, entry -> {
|
||||
return entry.getValue().stream().map(factory -> factory.create(Opcodes.ASM9)).toList();
|
||||
}));
|
||||
|
||||
@Override
|
||||
public byte[] modify(final PluginMeta configuration, byte[] bytecode) {
|
||||
int start = -1;
|
||||
if (configuration.getAPIVersion() != null) {
|
||||
int i = 0;
|
||||
for (final Map.Entry<ApiVersion, List<VersionedClassloaderBytecodeModifier>> entry : this.constructedModifiers.entrySet()) {
|
||||
final ApiVersion apiVersion = ApiVersion.getOrCreateVersion(configuration.getAPIVersion());
|
||||
final ApiVersion modifierApiVersion = entry.getKey();
|
||||
if (apiVersion.isOlderThanOrSameAs(modifierApiVersion)) {
|
||||
start = i;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
start = 0;
|
||||
}
|
||||
if (start == -1) {
|
||||
return bytecode; // no modification needed. The plugin version is newer than all versioned modifiers
|
||||
}
|
||||
|
||||
final Iterator<Map.Entry<ApiVersion, List<VersionedClassloaderBytecodeModifier>>> it = this.constructedModifiers.entrySet().iterator();
|
||||
Iterators.advance(it, start);
|
||||
while (it.hasNext()) {
|
||||
for (final VersionedClassloaderBytecodeModifier modifier : it.next().getValue()) {
|
||||
bytecode = modifier.modify(configuration, bytecode);
|
||||
}
|
||||
}
|
||||
return bytecode;
|
||||
}
|
||||
|
||||
private interface ModifierFactory {
|
||||
|
||||
VersionedClassloaderBytecodeModifier create(int api);
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package io.papermc.paper.plugin.entrypoint.classloader.bytecode;
|
||||
|
||||
import io.papermc.asm.AbstractRewriteRuleVisitorFactory;
|
||||
import io.papermc.asm.ClassInfoProvider;
|
||||
import io.papermc.asm.rules.builder.RuleFactoryConfiguration;
|
||||
import io.papermc.paper.plugin.configuration.PluginMeta;
|
||||
import io.papermc.paper.plugin.entrypoint.classloader.ClassloaderBytecodeModifier;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
|
||||
import static io.papermc.asm.util.DescriptorUtils.desc;
|
||||
|
||||
public abstract class VersionedClassloaderBytecodeModifier extends AbstractRewriteRuleVisitorFactory implements ClassloaderBytecodeModifier, RuleFactoryConfiguration.Holder {
|
||||
|
||||
protected VersionedClassloaderBytecodeModifier(final int api) {
|
||||
super(api, ClassInfoProvider.basic());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final byte[] modify(final PluginMeta config, final byte[] bytecode) {
|
||||
final ClassReader cr = new ClassReader(bytecode);
|
||||
final ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS); // need to compute maxs because of instruction removal in ctor rewriting
|
||||
|
||||
cr.accept(this.createVisitor(cw), 0);
|
||||
return cw.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RuleFactoryConfiguration configuration() {
|
||||
return RuleFactoryConfiguration.create(desc(this.getClass()));
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
@NullMarked
|
||||
package io.papermc.paper.plugin.entrypoint.classloader.bytecode;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
+3
-26
@@ -5,15 +5,13 @@ import com.google.common.collect.ImmutableList;
|
||||
import io.papermc.paper.configuration.constraint.Constraint;
|
||||
import io.papermc.paper.configuration.serializer.ComponentSerializer;
|
||||
import io.papermc.paper.configuration.serializer.EnumValueSerializer;
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import io.papermc.paper.plugin.configuration.PluginMeta;
|
||||
import io.papermc.paper.plugin.provider.configuration.serializer.PermissionConfigurationSerializer;
|
||||
import io.papermc.paper.plugin.provider.configuration.serializer.constraints.PluginConfigConstraints;
|
||||
import io.papermc.paper.plugin.provider.configuration.type.DependencyConfiguration;
|
||||
import io.papermc.paper.plugin.provider.configuration.type.PermissionConfiguration;
|
||||
import io.papermc.paper.plugin.provider.configuration.type.PluginDependencyLifeCycle;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.function.Predicate;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.plugin.PluginLoadOrder;
|
||||
@@ -26,8 +24,6 @@ import org.spongepowered.configurate.loader.HeaderMode;
|
||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||
import org.spongepowered.configurate.objectmapping.ObjectMapper;
|
||||
import org.spongepowered.configurate.objectmapping.meta.Required;
|
||||
import org.spongepowered.configurate.serialize.ScalarSerializer;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
import org.spongepowered.configurate.yaml.NodeStyle;
|
||||
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
|
||||
|
||||
@@ -63,6 +59,7 @@ public class PaperPluginMeta implements PluginMeta {
|
||||
@FlattenedResolver
|
||||
private PermissionConfiguration permissionConfiguration = new PermissionConfiguration(PermissionDefault.OP, List.of());
|
||||
@Required
|
||||
@ApiVersion.Minimum("1.19")
|
||||
private ApiVersion apiVersion;
|
||||
|
||||
private Map<PluginDependencyLifeCycle, Map<String, DependencyConfiguration>> dependencies = new EnumMap<>(PluginDependencyLifeCycle.class);
|
||||
@@ -70,7 +67,6 @@ public class PaperPluginMeta implements PluginMeta {
|
||||
public PaperPluginMeta() {
|
||||
}
|
||||
|
||||
static final ApiVersion MINIMUM = ApiVersion.getOrCreateVersion("1.19");
|
||||
public static PaperPluginMeta create(BufferedReader reader) throws ConfigurateException {
|
||||
YamlConfigurationLoader loader = YamlConfigurationLoader.builder()
|
||||
.indent(2)
|
||||
@@ -78,28 +74,9 @@ public class PaperPluginMeta implements PluginMeta {
|
||||
.headerMode(HeaderMode.NONE)
|
||||
.source(() -> reader)
|
||||
.defaultOptions((options) -> {
|
||||
|
||||
return options.serializers((serializers) -> {
|
||||
serializers
|
||||
.register(new ScalarSerializer<>(ApiVersion.class) {
|
||||
@Override
|
||||
public ApiVersion deserialize(final Type type, final Object obj) throws SerializationException {
|
||||
try {
|
||||
final ApiVersion version = ApiVersion.getOrCreateVersion(obj.toString());
|
||||
if (version.isOlderThan(MINIMUM)) {
|
||||
throw new SerializationException(version + " is too old for a paper plugin!");
|
||||
}
|
||||
return version;
|
||||
} catch (final IllegalArgumentException e) {
|
||||
throw new SerializationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object serialize(final ApiVersion item, final Predicate<Class<?>> typeSupported) {
|
||||
return item.getVersionString();
|
||||
}
|
||||
})
|
||||
.register(ApiVersion.SERIALIZER)
|
||||
.register(new EnumValueSerializer())
|
||||
.register(PermissionConfiguration.class, PermissionConfigurationSerializer.SERIALIZER)
|
||||
.register(new ComponentSerializer())
|
||||
|
||||
+1
-1
@@ -1,5 +1,6 @@
|
||||
package io.papermc.paper.registry.entry;
|
||||
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import io.papermc.paper.registry.PaperRegistryBuilder;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import java.util.function.BiFunction;
|
||||
@@ -10,7 +11,6 @@ import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
|
||||
import static io.papermc.paper.registry.entry.RegistryEntryMeta.RegistryModificationApiSupport.ADDABLE;
|
||||
import static io.papermc.paper.registry.entry.RegistryEntryMeta.RegistryModificationApiSupport.MODIFIABLE;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.papermc.paper.registry.entry;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import io.papermc.paper.registry.PaperRegistryBuilder;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.TypedKey;
|
||||
@@ -16,7 +17,6 @@ import net.minecraft.resources.ResourceKey;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
|
||||
public sealed interface RegistryEntryMeta<M, A extends Keyed> permits RegistryEntryMeta.ApiOnly, RegistryEntryMeta.ServerSide { // TODO remove Keyed
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import io.papermc.paper.registry.PaperRegistries;
|
||||
import io.papermc.paper.registry.RegistryAccess;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
@@ -8,7 +9,6 @@ import io.papermc.paper.registry.entry.RegistryEntryMeta;
|
||||
import io.papermc.paper.registry.set.NamedRegistryKeySetImpl;
|
||||
import io.papermc.paper.registry.tag.Tag;
|
||||
import io.papermc.paper.util.Holderable;
|
||||
import io.papermc.paper.util.MCUtil;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@@ -24,7 +24,6 @@ import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.craftbukkit.legacy.FieldRename;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
import org.bukkit.craftbukkit.util.Handleable;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.mojang.serialization.JsonOps;
|
||||
import io.papermc.paper.configuration.GlobalConfiguration;
|
||||
import io.papermc.paper.configuration.PaperServerConfiguration;
|
||||
import io.papermc.paper.configuration.ServerConfiguration;
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import io.papermc.paper.util.MCUtil;
|
||||
import io.papermc.paper.world.PaperWorldLoader;
|
||||
import io.papermc.paper.world.migration.WorldFolderMigration;
|
||||
@@ -153,7 +154,6 @@ import org.bukkit.craftbukkit.ban.CraftIpBanList;
|
||||
import org.bukkit.craftbukkit.ban.CraftProfileBanList;
|
||||
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||
import org.bukkit.craftbukkit.boss.CraftBossBar;
|
||||
import org.bukkit.craftbukkit.boss.CraftKeyedBossbar;
|
||||
import org.bukkit.craftbukkit.command.CraftCommandMap;
|
||||
import org.bukkit.craftbukkit.command.VanillaCommandWrapper;
|
||||
import org.bukkit.craftbukkit.entity.CraftEntityFactory;
|
||||
@@ -197,7 +197,6 @@ import org.bukkit.craftbukkit.tag.CraftEntityTag;
|
||||
import org.bukkit.craftbukkit.tag.CraftFluidTag;
|
||||
import org.bukkit.craftbukkit.tag.CraftGameEventTag;
|
||||
import org.bukkit.craftbukkit.tag.CraftItemTag;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.bukkit.craftbukkit.util.CraftChatMessage;
|
||||
import org.bukkit.craftbukkit.util.CraftIconCache;
|
||||
import org.bukkit.craftbukkit.util.CraftLocation;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.bukkit.craftbukkit.attribute;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.util.OldEnumHolderable;
|
||||
import java.util.Locale;
|
||||
@@ -10,7 +11,6 @@ import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.bukkit.craftbukkit.legacy.FieldRename;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
|
||||
public class CraftAttribute extends OldEnumHolderable<Attribute, net.minecraft.world.entity.ai.attributes.Attribute> implements Attribute {
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,7 @@
|
||||
package org.bukkit.craftbukkit.enchantments;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.util.Holderable;
|
||||
import java.util.Locale;
|
||||
@@ -12,7 +13,6 @@ import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.legacy.FieldRename;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.enchantments.EnchantmentWrapper;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import java.util.Locale;
|
||||
import net.minecraft.core.Holder;
|
||||
@@ -9,7 +10,6 @@ import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.bukkit.craftbukkit.legacy.FieldRename;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.bukkit.craftbukkit.inventory;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import org.bukkit.craftbukkit.legacy.FieldRename;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
|
||||
public class CraftItemFlag {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.craftbukkit.legacy;
|
||||
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import java.util.function.BiFunction;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Particle;
|
||||
@@ -12,7 +13,6 @@ import org.bukkit.craftbukkit.legacy.reroute.DoNotReroute;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.InjectPluginVersion;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.RerouteMethodName;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.RerouteStatic;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.craftbukkit.legacy;
|
||||
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
@@ -29,7 +30,6 @@ import org.bukkit.craftbukkit.legacy.reroute.InjectPluginVersion;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.RerouteStatic;
|
||||
import org.bukkit.craftbukkit.tag.CraftBlockTag;
|
||||
import org.bukkit.craftbukkit.tag.CraftItemTag;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.entity.Animals;
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package org.bukkit.craftbukkit.legacy.enums;
|
||||
|
||||
/**
|
||||
* A crash dummy to use, instead of the old enums which matured to Abstracthood or Interfacehood and the baby enums which are still growing.
|
||||
*/
|
||||
public enum DummyEnum {
|
||||
}
|
||||
@@ -1,288 +0,0 @@
|
||||
package org.bukkit.craftbukkit.legacy.enums;
|
||||
|
||||
import com.google.common.base.Converter;
|
||||
import com.google.common.base.Enums;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
import org.bukkit.Art;
|
||||
import org.bukkit.Fluid;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.banner.PatternType;
|
||||
import org.bukkit.craftbukkit.legacy.FieldRename;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.DoNotReroute;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.InjectPluginVersion;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.NotInBukkit;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.RequireCompatibility;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.RequirePluginVersion;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.RerouteArgumentType;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.RerouteReturnType;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.RerouteStatic;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.bukkit.craftbukkit.util.ClassTraverser;
|
||||
import org.bukkit.entity.Cat;
|
||||
import org.bukkit.entity.Frog;
|
||||
import org.bukkit.entity.Villager;
|
||||
import org.bukkit.map.MapCursor;
|
||||
import org.bukkit.util.OldEnum;
|
||||
|
||||
@Deprecated
|
||||
@NotInBukkit
|
||||
@RequireCompatibility("enum-compatibility-mode")
|
||||
@RequirePluginVersion(maxInclusive = "1.20.6")
|
||||
public class EnumEvil {
|
||||
|
||||
private static final Map<Class<?>, LegacyRegistryData> REGISTRIES = new HashMap<>();
|
||||
|
||||
static {
|
||||
// Add Classes which got changed here
|
||||
REGISTRIES.put(Art.class, new LegacyRegistryData(Registry.ART, Art::valueOf));
|
||||
REGISTRIES.put(Attribute.class, new LegacyRegistryData(Registry.ATTRIBUTE, Attribute::valueOf));
|
||||
REGISTRIES.put(Biome.class, new LegacyRegistryData(Registry.BIOME, Biome::valueOf));
|
||||
REGISTRIES.put(Fluid.class, new LegacyRegistryData(Registry.FLUID, Fluid::valueOf));
|
||||
REGISTRIES.put(Villager.Type.class, new LegacyRegistryData(Registry.VILLAGER_TYPE, Villager.Type::valueOf));
|
||||
REGISTRIES.put(Villager.Profession.class, new LegacyRegistryData(Registry.VILLAGER_PROFESSION, Villager.Profession::valueOf));
|
||||
REGISTRIES.put(Sound.class, new LegacyRegistryData(Registry.SOUNDS, Sound::valueOf));
|
||||
REGISTRIES.put(Frog.Variant.class, new LegacyRegistryData(Registry.FROG_VARIANT, Frog.Variant::valueOf));
|
||||
REGISTRIES.put(Cat.Type.class, new LegacyRegistryData(Registry.CAT_VARIANT, Cat.Type::valueOf));
|
||||
REGISTRIES.put(MapCursor.Type.class, new LegacyRegistryData(Registry.MAP_DECORATION_TYPE, MapCursor.Type::valueOf));
|
||||
REGISTRIES.put(PatternType.class, new LegacyRegistryData(Registry.BANNER_PATTERN, PatternType::valueOf));
|
||||
}
|
||||
|
||||
public static LegacyRegistryData getRegistryData(Class<?> clazz) {
|
||||
ClassTraverser it = new ClassTraverser(clazz);
|
||||
LegacyRegistryData registryData;
|
||||
while (it.hasNext()) {
|
||||
registryData = EnumEvil.REGISTRIES.get(it.next());
|
||||
if (registryData != null) {
|
||||
return registryData;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@DoNotReroute
|
||||
public static Registry<?> getRegistry(Class<?> clazz) {
|
||||
LegacyRegistryData registryData = EnumEvil.getRegistryData(clazz);
|
||||
|
||||
if (registryData != null) {
|
||||
return registryData.registry();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@RerouteStatic("com/google/common/collect/Maps")
|
||||
@RerouteReturnType("java/util/EnumSet")
|
||||
public static ImposterEnumMap newEnumMap(Class<?> objectClass) {
|
||||
return new ImposterEnumMap(objectClass);
|
||||
}
|
||||
|
||||
@RerouteStatic("com/google/common/collect/Maps")
|
||||
@RerouteReturnType("java/util/EnumSet")
|
||||
public static ImposterEnumMap newEnumMap(Map map) {
|
||||
return new ImposterEnumMap(map);
|
||||
}
|
||||
|
||||
@RerouteStatic("com/google/common/collect/Sets")
|
||||
public static Collector<?, ?, ?> toImmutableEnumSet() {
|
||||
return Collectors.toUnmodifiableSet();
|
||||
}
|
||||
|
||||
@RerouteStatic("com/google/common/collect/Sets")
|
||||
@RerouteReturnType("java/util/EnumSet")
|
||||
public static ImposterEnumSet newEnumSet(Iterable<?> iterable, Class<?> clazz) {
|
||||
ImposterEnumSet set = ImposterEnumSet.noneOf(clazz);
|
||||
|
||||
for (Object some : iterable) {
|
||||
set.add(some);
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
@RerouteStatic("com/google/common/collect/Sets")
|
||||
public static ImmutableSet<?> immutableEnumSet(Iterable<?> iterable) {
|
||||
return ImmutableSet.of(iterable);
|
||||
}
|
||||
|
||||
@RerouteStatic("com/google/common/collect/Sets")
|
||||
public static ImmutableSet<?> immutableEnumSet(@RerouteArgumentType("java/lang/Enum") Object first, @RerouteArgumentType("[java/lang/Enum") Object... rest) {
|
||||
return ImmutableSet.of(first, rest);
|
||||
}
|
||||
|
||||
@RerouteStatic("com/google/common/base/Enums")
|
||||
public static Field getField(@RerouteArgumentType("java/lang/Enum") Object value) {
|
||||
if (value instanceof Enum eValue) {
|
||||
return Enums.getField(eValue);
|
||||
}
|
||||
|
||||
try {
|
||||
return value.getClass().getField(((OldEnum) value).name());
|
||||
} catch (NoSuchFieldException impossible) {
|
||||
throw new AssertionError(impossible);
|
||||
}
|
||||
}
|
||||
|
||||
@RerouteStatic("com/google/common/base/Enums")
|
||||
public static com.google.common.base.Optional getIfPresent(Class clazz, String name, @InjectPluginVersion ApiVersion apiVersion) {
|
||||
if (clazz.isEnum()) {
|
||||
return Enums.getIfPresent(clazz, name);
|
||||
}
|
||||
|
||||
Registry registry = EnumEvil.getRegistry(clazz);
|
||||
if (registry == null) {
|
||||
return com.google.common.base.Optional.absent();
|
||||
}
|
||||
|
||||
name = FieldRename.rename(apiVersion, clazz.getName().replace('.', '/'), name);
|
||||
return com.google.common.base.Optional.fromNullable(registry.get(NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))));
|
||||
}
|
||||
|
||||
@RerouteStatic("com/google/common/base/Enums")
|
||||
public static Converter stringConverter(Class clazz, @InjectPluginVersion ApiVersion apiVersion) {
|
||||
if (clazz.isEnum()) {
|
||||
return Enums.stringConverter(clazz);
|
||||
}
|
||||
|
||||
return new StringConverter(apiVersion, clazz);
|
||||
}
|
||||
|
||||
public static Object[] getEnumConstants(Class<?> clazz) {
|
||||
if (clazz.isEnum()) {
|
||||
return clazz.getEnumConstants();
|
||||
}
|
||||
|
||||
Registry<?> registry = EnumEvil.getRegistry(clazz);
|
||||
|
||||
if (registry == null) {
|
||||
return clazz.getEnumConstants();
|
||||
}
|
||||
|
||||
// Need to do this in such away to avoid ClassCastException
|
||||
List<?> values = Lists.newArrayList(registry);
|
||||
Object array = Array.newInstance(clazz, values.size());
|
||||
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
Array.set(array, i, values.get(i));
|
||||
}
|
||||
|
||||
return (Object[]) array;
|
||||
}
|
||||
|
||||
public static String name(@RerouteArgumentType("java/lang/Enum") Object object) {
|
||||
if (object instanceof OldEnum<?>) {
|
||||
return ((OldEnum<?>) object).name();
|
||||
}
|
||||
|
||||
return ((Enum<?>) object).name();
|
||||
}
|
||||
|
||||
public static int compareTo(@RerouteArgumentType("java/lang/Enum") Object object, @RerouteArgumentType("java/lang/Enum") Object other) {
|
||||
if (object instanceof OldEnum<?>) {
|
||||
return ((OldEnum) object).compareTo((OldEnum) other);
|
||||
}
|
||||
|
||||
return ((Enum) object).compareTo((Enum) other);
|
||||
}
|
||||
|
||||
public static Class<?> getDeclaringClass(@RerouteArgumentType("java/lang/Enum") Object object) {
|
||||
Class<?> clazz = object.getClass();
|
||||
Class<?> zuper = clazz.getSuperclass();
|
||||
return (zuper == Enum.class) ? clazz : zuper;
|
||||
}
|
||||
|
||||
public static Optional<Enum.EnumDesc> describeConstable(@RerouteArgumentType("java/lang/Enum") Object object) {
|
||||
return EnumEvil.getDeclaringClass(object)
|
||||
.describeConstable()
|
||||
.map(c -> Enum.EnumDesc.of(c, EnumEvil.name(object)));
|
||||
}
|
||||
|
||||
@RerouteStatic("java/lang/Enum")
|
||||
@RerouteReturnType("java/lang/Enum")
|
||||
public static Object valueOf(Class enumClass, String name, @InjectPluginVersion ApiVersion apiVersion) {
|
||||
name = FieldRename.rename(apiVersion, enumClass.getName().replace('.', '/'), name);
|
||||
LegacyRegistryData registryData = EnumEvil.getRegistryData(enumClass);
|
||||
if (registryData != null) {
|
||||
return registryData.function().apply(name);
|
||||
}
|
||||
|
||||
return Enum.valueOf(enumClass, name);
|
||||
}
|
||||
|
||||
public static String toString(@RerouteArgumentType("java/lang/Enum") Object object) {
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
public static int ordinal(@RerouteArgumentType("java/lang/Enum") Object object) {
|
||||
if (object instanceof OldEnum<?>) {
|
||||
return ((OldEnum<?>) object).ordinal();
|
||||
}
|
||||
|
||||
return ((Enum<?>) object).ordinal();
|
||||
}
|
||||
|
||||
public record LegacyRegistryData(Registry<?> registry, Function<String, ?> function) {
|
||||
}
|
||||
|
||||
private static final class StringConverter<T extends OldEnum<T>> extends Converter<String, T> implements Serializable {
|
||||
|
||||
private final ApiVersion apiVersion;
|
||||
private final Class<T> clazz;
|
||||
private transient LegacyRegistryData registryData;
|
||||
|
||||
StringConverter(ApiVersion apiVersion, Class<T> clazz) {
|
||||
this.apiVersion = apiVersion;
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected T doForward(String value) {
|
||||
if (this.registryData == null) {
|
||||
this.registryData = EnumEvil.getRegistryData(this.clazz);
|
||||
}
|
||||
value = FieldRename.rename(this.apiVersion, this.clazz.getName().replace('.', '/'), value);
|
||||
return (T) this.registryData.function().apply(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doBackward(T enumValue) {
|
||||
return enumValue.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof StringConverter<?> that) {
|
||||
return this.clazz.equals(that.clazz);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.clazz.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Enums.stringConverter(" + this.clazz.getName() + ".class)";
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0L;
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
package org.bukkit.craftbukkit.legacy.enums;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* The "I can't believe it works" map.
|
||||
* It replaces every EnumMap with the ImposterEnumMap and uses a HashMap instead of an object array.
|
||||
* Used so that plugins which use an EnumMap still work.
|
||||
*/
|
||||
public class ImposterEnumMap extends AbstractMap<Object, Object> {
|
||||
|
||||
private final Class<?> objectClass;
|
||||
private final Map map;
|
||||
|
||||
public ImposterEnumMap(Class<?> objectClass) {
|
||||
this.objectClass = objectClass;
|
||||
this.map = ImposterEnumMap.getMap(objectClass);
|
||||
}
|
||||
|
||||
public ImposterEnumMap(EnumMap enumMap) {
|
||||
this.objectClass = DummyEnum.class;
|
||||
this.map = enumMap.clone();
|
||||
}
|
||||
|
||||
public ImposterEnumMap(Map map) {
|
||||
if (map instanceof ImposterEnumMap) {
|
||||
this.objectClass = ((ImposterEnumMap) map).objectClass;
|
||||
this.map = ImposterEnumMap.getMap(this.objectClass);
|
||||
} else {
|
||||
this.objectClass = DummyEnum.class;
|
||||
this.map = new TreeMap();
|
||||
}
|
||||
|
||||
this.map.putAll(map);
|
||||
}
|
||||
|
||||
private static Map getMap(Class<?> objectClass) {
|
||||
// Since we replace every enum map we might also replace some maps which are for real enums.
|
||||
// If this is the case use a EnumMap instead of a HashMap
|
||||
if (objectClass.isEnum()) {
|
||||
return new EnumMap(objectClass);
|
||||
} else {
|
||||
return new HashMap();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.map.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
return this.map.containsValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return this.map.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Object key) {
|
||||
return this.map.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object put(Object key, Object value) {
|
||||
this.typeCheck(key);
|
||||
return this.map.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object remove(Object key) {
|
||||
return this.map.remove(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends Object, ?> m) {
|
||||
if (this.map instanceof EnumMap<?, ?>) {
|
||||
this.map.putAll(m);
|
||||
}
|
||||
|
||||
super.putAll(m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.map.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Object> keySet() {
|
||||
return this.map.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Object> values() {
|
||||
return this.map.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Entry<Object, Object>> entrySet() {
|
||||
return this.map.entrySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return this.map.equals(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.map.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImposterEnumMap clone() {
|
||||
ImposterEnumMap enumMap = new ImposterEnumMap(this.objectClass);
|
||||
enumMap.putAll(this.map);
|
||||
return enumMap;
|
||||
}
|
||||
|
||||
private void typeCheck(Object object) {
|
||||
if (this.objectClass != DummyEnum.class) {
|
||||
if (!this.objectClass.isAssignableFrom(object.getClass())) {
|
||||
throw new ClassCastException(object.getClass() + " != " + this.objectClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,346 +0,0 @@
|
||||
package org.bukkit.craftbukkit.legacy.enums;
|
||||
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.util.OldEnum;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ImposterEnumSet extends AbstractSet<Object> {
|
||||
|
||||
private final Class<?> objectClass;
|
||||
private final Set set;
|
||||
|
||||
private static Set createSet(Class<?> clazz) {
|
||||
if (clazz.isEnum()) {
|
||||
return EnumSet.noneOf((Class<Enum>) clazz);
|
||||
} else {
|
||||
return new TreeSet();
|
||||
}
|
||||
}
|
||||
|
||||
public static ImposterEnumSet noneOf(Class<?> clazz) {
|
||||
Set set = ImposterEnumSet.createSet(clazz);
|
||||
return new ImposterEnumSet(set, clazz);
|
||||
}
|
||||
|
||||
public static ImposterEnumSet allOf(Class<?> clazz) {
|
||||
Set set;
|
||||
if (clazz.isEnum()) {
|
||||
set = EnumSet.allOf((Class<Enum>) clazz);
|
||||
} else {
|
||||
set = new HashSet();
|
||||
Registry registry = EnumEvil.getRegistry(clazz);
|
||||
if (registry == null) {
|
||||
throw new IllegalArgumentException("Class " + clazz + " is not an Enum nor an OldEnum");
|
||||
}
|
||||
|
||||
for (Object object : registry) {
|
||||
set.add(object);
|
||||
}
|
||||
}
|
||||
return new ImposterEnumSet(set, clazz);
|
||||
}
|
||||
|
||||
public static ImposterEnumSet copyOf(Set set) {
|
||||
Class<?> clazz;
|
||||
if (set instanceof ImposterEnumSet imposter) {
|
||||
set = imposter.set;
|
||||
clazz = imposter.objectClass;
|
||||
} else {
|
||||
if (!set.isEmpty()) {
|
||||
clazz = (Class<?>) set.stream()
|
||||
.filter(val -> val != null)
|
||||
.map(val -> val.getClass())
|
||||
.findAny()
|
||||
.orElse(Object.class);
|
||||
} else {
|
||||
clazz = Object.class;
|
||||
}
|
||||
}
|
||||
|
||||
Set newSet = ImposterEnumSet.createSet(clazz);
|
||||
newSet.addAll(set);
|
||||
|
||||
return new ImposterEnumSet(newSet, clazz);
|
||||
}
|
||||
|
||||
public static ImposterEnumSet copyOf(Collection collection) {
|
||||
Class<?> clazz;
|
||||
if (collection instanceof ImposterEnumSet imposter) {
|
||||
collection = imposter.set;
|
||||
clazz = imposter.objectClass;
|
||||
} else {
|
||||
if (!collection.isEmpty()) {
|
||||
clazz = (Class<?>) collection.stream()
|
||||
.filter(val -> val != null)
|
||||
.map(val -> val.getClass())
|
||||
.findAny()
|
||||
.orElse(Object.class);
|
||||
} else {
|
||||
clazz = Object.class;
|
||||
}
|
||||
}
|
||||
|
||||
Set newSet = ImposterEnumSet.createSet(clazz);
|
||||
newSet.addAll(collection);
|
||||
|
||||
return new ImposterEnumSet(newSet, clazz);
|
||||
}
|
||||
|
||||
public static ImposterEnumSet complementOf(Set set) {
|
||||
Class<?> clazz = null;
|
||||
if (set instanceof ImposterEnumSet imposter) {
|
||||
set = imposter.set;
|
||||
clazz = imposter.objectClass;
|
||||
}
|
||||
|
||||
if (set instanceof EnumSet<?> enumSet) {
|
||||
enumSet = EnumSet.complementOf(enumSet);
|
||||
|
||||
if (clazz != null) {
|
||||
return new ImposterEnumSet(enumSet, clazz);
|
||||
}
|
||||
|
||||
if (!set.isEmpty()) {
|
||||
clazz = (Class<?>) set.stream()
|
||||
.filter(val -> val != null)
|
||||
.map(val -> val.getClass())
|
||||
.findAny()
|
||||
.orElse(Object.class);
|
||||
} else {
|
||||
clazz = (Class<?>) enumSet.stream()
|
||||
.filter(val -> val != null)
|
||||
.map(val -> val.getClass())
|
||||
.map(val -> (Class) val)
|
||||
.findAny()
|
||||
.orElse(Object.class);
|
||||
}
|
||||
|
||||
return new ImposterEnumSet(enumSet, clazz);
|
||||
}
|
||||
|
||||
if (set.isEmpty() && clazz == null) {
|
||||
throw new IllegalStateException("Class is null and set is empty, cannot get class!");
|
||||
}
|
||||
|
||||
if (clazz == null) {
|
||||
clazz = (Class<?>) set.stream()
|
||||
.filter(val -> val != null)
|
||||
.map(val -> val.getClass())
|
||||
.findAny()
|
||||
.orElse(Object.class);
|
||||
}
|
||||
|
||||
Registry registry = EnumEvil.getRegistry(clazz);
|
||||
Set newSet = new HashSet();
|
||||
|
||||
for (Object value : registry) {
|
||||
if (set.contains(value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
newSet.add(value);
|
||||
}
|
||||
|
||||
return new ImposterEnumSet(newSet, clazz);
|
||||
}
|
||||
|
||||
public static ImposterEnumSet of(Object e) {
|
||||
Set set = ImposterEnumSet.createSet(e.getClass());
|
||||
set.add(e);
|
||||
|
||||
return new ImposterEnumSet(set, e.getClass());
|
||||
}
|
||||
|
||||
public static ImposterEnumSet of(Object e1, Object e2) {
|
||||
Set set = ImposterEnumSet.createSet(e1.getClass());
|
||||
set.add(e1);
|
||||
set.add(e2);
|
||||
|
||||
return new ImposterEnumSet(set, e1.getClass());
|
||||
}
|
||||
|
||||
public static ImposterEnumSet of(Object e1, Object e2, Object e3) {
|
||||
Set set = ImposterEnumSet.createSet(e1.getClass());
|
||||
set.add(e1);
|
||||
set.add(e2);
|
||||
set.add(e3);
|
||||
|
||||
return new ImposterEnumSet(set, e1.getClass());
|
||||
}
|
||||
|
||||
|
||||
public static ImposterEnumSet of(Object e1, Object e2, Object e3, Object e4) {
|
||||
Set set = ImposterEnumSet.createSet(e1.getClass());
|
||||
set.add(e1);
|
||||
set.add(e2);
|
||||
set.add(e3);
|
||||
set.add(e4);
|
||||
|
||||
return new ImposterEnumSet(set, e1.getClass());
|
||||
}
|
||||
|
||||
|
||||
public static ImposterEnumSet of(Object e1, Object e2, Object e3, Object e4, Object e5) {
|
||||
Set set = ImposterEnumSet.createSet(e1.getClass());
|
||||
set.add(e1);
|
||||
set.add(e2);
|
||||
set.add(e3);
|
||||
set.add(e4);
|
||||
set.add(e5);
|
||||
|
||||
return new ImposterEnumSet(set, e1.getClass());
|
||||
}
|
||||
|
||||
|
||||
public static ImposterEnumSet of(Object e, Object... rest) {
|
||||
Set set = ImposterEnumSet.createSet(e.getClass());
|
||||
set.add(e);
|
||||
|
||||
Collections.addAll(set, rest);
|
||||
|
||||
return new ImposterEnumSet(set, e.getClass());
|
||||
}
|
||||
|
||||
public static ImposterEnumSet range(Object from, Object to) {
|
||||
Set set;
|
||||
if (from.getClass().isEnum()) {
|
||||
set = EnumSet.range((Enum) from, (Enum) to);
|
||||
} else {
|
||||
set = new HashSet();
|
||||
Registry registry = EnumEvil.getRegistry(from.getClass());
|
||||
for (Object o : registry) {
|
||||
if (((OldEnum) o).ordinal() < ((OldEnum) from).ordinal()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((OldEnum) o).ordinal() > ((OldEnum) to).ordinal()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
set.add(o);
|
||||
}
|
||||
}
|
||||
|
||||
return new ImposterEnumSet(set, from.getClass());
|
||||
}
|
||||
|
||||
private ImposterEnumSet(Set set, Class<?> objectClass) {
|
||||
this.set = set;
|
||||
this.objectClass = objectClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Object> iterator() {
|
||||
return this.set.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.set.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return this.set.equals(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.set.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
return this.set.removeAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return this.set.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return this.set.contains(o);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
return this.set.toArray();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> T[] toArray(@NotNull T[] a) {
|
||||
return (T[]) this.set.toArray(a);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(Object o) {
|
||||
this.typeCheck(o);
|
||||
return this.set.add(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
return this.set.remove(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(@NotNull Collection<?> c) {
|
||||
return this.set.containsAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(@NotNull Collection<?> c) {
|
||||
if (this.set instanceof EnumSet<?>) {
|
||||
this.set.addAll(c);
|
||||
}
|
||||
|
||||
return super.addAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(@NotNull Collection<?> c) {
|
||||
return this.set.retainAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.set.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.set.toString();
|
||||
}
|
||||
|
||||
public ImposterEnumSet clone() {
|
||||
Set newSet;
|
||||
if (this.set instanceof EnumSet<?> enumSet) {
|
||||
newSet = enumSet.clone();
|
||||
} else {
|
||||
newSet = new HashSet();
|
||||
newSet.addAll(this.set);
|
||||
}
|
||||
|
||||
return new ImposterEnumSet(newSet, this.objectClass);
|
||||
}
|
||||
|
||||
private void typeCheck(Object object) {
|
||||
if (this.objectClass != DummyEnum.class) {
|
||||
if (!this.objectClass.isAssignableFrom(object.getClass())) {
|
||||
throw new ClassCastException(object.getClass() + " != " + this.objectClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,12 +1,12 @@
|
||||
package org.bukkit.craftbukkit.legacy.fieldrename;
|
||||
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import java.util.HashMap;
|
||||
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(RenameData<String> renameData, RenameData<NamespacedKey> keyRenameData) {
|
||||
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
package org.bukkit.craftbukkit.legacy.reroute;
|
||||
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
|
||||
public record RequirePluginVersionData(ApiVersion minInclusive, ApiVersion maxInclusive) {
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package org.bukkit.craftbukkit.legacy.reroute;
|
||||
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.bukkit.craftbukkit.util.ClassTraverser;
|
||||
import org.jetbrains.annotations.VisibleForTesting;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
+1
-1
@@ -1,6 +1,7 @@
|
||||
package org.bukkit.craftbukkit.legacy.reroute;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
@@ -10,7 +11,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
public class RerouteBuilder {
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.bukkit.craftbukkit.potion;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Suppliers;
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -13,7 +14,6 @@ import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.bukkit.craftbukkit.legacy.FieldRename;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
package org.bukkit.craftbukkit.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class ApiVersion implements Comparable<ApiVersion>, Serializable {
|
||||
|
||||
public static final ApiVersion CURRENT;
|
||||
public static final ApiVersion FLATTENING;
|
||||
public static final ApiVersion FIELD_NAME_PARITY;
|
||||
public static final ApiVersion ABSTRACT_COW;
|
||||
public static final ApiVersion ABSTRACT_CUBE_MOB;
|
||||
public static final ApiVersion NONE;
|
||||
|
||||
private static final Map<String, ApiVersion> versions;
|
||||
|
||||
static {
|
||||
versions = new HashMap<>();
|
||||
CURRENT = getOrCreateVersion(Versioning.getCurrentApiVersion());
|
||||
FLATTENING = getOrCreateVersion("1.13");
|
||||
FIELD_NAME_PARITY = getOrCreateVersion("1.20.5");
|
||||
ABSTRACT_COW = getOrCreateVersion("1.21.5");
|
||||
ABSTRACT_CUBE_MOB = getOrCreateVersion("26.2");
|
||||
NONE = getOrCreateVersion("none");
|
||||
}
|
||||
|
||||
private final boolean none;
|
||||
private final int major;
|
||||
private final int minor;
|
||||
private final int patch;
|
||||
|
||||
private ApiVersion() {
|
||||
this.none = true;
|
||||
this.major = Integer.MIN_VALUE;
|
||||
this.minor = Integer.MIN_VALUE;
|
||||
this.patch = Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
private ApiVersion(int major, int minor, int patch) {
|
||||
this.none = false;
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.patch = patch;
|
||||
}
|
||||
|
||||
public static ApiVersion getOrCreateVersion(String versionString) {
|
||||
if (versionString == null || versionString.trim().isEmpty() || versionString.equalsIgnoreCase("none")) {
|
||||
return ApiVersion.versions.computeIfAbsent("none", s -> new ApiVersion());
|
||||
}
|
||||
|
||||
ApiVersion version = ApiVersion.versions.get(versionString);
|
||||
|
||||
if (version != null) {
|
||||
return version;
|
||||
}
|
||||
|
||||
String[] versionParts = versionString.split("\\.");
|
||||
|
||||
if (versionParts.length != 2 && versionParts.length != 3) {
|
||||
throw new IllegalArgumentException(String.format("API version string should be of format \"major.minor.patch\" or \"major.minor\", where \"major\", \"minor\" and \"patch\" are numbers. For example \"1.18.2\" or \"1.13\", but got '%s' instead.", versionString));
|
||||
}
|
||||
|
||||
int major = ApiVersion.parseNumber(versionParts[0]);
|
||||
int minor = ApiVersion.parseNumber(versionParts[1]);
|
||||
|
||||
int patch;
|
||||
if (versionParts.length == 3) {
|
||||
patch = ApiVersion.parseNumber(versionParts[2]);
|
||||
} else {
|
||||
patch = 0;
|
||||
}
|
||||
|
||||
versionString = ApiVersion.toVersionString(major, minor, patch);
|
||||
return ApiVersion.versions.computeIfAbsent(versionString, s -> new ApiVersion(major, minor, patch));
|
||||
}
|
||||
|
||||
private static int parseNumber(String number) {
|
||||
return Integer.parseInt(number);
|
||||
}
|
||||
|
||||
private static String toVersionString(int major, int minor, int patch) {
|
||||
return major + "." + minor + "." + patch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull ApiVersion other) {
|
||||
int result = Integer.compare(this.major, other.major);
|
||||
|
||||
if (result == 0) {
|
||||
result = Integer.compare(this.minor, other.minor);
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
result = Integer.compare(this.patch, other.patch);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getVersionString() {
|
||||
if (this.none) {
|
||||
return "none";
|
||||
}
|
||||
|
||||
return ApiVersion.toVersionString(this.major, this.minor, this.patch);
|
||||
}
|
||||
|
||||
public boolean isNewerThan(ApiVersion apiVersion) {
|
||||
return this.compareTo(apiVersion) > 0;
|
||||
}
|
||||
|
||||
public boolean isOlderThan(ApiVersion apiVersion) {
|
||||
return this.compareTo(apiVersion) < 0;
|
||||
}
|
||||
|
||||
public boolean isNewerThanOrSameAs(ApiVersion apiVersion) {
|
||||
return this.compareTo(apiVersion) >= 0;
|
||||
}
|
||||
|
||||
public boolean isOlderThanOrSameAs(ApiVersion apiVersion) {
|
||||
return this.compareTo(apiVersion) <= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getVersionString();
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0L;
|
||||
}
|
||||
@@ -1,15 +1,13 @@
|
||||
package org.bukkit.craftbukkit.util;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
@@ -31,7 +29,6 @@ import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.legacy.FieldRename;
|
||||
import org.bukkit.craftbukkit.legacy.MaterialRerouting;
|
||||
import org.bukkit.craftbukkit.legacy.MethodRerouting;
|
||||
import org.bukkit.craftbukkit.legacy.enums.EnumEvil;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.Reroute;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.RerouteArgument;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.RerouteBuilder;
|
||||
@@ -70,12 +67,6 @@ public class Commodore {
|
||||
"org/bukkit/inventory/ItemStack (S)V setDurability"
|
||||
));
|
||||
|
||||
private static final Map<String, String> ENUM_RENAMES = Map.of(
|
||||
"java/lang/Enum", "java/lang/Object",
|
||||
"java/util/EnumSet", "org/bukkit/craftbukkit/legacy/enums/ImposterEnumSet",
|
||||
"java/util/EnumMap", "org/bukkit/craftbukkit/legacy/enums/ImposterEnumMap"
|
||||
);
|
||||
|
||||
private static final Map<String, String> RENAMES = Map.of(
|
||||
"org/bukkit/entity/TextDisplay$TextAligment", "org/bukkit/entity/TextDisplay$TextAlignment", // SPIGOT-7335
|
||||
"org/spigotmc/event/entity/EntityMountEvent", "org/bukkit/event/entity/EntityMountEvent",
|
||||
@@ -123,7 +114,6 @@ public class Commodore {
|
||||
.create(compatibilityPresent)
|
||||
.forClass(FieldRename.class)
|
||||
.forClass(MethodRerouting.class)
|
||||
.forClass(EnumEvil.class)
|
||||
.build();
|
||||
|
||||
this.reroutes.clear();
|
||||
|
||||
@@ -19,6 +19,8 @@ import io.papermc.paper.adventure.PaperAdventure;
|
||||
import io.papermc.paper.datapack.DynamicBuiltinPack;
|
||||
import io.papermc.paper.datapack.DynamicBuiltinPacks;
|
||||
import io.papermc.paper.entity.EntitySerializationFlag;
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import io.papermc.paper.plugin.entrypoint.classloader.ClassloaderBytecodeModifier;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.util.MCUtil;
|
||||
import java.io.IOException;
|
||||
@@ -421,6 +423,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
// Paper end
|
||||
try {
|
||||
clazz = this.commodore.convert(clazz, pdf.getName(), ApiVersion.getOrCreateVersion(pdf.getAPIVersion()), ((CraftServer) Bukkit.getServer()).activeCompatibilities);
|
||||
clazz = ClassloaderBytecodeModifier.bytecodeModifier().modify(pdf, clazz);
|
||||
} catch (Exception ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Fatal error trying to convert " + pdf.getFullName() + ":" + path, ex);
|
||||
}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
io.papermc.paper.plugin.entrypoint.classloader.PaperClassloaderBytecodeModifier
|
||||
io.papermc.paper.plugin.entrypoint.classloader.bytecode.PaperClassloaderBytecodeModifier
|
||||
@@ -3,6 +3,7 @@ package org.bukkit.craftbukkit.legacy;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Predicates;
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -15,7 +16,6 @@ import java.util.stream.Stream;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.Reroute;
|
||||
import org.bukkit.craftbukkit.legacy.reroute.RerouteBuilder;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.bukkit.craftbukkit.util.Commodore;
|
||||
import org.bukkit.support.environment.Normal;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
|
||||
+3
-3
@@ -2,9 +2,9 @@ package org.bukkit.craftbukkit.legacy.reroute;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import com.google.common.base.Predicates;
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.bukkit.support.environment.Normal;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -20,12 +20,12 @@ public class InjectPluginVersionTest extends AbstractRerouteTest {
|
||||
"java/lang/Object",
|
||||
"getList",
|
||||
false,
|
||||
"(Ljava/lang/Object;Lorg/bukkit/craftbukkit/util/ApiVersion;)Ljava/util/List;",
|
||||
"(Ljava/lang/Object;Lio/papermc/paper/plugin/ApiVersion;)Ljava/util/List;",
|
||||
"org/bukkit/craftbukkit/legacy/reroute/InjectPluginVersionTest$InjectPluginVersionTestData",
|
||||
"getList",
|
||||
this.create(
|
||||
this.create("Ljava/lang/Object;", "Ljava/lang/Object;", false, false, null),
|
||||
this.create("Lorg/bukkit/craftbukkit/util/ApiVersion;", "Lorg/bukkit/craftbukkit/util/ApiVersion;", false, true, null)
|
||||
this.create("Lio/papermc/paper/plugin/ApiVersion;", "Lio/papermc/paper/plugin/ApiVersion;", false, true, null)
|
||||
),
|
||||
"Ljava/util/List;",
|
||||
true,
|
||||
|
||||
+16
-15
@@ -1,8 +1,9 @@
|
||||
package org.bukkit.craftbukkit.legacy.reroute;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import java.lang.annotation.Annotation;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.bukkit.support.environment.Normal;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -19,56 +20,56 @@ public class RequirePluginVersionDataTest {
|
||||
|
||||
@Test
|
||||
public void testDifferent() {
|
||||
RequirePluginVersionData data = RequirePluginVersionData.create(new RequirePluginVersionImpl("", "1.21", "1.23"));
|
||||
RequirePluginVersionData data = RequirePluginVersionData.create(new RequirePluginVersionImpl("", "1.20", "1.21"));
|
||||
|
||||
assertEquals(ApiVersion.getOrCreateVersion("1.21"), data.minInclusive());
|
||||
assertEquals(ApiVersion.getOrCreateVersion("1.23"), data.maxInclusive());
|
||||
assertEquals(ApiVersion.getOrCreateVersion("1.20"), data.minInclusive());
|
||||
assertEquals(ApiVersion.getOrCreateVersion("1.21"), data.maxInclusive());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValue() {
|
||||
RequirePluginVersionData data = RequirePluginVersionData.create(new RequirePluginVersionImpl("1.42", "", ""));
|
||||
RequirePluginVersionData data = RequirePluginVersionData.create(new RequirePluginVersionImpl("1.21", "", ""));
|
||||
|
||||
assertEquals(ApiVersion.getOrCreateVersion("1.42"), data.minInclusive());
|
||||
assertEquals(ApiVersion.getOrCreateVersion("1.42"), data.maxInclusive());
|
||||
assertEquals(ApiVersion.getOrCreateVersion("1.21"), data.minInclusive());
|
||||
assertEquals(ApiVersion.getOrCreateVersion("1.21"), data.maxInclusive());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValueAndMin() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RequirePluginVersionData.create(new RequirePluginVersionImpl("1.42", "1.52", "")));
|
||||
assertThrows(IllegalArgumentException.class, () -> RequirePluginVersionData.create(new RequirePluginVersionImpl("1.20", "1.21", "")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValueAndMax() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RequirePluginVersionData.create(new RequirePluginVersionImpl("1.42", "", "1.53")));
|
||||
assertThrows(IllegalArgumentException.class, () -> RequirePluginVersionData.create(new RequirePluginVersionImpl("1.20", "", "1.21")));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testValueAndMinMax() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RequirePluginVersionData.create(new RequirePluginVersionImpl("1.42", "1.51", "1.53")));
|
||||
assertThrows(IllegalArgumentException.class, () -> RequirePluginVersionData.create(new RequirePluginVersionImpl("1.19", "1.20", "1.21")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMinNewerThanMax() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RequirePluginVersionData.create(new RequirePluginVersionImpl("", "1.59", "1.57")));
|
||||
assertThrows(IllegalArgumentException.class, () -> RequirePluginVersionData.create(new RequirePluginVersionImpl("", "1.21", "1.20")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnlyMin() {
|
||||
RequirePluginVersionData data = RequirePluginVersionData.create(new RequirePluginVersionImpl("", "1.44", ""));
|
||||
RequirePluginVersionData data = RequirePluginVersionData.create(new RequirePluginVersionImpl("", "1.21", ""));
|
||||
|
||||
assertEquals(ApiVersion.getOrCreateVersion("1.44"), data.minInclusive());
|
||||
assertEquals(ApiVersion.getOrCreateVersion("1.21"), data.minInclusive());
|
||||
assertNull(data.maxInclusive());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testOnlyMax() {
|
||||
RequirePluginVersionData data = RequirePluginVersionData.create(new RequirePluginVersionImpl("", "", "1.96"));
|
||||
RequirePluginVersionData data = RequirePluginVersionData.create(new RequirePluginVersionImpl("", "", "1.21"));
|
||||
|
||||
assertNull(data.minInclusive());
|
||||
assertEquals(ApiVersion.getOrCreateVersion("1.96"), data.maxInclusive());
|
||||
assertEquals(ApiVersion.getOrCreateVersion("1.21"), data.maxInclusive());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
package org.bukkit.craftbukkit.legacy.reroute;
|
||||
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.bukkit.support.environment.Normal;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -26,7 +26,7 @@ public class RequirePluginVersionTest extends AbstractRerouteTest {
|
||||
),
|
||||
"Ljava/util/List;",
|
||||
true,
|
||||
new RequirePluginVersionData(ApiVersion.getOrCreateVersion("1.42"), ApiVersion.getOrCreateVersion("1.42"))
|
||||
new RequirePluginVersionData(ApiVersion.getOrCreateVersion("1.21"), ApiVersion.getOrCreateVersion("1.21"))
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -34,7 +34,7 @@ public class RequirePluginVersionTest extends AbstractRerouteTest {
|
||||
|
||||
public static class RequirePluginVersionTestData {
|
||||
|
||||
@RequirePluginVersion("1.42")
|
||||
@RequirePluginVersion("1.21")
|
||||
public static List<String> getList(Object o) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package org.bukkit.craftbukkit.util;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import io.papermc.paper.plugin.ApiVersion;
|
||||
import java.util.stream.Stream;
|
||||
import net.minecraft.SharedConstants;
|
||||
import org.bukkit.support.environment.VanillaFeature;
|
||||
@@ -19,7 +21,9 @@ public class ApiVersionTest {
|
||||
Arguments.of("none", "none"),
|
||||
Arguments.of("1.12", "1.12.0"),
|
||||
Arguments.of("1.13.3", "1.13.3"),
|
||||
Arguments.of("1.+20.3", "1.20.3")
|
||||
Arguments.of("1.+20.3", "1.20.3"),
|
||||
Arguments.of("26.1", "26.1.0"),
|
||||
Arguments.of("28.2.3", "28.2.3")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -27,7 +31,11 @@ public class ApiVersionTest {
|
||||
return Stream.of(
|
||||
Arguments.of("none", "none", CompareResult.SAME),
|
||||
Arguments.of("none", "1.20", CompareResult.SMALLER),
|
||||
Arguments.of("2.20.3", "1.30.4", CompareResult.BIGGER),
|
||||
Arguments.of("1.20.3", "1.19.4", CompareResult.BIGGER),
|
||||
Arguments.of("26.1", "1.21.4", CompareResult.BIGGER),
|
||||
Arguments.of("26.3.2", "1.21.11", CompareResult.BIGGER),
|
||||
Arguments.of("none", "26.1.2", CompareResult.SMALLER),
|
||||
Arguments.of("1.8.9", "26.1.2", CompareResult.SMALLER),
|
||||
Arguments.of("1.13", "1.12", CompareResult.BIGGER),
|
||||
Arguments.of("1.13.2", "1.13.3", CompareResult.SMALLER)
|
||||
);
|
||||
@@ -90,8 +98,8 @@ public class ApiVersionTest {
|
||||
|
||||
@Test
|
||||
public void testSameInstance() {
|
||||
ApiVersion one = ApiVersion.getOrCreateVersion("1.23.3");
|
||||
ApiVersion second = ApiVersion.getOrCreateVersion("1.+23.3");
|
||||
ApiVersion one = ApiVersion.getOrCreateVersion("1.20.3");
|
||||
ApiVersion second = ApiVersion.getOrCreateVersion("1.+20.3");
|
||||
|
||||
assertSame(one, second);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user