mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-27 15:00:13 +01:00
update generator
This commit is contained in:
parent
9f60650248
commit
e0adb01ddc
15 changed files with 228 additions and 146 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -61,6 +61,7 @@ out/
|
||||||
|
|
||||||
# other stuff
|
# other stuff
|
||||||
run/
|
run/
|
||||||
|
logs/
|
||||||
|
|
||||||
Paper-Server
|
Paper-Server
|
||||||
Paper-API
|
Paper-API
|
||||||
|
|
|
@ -16,6 +16,8 @@ dependencies {
|
||||||
implementation(project(":paper-api"))
|
implementation(project(":paper-api"))
|
||||||
implementation("io.github.classgraph:classgraph:4.8.47")
|
implementation("io.github.classgraph:classgraph:4.8.47")
|
||||||
implementation("org.jetbrains:annotations:24.0.1")
|
implementation("org.jetbrains:annotations:24.0.1")
|
||||||
|
testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
|
||||||
|
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register<JavaExec>("generate") {
|
tasks.register<JavaExec>("generate") {
|
||||||
|
@ -24,5 +26,9 @@ tasks.register<JavaExec>("generate") {
|
||||||
args(projectDir.toPath().resolve("generated").toString())
|
args(projectDir.toPath().resolve("generated").toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
|
||||||
group = "io.papermc.paper"
|
group = "io.papermc.paper"
|
||||||
version = "1.0-SNAPSHOT"
|
version = "1.0-SNAPSHOT"
|
||||||
|
|
|
@ -1122,7 +1122,8 @@ public interface VanillaGoal<T extends Mob> extends Goal<T> {
|
||||||
)
|
)
|
||||||
GoalKey<Mob> UNIVERSAL_ANGER_RESET = create("universal_anger_reset", Mob.class);
|
GoalKey<Mob> UNIVERSAL_ANGER_RESET = create("universal_anger_reset", Mob.class);
|
||||||
|
|
||||||
private static @NotNull GoalKey create(final @NotNull String key, final @NotNull Class clazz) {
|
private static <T extends Mob> @NotNull GoalKey<T> create(final @NotNull String key,
|
||||||
return GoalKey.of(clazz, NamespacedKey.minecraft(key));
|
final @NotNull Class<T> type) {
|
||||||
|
return GoalKey.of(type, NamespacedKey.minecraft(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,6 +124,13 @@ public final class GameEventKeys {
|
||||||
*/
|
*/
|
||||||
public static final TypedKey<GameEvent> ELYTRA_GLIDE = create(key("elytra_glide"));
|
public static final TypedKey<GameEvent> ELYTRA_GLIDE = create(key("elytra_glide"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code minecraft:entity_action}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TypedKey<GameEvent> ENTITY_ACTION = create(key("entity_action"));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code minecraft:entity_damage}
|
* {@code minecraft:entity_damage}
|
||||||
*
|
*
|
||||||
|
@ -166,13 +173,6 @@ public final class GameEventKeys {
|
||||||
*/
|
*/
|
||||||
public static final TypedKey<GameEvent> ENTITY_PLACE = create(key("entity_place"));
|
public static final TypedKey<GameEvent> ENTITY_PLACE = create(key("entity_place"));
|
||||||
|
|
||||||
/**
|
|
||||||
* {@code minecraft:entity_action}
|
|
||||||
*
|
|
||||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
|
||||||
*/
|
|
||||||
public static final TypedKey<GameEvent> ENTITY_ACTION = create(key("entity_action"));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code minecraft:equip}
|
* {@code minecraft:equip}
|
||||||
*
|
*
|
||||||
|
@ -285,62 +285,6 @@ public final class GameEventKeys {
|
||||||
*/
|
*/
|
||||||
public static final TypedKey<GameEvent> PROJECTILE_SHOOT = create(key("projectile_shoot"));
|
public static final TypedKey<GameEvent> PROJECTILE_SHOOT = create(key("projectile_shoot"));
|
||||||
|
|
||||||
/**
|
|
||||||
* {@code minecraft:sculk_sensor_tendrils_clicking}
|
|
||||||
*
|
|
||||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
|
||||||
*/
|
|
||||||
public static final TypedKey<GameEvent> SCULK_SENSOR_TENDRILS_CLICKING = create(key("sculk_sensor_tendrils_clicking"));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@code minecraft:shear}
|
|
||||||
*
|
|
||||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
|
||||||
*/
|
|
||||||
public static final TypedKey<GameEvent> SHEAR = create(key("shear"));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@code minecraft:shriek}
|
|
||||||
*
|
|
||||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
|
||||||
*/
|
|
||||||
public static final TypedKey<GameEvent> SHRIEK = create(key("shriek"));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@code minecraft:splash}
|
|
||||||
*
|
|
||||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
|
||||||
*/
|
|
||||||
public static final TypedKey<GameEvent> SPLASH = create(key("splash"));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@code minecraft:step}
|
|
||||||
*
|
|
||||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
|
||||||
*/
|
|
||||||
public static final TypedKey<GameEvent> STEP = create(key("step"));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@code minecraft:swim}
|
|
||||||
*
|
|
||||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
|
||||||
*/
|
|
||||||
public static final TypedKey<GameEvent> SWIM = create(key("swim"));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@code minecraft:teleport}
|
|
||||||
*
|
|
||||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
|
||||||
*/
|
|
||||||
public static final TypedKey<GameEvent> TELEPORT = create(key("teleport"));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@code minecraft:unequip}
|
|
||||||
*
|
|
||||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
|
||||||
*/
|
|
||||||
public static final TypedKey<GameEvent> UNEQUIP = create(key("unequip"));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code minecraft:resonate_1}
|
* {@code minecraft:resonate_1}
|
||||||
*
|
*
|
||||||
|
@ -446,6 +390,62 @@ public final class GameEventKeys {
|
||||||
*/
|
*/
|
||||||
public static final TypedKey<GameEvent> RESONATE_15 = create(key("resonate_15"));
|
public static final TypedKey<GameEvent> RESONATE_15 = create(key("resonate_15"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code minecraft:sculk_sensor_tendrils_clicking}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TypedKey<GameEvent> SCULK_SENSOR_TENDRILS_CLICKING = create(key("sculk_sensor_tendrils_clicking"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code minecraft:shear}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TypedKey<GameEvent> SHEAR = create(key("shear"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code minecraft:shriek}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TypedKey<GameEvent> SHRIEK = create(key("shriek"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code minecraft:splash}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TypedKey<GameEvent> SPLASH = create(key("splash"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code minecraft:step}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TypedKey<GameEvent> STEP = create(key("step"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code minecraft:swim}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TypedKey<GameEvent> SWIM = create(key("swim"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code minecraft:teleport}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TypedKey<GameEvent> TELEPORT = create(key("teleport"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code minecraft:unequip}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TypedKey<GameEvent> UNEQUIP = create(key("unequip"));
|
||||||
|
|
||||||
private GameEventKeys() {
|
private GameEventKeys() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
package io.papermc.generator;
|
package io.papermc.generator;
|
||||||
|
|
||||||
import com.mojang.logging.LogUtils;
|
import com.mojang.logging.LogUtils;
|
||||||
import io.papermc.generator.types.GeneratedKeyType;
|
|
||||||
import io.papermc.generator.types.SourceGenerator;
|
import io.papermc.generator.types.SourceGenerator;
|
||||||
import io.papermc.paper.registry.RegistryKey;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.List;
|
|
||||||
import net.minecraft.SharedConstants;
|
import net.minecraft.SharedConstants;
|
||||||
import net.minecraft.core.LayeredRegistryAccess;
|
import net.minecraft.core.LayeredRegistryAccess;
|
||||||
import net.minecraft.core.Registry;
|
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.core.registries.Registries;
|
|
||||||
import net.minecraft.resources.RegistryDataLoader;
|
import net.minecraft.resources.RegistryDataLoader;
|
||||||
import net.minecraft.resources.ResourceKey;
|
|
||||||
import net.minecraft.server.Bootstrap;
|
import net.minecraft.server.Bootstrap;
|
||||||
import net.minecraft.server.RegistryLayer;
|
import net.minecraft.server.RegistryLayer;
|
||||||
import net.minecraft.server.WorldLoader;
|
import net.minecraft.server.WorldLoader;
|
||||||
|
@ -24,12 +18,6 @@ import net.minecraft.server.packs.repository.PackRepository;
|
||||||
import net.minecraft.server.packs.repository.ServerPacksSource;
|
import net.minecraft.server.packs.repository.ServerPacksSource;
|
||||||
import net.minecraft.server.packs.resources.MultiPackResourceManager;
|
import net.minecraft.server.packs.resources.MultiPackResourceManager;
|
||||||
import org.apache.commons.io.file.PathUtils;
|
import org.apache.commons.io.file.PathUtils;
|
||||||
import org.bukkit.GameEvent;
|
|
||||||
import org.bukkit.block.Biome;
|
|
||||||
import org.bukkit.generator.structure.Structure;
|
|
||||||
import org.bukkit.generator.structure.StructureType;
|
|
||||||
import org.bukkit.inventory.meta.trim.TrimMaterial;
|
|
||||||
import org.bukkit.inventory.meta.trim.TrimPattern;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
public final class Main {
|
public final class Main {
|
||||||
|
@ -40,6 +28,8 @@ public final class Main {
|
||||||
static {
|
static {
|
||||||
SharedConstants.tryDetectVersion();
|
SharedConstants.tryDetectVersion();
|
||||||
Bootstrap.bootStrap();
|
Bootstrap.bootStrap();
|
||||||
|
Bootstrap.validate();
|
||||||
|
|
||||||
final PackRepository resourceRepository = ServerPacksSource.createVanillaTrustedRepository();
|
final PackRepository resourceRepository = ServerPacksSource.createVanillaTrustedRepository();
|
||||||
resourceRepository.reload();
|
resourceRepository.reload();
|
||||||
final MultiPackResourceManager resourceManager = new MultiPackResourceManager(PackType.SERVER_DATA, resourceRepository.getAvailablePacks().stream().map(Pack::open).toList());
|
final MultiPackResourceManager resourceManager = new MultiPackResourceManager(PackType.SERVER_DATA, resourceRepository.getAvailablePacks().stream().map(Pack::open).toList());
|
||||||
|
|
|
@ -10,6 +10,7 @@ import com.squareup.javapoet.TypeSpec;
|
||||||
import io.papermc.generator.Main;
|
import io.papermc.generator.Main;
|
||||||
import io.papermc.generator.utils.Annotations;
|
import io.papermc.generator.utils.Annotations;
|
||||||
import io.papermc.generator.utils.CollectingContext;
|
import io.papermc.generator.utils.CollectingContext;
|
||||||
|
import io.papermc.generator.utils.Formatting;
|
||||||
import io.papermc.generator.utils.Javadocs;
|
import io.papermc.generator.utils.Javadocs;
|
||||||
import io.papermc.paper.registry.RegistryKey;
|
import io.papermc.paper.registry.RegistryKey;
|
||||||
import io.papermc.paper.registry.TypedKey;
|
import io.papermc.paper.registry.TypedKey;
|
||||||
|
@ -19,14 +20,15 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.RegistrySetBuilder;
|
import net.minecraft.core.RegistrySetBuilder;
|
||||||
import net.minecraft.data.registries.UpdateOneTwentyOneRegistries;
|
import net.minecraft.data.registries.UpdateOneTwentyOneRegistries;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import org.bukkit.MinecraftExperimental;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||||
|
@ -115,30 +117,31 @@ public class GeneratedKeyType<T, A> extends SimpleGenerator {
|
||||||
final TypeName typedKey = ParameterizedTypeName.get(TypedKey.class, this.apiType);
|
final TypeName typedKey = ParameterizedTypeName.get(TypedKey.class, this.apiType);
|
||||||
|
|
||||||
final TypeSpec.Builder typeBuilder = this.keyHolderType();
|
final TypeSpec.Builder typeBuilder = this.keyHolderType();
|
||||||
typeBuilder.addAnnotation(EXPERIMENTAL_API_ANNOTATION); // TODO experimental API
|
|
||||||
final MethodSpec.Builder createMethod = this.createMethod(typedKey);
|
final MethodSpec.Builder createMethod = this.createMethod(typedKey);
|
||||||
|
|
||||||
final Registry<T> registry = Main.REGISTRY_ACCESS.registryOrThrow(this.registryKey);
|
final Registry<T> registry = Main.REGISTRY_ACCESS.registryOrThrow(this.registryKey);
|
||||||
final List<ResourceKey<T>> experimental = this.collectExperimentalKeys(registry);
|
final List<ResourceKey<T>> experimental = this.collectExperimentalKeys(registry);
|
||||||
|
|
||||||
boolean allExperimental = true;
|
boolean allExperimental = true;
|
||||||
for (final T value : registry) {
|
for (final Holder.Reference<T> reference : registry.holders().sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath())).toList()) {
|
||||||
final ResourceKey<T> key = registry.getResourceKey(value).orElseThrow();
|
final ResourceKey<T> key = reference.key();
|
||||||
final String keyPath = key.location().getPath();
|
final String keyPath = key.location().getPath();
|
||||||
final String fieldName = keyPath.toUpperCase(Locale.ENGLISH).replaceAll("[.-/]", "_"); // replace invalid field name chars
|
final String fieldName = Formatting.formatKeyAsField(keyPath);
|
||||||
final FieldSpec.Builder fieldBuilder = FieldSpec.builder(typedKey, fieldName, PUBLIC, STATIC, FINAL)
|
final FieldSpec.Builder fieldBuilder = FieldSpec.builder(typedKey, fieldName, PUBLIC, STATIC, FINAL)
|
||||||
.initializer("$N(key($S))", createMethod.build(), keyPath)
|
.initializer("$N(key($S))", createMethod.build(), keyPath)
|
||||||
.addJavadoc(Javadocs.getVersionDependentField("{@code $L}"), key.location().toString());
|
.addJavadoc(Javadocs.getVersionDependentField("{@code $L}"), key.location().toString());
|
||||||
if (experimental.contains(key)) {
|
if (experimental.contains(key)) {
|
||||||
fieldBuilder.addAnnotations(experimentalAnnotations("MinecraftExperimental.Requires.UPDATE_1_21"));
|
fieldBuilder.addAnnotations(experimentalAnnotations(MinecraftExperimental.Requires.UPDATE_1_21));
|
||||||
} else {
|
} else {
|
||||||
allExperimental = false;
|
allExperimental = false;
|
||||||
}
|
}
|
||||||
typeBuilder.addField(fieldBuilder.build());
|
typeBuilder.addField(fieldBuilder.build());
|
||||||
}
|
}
|
||||||
if (allExperimental) {
|
if (allExperimental) {
|
||||||
typeBuilder.addAnnotations(experimentalAnnotations("MinecraftExperimental.Requires.UPDATE_1_21"));
|
typeBuilder.addAnnotations(experimentalAnnotations(MinecraftExperimental.Requires.UPDATE_1_21));
|
||||||
createMethod.addAnnotations(experimentalAnnotations("MinecraftExperimental.Requires.UPDATE_1_21"));
|
createMethod.addAnnotations(experimentalAnnotations(MinecraftExperimental.Requires.UPDATE_1_21));
|
||||||
|
} else {
|
||||||
|
typeBuilder.addAnnotation(EXPERIMENTAL_API_ANNOTATION); // TODO experimental API
|
||||||
}
|
}
|
||||||
return typeBuilder.addMethod(createMethod.build()).build();
|
return typeBuilder.addMethod(createMethod.build()).build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import com.squareup.javapoet.TypeSpec;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
public abstract class SimpleGenerator implements SourceGenerator {
|
public abstract class SimpleGenerator implements SourceGenerator {
|
||||||
|
@ -24,14 +23,13 @@ public abstract class SimpleGenerator implements SourceGenerator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToFile(Path parent) throws IOException {
|
public void writeToFile(Path parent) throws IOException {
|
||||||
Path packagePath = parent.resolve(this.packageName.replace('.', '/'));
|
|
||||||
Files.createDirectories(packagePath);
|
|
||||||
|
|
||||||
JavaFile.Builder builder = JavaFile.builder(this.packageName, this.getTypeSpec())
|
JavaFile.Builder builder = JavaFile.builder(this.packageName, this.getTypeSpec());
|
||||||
.indent(" ");
|
this.file(builder)
|
||||||
this.file(builder);
|
.indent(" ")
|
||||||
|
.skipJavaLangImports(true);
|
||||||
|
|
||||||
Files.writeString(packagePath.resolve(this.className + ".java"), this.file(builder).build().toString(), StandardCharsets.UTF_8);
|
builder.build().writeTo(parent, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package io.papermc.generator.types.goal;
|
||||||
|
|
||||||
import com.destroystokyo.paper.entity.RangedEntity;
|
import com.destroystokyo.paper.entity.RangedEntity;
|
||||||
import com.destroystokyo.paper.entity.ai.GoalKey;
|
import com.destroystokyo.paper.entity.ai.GoalKey;
|
||||||
import com.squareup.javapoet.AnnotationSpec;
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.FieldSpec;
|
import com.squareup.javapoet.FieldSpec;
|
||||||
import com.squareup.javapoet.JavaFile;
|
import com.squareup.javapoet.JavaFile;
|
||||||
|
@ -19,12 +18,7 @@ import io.papermc.generator.utils.Annotations;
|
||||||
import io.papermc.generator.utils.Formatting;
|
import io.papermc.generator.utils.Formatting;
|
||||||
import io.papermc.generator.utils.Javadocs;
|
import io.papermc.generator.utils.Javadocs;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
import net.minecraft.world.entity.ai.goal.Goal;
|
import net.minecraft.world.entity.ai.goal.Goal;
|
||||||
import net.minecraft.world.entity.ai.goal.WrappedGoal;
|
import net.minecraft.world.entity.ai.goal.WrappedGoal;
|
||||||
|
@ -65,9 +59,13 @@ import org.bukkit.entity.Vindicator;
|
||||||
import org.bukkit.entity.WanderingTrader;
|
import org.bukkit.entity.WanderingTrader;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import static javax.lang.model.element.Modifier.FINAL;
|
||||||
|
import static javax.lang.model.element.Modifier.PRIVATE;
|
||||||
|
import static javax.lang.model.element.Modifier.PUBLIC;
|
||||||
|
import static javax.lang.model.element.Modifier.STATIC;
|
||||||
|
|
||||||
@DefaultQualifier(NonNull.class)
|
@DefaultQualifier(NonNull.class)
|
||||||
public class MobGoalGenerator extends SimpleGenerator {
|
public class MobGoalGenerator extends SimpleGenerator {
|
||||||
|
|
||||||
|
@ -168,57 +166,53 @@ public class MobGoalGenerator extends SimpleGenerator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TypeSpec getTypeSpec() {
|
protected TypeSpec getTypeSpec() {
|
||||||
TypeName clazzType = TypeName.get(Class.class)
|
|
||||||
.annotated(Annotations.NOT_NULL);
|
|
||||||
TypeName keyType = TypeName.get(String.class)
|
|
||||||
.annotated(Annotations.NOT_NULL);
|
|
||||||
|
|
||||||
MethodSpec.Builder createMethod = MethodSpec.methodBuilder("create")
|
|
||||||
.addModifiers(Modifier.PRIVATE, Modifier.STATIC)
|
|
||||||
.addParameter(ParameterSpec.builder(keyType, "key", Modifier.FINAL)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.addParameter(ParameterSpec.builder(clazzType, "clazz", Modifier.FINAL)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.addCode("return $T.of(clazz, $T.minecraft(key));", GoalKey.class, NamespacedKey.class)
|
|
||||||
.returns(ParameterizedTypeName.get(GoalKey.class).annotated(Annotations.NOT_NULL));
|
|
||||||
|
|
||||||
|
|
||||||
TypeVariableName type = TypeVariableName.get("T", Mob.class);
|
TypeVariableName type = TypeVariableName.get("T", Mob.class);
|
||||||
TypeSpec.Builder typeBuilder = TypeSpec.interfaceBuilder(this.className)
|
TypeSpec.Builder typeBuilder = TypeSpec.interfaceBuilder(this.className)
|
||||||
.addSuperinterface(ParameterizedTypeName.get(ClassName.get(com.destroystokyo.paper.entity.ai.Goal.class), type))
|
.addSuperinterface(ParameterizedTypeName.get(ClassName.get(com.destroystokyo.paper.entity.ai.Goal.class), type))
|
||||||
.addModifiers(Modifier.PUBLIC)
|
.addModifiers(PUBLIC)
|
||||||
.addTypeVariable(type)
|
.addTypeVariable(type)
|
||||||
.addAnnotations(Annotations.CLASS_HEADER)
|
.addAnnotations(Annotations.CLASS_HEADER)
|
||||||
.addJavadoc(CLASS_HEADER);
|
.addJavadoc(CLASS_HEADER);
|
||||||
|
|
||||||
|
TypeName mobType = ParameterizedTypeName.get(ClassName.get(Class.class), type)
|
||||||
|
.annotated(Annotations.NOT_NULL);
|
||||||
|
TypeName keyType = TypeName.get(String.class)
|
||||||
|
.annotated(Annotations.NOT_NULL);
|
||||||
|
|
||||||
List<Class<?>> classes;
|
ParameterSpec keyParam = ParameterSpec.builder(keyType, "key", FINAL).build();
|
||||||
|
ParameterSpec typeParam = ParameterSpec.builder(mobType, "type", FINAL).build();
|
||||||
|
MethodSpec.Builder createMethod = MethodSpec.methodBuilder("create")
|
||||||
|
.addModifiers(PRIVATE, STATIC)
|
||||||
|
.addParameter(keyParam)
|
||||||
|
.addParameter(typeParam)
|
||||||
|
.addCode("return $T.of($N, $T.minecraft($N));", GoalKey.class, typeParam, NamespacedKey.class, keyParam)
|
||||||
|
.addTypeVariable(type)
|
||||||
|
.returns(ParameterizedTypeName.get(ClassName.get(GoalKey.class), type).annotated(Annotations.NOT_NULL));
|
||||||
|
|
||||||
|
List<Class<Goal>> classes;
|
||||||
try (ScanResult scanResult = new ClassGraph().enableAllInfo().whitelistPackages("net.minecraft").scan()) {
|
try (ScanResult scanResult = new ClassGraph().enableAllInfo().whitelistPackages("net.minecraft").scan()) {
|
||||||
classes = scanResult.getSubclasses(net.minecraft.world.entity.ai.goal.Goal.class.getName()).loadClasses();
|
classes = scanResult.getSubclasses(Goal.class.getName()).loadClasses(Goal.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<VanillaGoalKey> vanillaNames = classes.stream()
|
List<GoalKey<Mob>> vanillaNames = classes.stream()
|
||||||
.filter(clazz -> !java.lang.reflect.Modifier.isAbstract(clazz.getModifiers()))
|
.filter(clazz -> !java.lang.reflect.Modifier.isAbstract(clazz.getModifiers()))
|
||||||
.filter(clazz -> !WrappedGoal.class.equals(clazz)) // TODO - properly fix
|
.filter(clazz -> !WrappedGoal.class.equals(clazz)) // TODO - properly fix
|
||||||
.map(goalClass -> new VanillaGoalKey(goalClass, MobGoalNames.getKey(goalClass.getName(), (Class<? extends Goal>) goalClass)))
|
.map(goalClass -> MobGoalNames.getKey(goalClass.getName(), goalClass))
|
||||||
.filter((key) -> !MobGoalNames.isIgnored(key.key().getNamespacedKey().getKey()))
|
.filter((key) -> !MobGoalNames.isIgnored(key.getNamespacedKey().getKey()))
|
||||||
.sorted(Comparator.<VanillaGoalKey, String>comparing(o -> o.key().getEntityClass().getSimpleName())
|
.sorted(Comparator.<GoalKey<?>, String>comparing(o -> o.getEntityClass().getSimpleName())
|
||||||
.thenComparing(vanillaGoalKey -> vanillaGoalKey.key.getNamespacedKey().getKey())
|
.thenComparing(vanillaGoalKey -> vanillaGoalKey.getNamespacedKey().getKey())
|
||||||
)
|
)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
|
||||||
for (final VanillaGoalKey vanillaGoalKey : vanillaNames) {
|
for (final GoalKey<?> goalKey : vanillaNames) {
|
||||||
GoalKey<?> value = vanillaGoalKey.key();
|
TypeName typedKey = ParameterizedTypeName.get(GoalKey.class, goalKey.getEntityClass());
|
||||||
TypeName typedKey = ParameterizedTypeName.get(GoalKey.class, value.getEntityClass());
|
NamespacedKey key = goalKey.getNamespacedKey();
|
||||||
NamespacedKey key = value.getNamespacedKey();
|
|
||||||
|
|
||||||
String keyPath = key.getKey();
|
String keyPath = key.getKey();
|
||||||
String fieldName = Formatting.formatKeyAsField(key);
|
String fieldName = Formatting.formatKeyAsField(keyPath);
|
||||||
FieldSpec.Builder fieldBuilder = FieldSpec.builder(typedKey, fieldName, Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
|
FieldSpec.Builder fieldBuilder = FieldSpec.builder(typedKey, fieldName, PUBLIC, STATIC, FINAL)
|
||||||
.initializer("$N($S, $T.class)", createMethod.build(), keyPath, value.getEntityClass());
|
.initializer("$N($S, $T.class)", createMethod.build(), keyPath, goalKey.getEntityClass());
|
||||||
typeBuilder.addField(fieldBuilder.build());
|
typeBuilder.addField(fieldBuilder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,8 +221,8 @@ public class MobGoalGenerator extends SimpleGenerator {
|
||||||
NamespacedKey key = NamespacedKey.minecraft(value.entryName);
|
NamespacedKey key = NamespacedKey.minecraft(value.entryName);
|
||||||
|
|
||||||
String keyPath = key.getKey();
|
String keyPath = key.getKey();
|
||||||
String fieldName = Formatting.formatKeyAsField(key);
|
String fieldName = Formatting.formatKeyAsField(keyPath);
|
||||||
FieldSpec.Builder fieldBuilder = FieldSpec.builder(typedKey, fieldName, Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
|
FieldSpec.Builder fieldBuilder = FieldSpec.builder(typedKey, fieldName, PUBLIC, STATIC, FINAL)
|
||||||
.addAnnotation(Annotations.deprecatedVersioned(value.removedVersion, value.removalVersion != null))
|
.addAnnotation(Annotations.deprecatedVersioned(value.removedVersion, value.removalVersion != null))
|
||||||
.initializer("$N($S, $T.class)", createMethod.build(), keyPath, value.entity);
|
.initializer("$N($S, $T.class)", createMethod.build(), keyPath, value.entity);
|
||||||
|
|
||||||
|
@ -251,9 +245,6 @@ public class MobGoalGenerator extends SimpleGenerator {
|
||||||
.skipJavaLangImports(true);
|
.skipJavaLangImports(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
record VanillaGoalKey(Class<?> clazz, GoalKey<?> key) {
|
|
||||||
}
|
|
||||||
|
|
||||||
record DeprecatedEntry(Class<?> entity, String entryName, @Nullable String removalVersion,
|
record DeprecatedEntry(Class<?> entity, String entryName, @Nullable String removalVersion,
|
||||||
@Nullable String removedVersion) {
|
@Nullable String removedVersion) {
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ import java.util.Set;
|
||||||
public class MobGoalNames {
|
public class MobGoalNames {
|
||||||
|
|
||||||
private static final Map<Class<? extends Goal>, Class<? extends Mob>> entityClassCache = new HashMap<>();
|
private static final Map<Class<? extends Goal>, Class<? extends Mob>> entityClassCache = new HashMap<>();
|
||||||
private static final Map<Class<? extends net.minecraft.world.entity.Mob>, Class<? extends Mob>> bukkitMap = new HashMap<>();
|
public static final Map<Class<? extends net.minecraft.world.entity.Mob>, Class<? extends Mob>> bukkitMap = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -233,6 +233,8 @@ public class MobGoalNames {
|
||||||
bukkitMap.put(net.minecraft.world.entity.animal.allay.Allay.class, org.bukkit.entity.Allay.class);
|
bukkitMap.put(net.minecraft.world.entity.animal.allay.Allay.class, org.bukkit.entity.Allay.class);
|
||||||
bukkitMap.put(net.minecraft.world.entity.animal.sniffer.Sniffer.class, org.bukkit.entity.Sniffer.class);
|
bukkitMap.put(net.minecraft.world.entity.animal.sniffer.Sniffer.class, org.bukkit.entity.Sniffer.class);
|
||||||
bukkitMap.put(net.minecraft.world.entity.monster.breeze.Breeze.class, org.bukkit.entity.Breeze.class);
|
bukkitMap.put(net.minecraft.world.entity.monster.breeze.Breeze.class, org.bukkit.entity.Breeze.class);
|
||||||
|
bukkitMap.put(net.minecraft.world.entity.animal.armadillo.Armadillo.class, org.bukkit.entity.Armadillo.class);
|
||||||
|
bukkitMap.put(net.minecraft.world.entity.monster.Bogged.class, org.bukkit.entity.Bogged.class);
|
||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,11 @@ import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public final class Annotations {
|
public final class Annotations {
|
||||||
|
|
||||||
public static List<AnnotationSpec> experimentalAnnotations(final String version) {
|
public static List<AnnotationSpec> experimentalAnnotations(final MinecraftExperimental.Requires requiredFeatureFlag) {
|
||||||
return List.of(
|
return List.of(
|
||||||
AnnotationSpec.builder(ApiStatus.Experimental.class).build(),
|
AnnotationSpec.builder(ApiStatus.Experimental.class).build(),
|
||||||
AnnotationSpec.builder(MinecraftExperimental.class)
|
AnnotationSpec.builder(MinecraftExperimental.class)
|
||||||
.addMember("value", "$L", version)
|
.addMember("value", "$T.$L", MinecraftExperimental.Requires.class, requiredFeatureFlag.name())
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,47 @@
|
||||||
package io.papermc.generator.utils;
|
package io.papermc.generator.utils;
|
||||||
|
|
||||||
import net.kyori.adventure.key.Key;
|
import org.apache.commons.lang3.math.NumberUtils;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.OptionalInt;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public final class Formatting {
|
public final class Formatting {
|
||||||
|
|
||||||
public static String formatKeyAsField(Key key) {
|
private static final Pattern ILLEGAL_FIELD_CHARACTERS = Pattern.compile("[.-/]");
|
||||||
return key.value().toUpperCase(Locale.ENGLISH).replaceAll("[.-/]", "_"); // replace invalid field name chars
|
|
||||||
|
public static String formatKeyAsField(String path) {
|
||||||
|
return ILLEGAL_FIELD_CHARACTERS.matcher(path.toUpperCase(Locale.ENGLISH)).replaceAll("_");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Comparator<String> ALPHABETIC_KEY_ORDER = alphabeticKeyOrder(path -> path);
|
||||||
|
|
||||||
|
public static <T> Comparator<T> alphabeticKeyOrder(Function<T, String> mapper) {
|
||||||
|
return (o1, o2) -> {
|
||||||
|
String path1 = mapper.apply(o1);
|
||||||
|
String path2 = mapper.apply(o2);
|
||||||
|
|
||||||
|
OptionalInt trailingInt1 = tryParseTrailingInt(path1);
|
||||||
|
OptionalInt trailingInt2 = tryParseTrailingInt(path2);
|
||||||
|
|
||||||
|
if (trailingInt1.isPresent() && trailingInt2.isPresent()) {
|
||||||
|
return Integer.compare(trailingInt1.getAsInt(), trailingInt2.getAsInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
return path1.compareTo(path2);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static OptionalInt tryParseTrailingInt(String path) {
|
||||||
|
int delimiterIndex = path.lastIndexOf('_');
|
||||||
|
if (delimiterIndex != -1) {
|
||||||
|
String score = path.substring(delimiterIndex + 1);
|
||||||
|
if (NumberUtils.isDigits(score)) {
|
||||||
|
return OptionalInt.of(Integer.parseInt(score));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return OptionalInt.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Formatting() {
|
private Formatting() {
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package io.papermc.generator;
|
||||||
|
|
||||||
|
import io.github.classgraph.ClassGraph;
|
||||||
|
import io.github.classgraph.ScanResult;
|
||||||
|
import io.papermc.generator.types.goal.MobGoalNames;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.Mob;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
|
public class MobGoalConverterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBukkitMap() {
|
||||||
|
final List<Class<Mob>> classes;
|
||||||
|
try (ScanResult scanResult = new ClassGraph().enableAllInfo().whitelistPackages(Entity.class.getPackageName()).scan()) {
|
||||||
|
classes = scanResult.getSubclasses(Mob.class.getName()).loadClasses(Mob.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertFalse(classes.isEmpty(), "There are supposed to be more than 0 mob classes!");
|
||||||
|
|
||||||
|
List<String> missingClasses = new ArrayList<>();
|
||||||
|
for (Class<Mob> nmsClass : classes) {
|
||||||
|
if (!MobGoalNames.bukkitMap.containsKey(nmsClass)) {
|
||||||
|
missingClasses.add(nmsClass.getCanonicalName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!missingClasses.isEmpty()) {
|
||||||
|
fail("Missing some entity classes in the bukkit map: " + String.join(", ", missingClasses));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -250,9 +250,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
--- a/src/main/java/org/bukkit/MinecraftExperimental.java
|
--- a/src/main/java/org/bukkit/MinecraftExperimental.java
|
||||||
+++ b/src/main/java/org/bukkit/MinecraftExperimental.java
|
+++ b/src/main/java/org/bukkit/MinecraftExperimental.java
|
||||||
@@ -0,0 +0,0 @@ public @interface MinecraftExperimental {
|
@@ -0,0 +0,0 @@ public @interface MinecraftExperimental {
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public enum Requires {
|
||||||
|
|
||||||
UPDATE_1_21
|
- UPDATE_1_21
|
||||||
|
+ UPDATE_1_21, BUNDLE, TRADE_REBALANCE // Paper
|
||||||
}
|
}
|
||||||
+
|
|
||||||
+ String desc() default ""; // Paper
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,6 +244,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
EGG(21603, 16),
|
EGG(21603, 16),
|
||||||
COMPASS(24139),
|
COMPASS(24139),
|
||||||
RECOVERY_COMPASS(12710),
|
RECOVERY_COMPASS(12710),
|
||||||
|
+ @MinecraftExperimental(Requires.BUNDLE) // Paper - add missing annotation
|
||||||
+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation
|
+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation
|
||||||
BUNDLE(16835, 1),
|
BUNDLE(16835, 1),
|
||||||
FISHING_ROD(4167, 1, 64),
|
FISHING_ROD(4167, 1, 64),
|
||||||
|
@ -796,6 +797,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
EVENT_MOB_EFFECT_TRIAL_OMEN("event.mob_effect.trial_omen"),
|
EVENT_MOB_EFFECT_TRIAL_OMEN("event.mob_effect.trial_omen"),
|
||||||
EVENT_RAID_HORN("event.raid.horn"),
|
EVENT_RAID_HORN("event.raid.horn"),
|
||||||
INTENTIONALLY_EMPTY("intentionally_empty"),
|
INTENTIONALLY_EMPTY("intentionally_empty"),
|
||||||
|
@@ -0,0 +0,0 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa
|
||||||
|
ITEM_BUCKET_FILL_LAVA("item.bucket.fill_lava"),
|
||||||
|
ITEM_BUCKET_FILL_POWDER_SNOW("item.bucket.fill_powder_snow"),
|
||||||
|
ITEM_BUCKET_FILL_TADPOLE("item.bucket.fill_tadpole"),
|
||||||
|
+ @MinecraftExperimental(Requires.BUNDLE) // Paper - add missing annotation
|
||||||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation
|
||||||
|
ITEM_BUNDLE_DROP_CONTENTS("item.bundle.drop_contents"),
|
||||||
|
+ @MinecraftExperimental(Requires.BUNDLE) // Paper - add missing annotation
|
||||||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation
|
||||||
|
ITEM_BUNDLE_INSERT("item.bundle.insert"),
|
||||||
|
+ @MinecraftExperimental(Requires.BUNDLE) // Paper - add missing annotation
|
||||||
|
+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation
|
||||||
|
ITEM_BUNDLE_REMOVE_ONE("item.bundle.remove_one"),
|
||||||
|
ITEM_CHORUS_FRUIT_TELEPORT("item.chorus_fruit.teleport"),
|
||||||
|
ITEM_CROP_PLANT("item.crop.plant"),
|
||||||
@@ -0,0 +0,0 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa
|
@@ -0,0 +0,0 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa
|
||||||
ITEM_INK_SAC_USE("item.ink_sac.use"),
|
ITEM_INK_SAC_USE("item.ink_sac.use"),
|
||||||
ITEM_LODESTONE_COMPASS_LOCK("item.lodestone_compass.lock"),
|
ITEM_LODESTONE_COMPASS_LOCK("item.lodestone_compass.lock"),
|
||||||
|
|
|
@ -270,6 +270,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
+ bukkitMap.put(net.minecraft.world.entity.animal.allay.Allay.class, org.bukkit.entity.Allay.class);
|
+ bukkitMap.put(net.minecraft.world.entity.animal.allay.Allay.class, org.bukkit.entity.Allay.class);
|
||||||
+ bukkitMap.put(net.minecraft.world.entity.animal.sniffer.Sniffer.class, org.bukkit.entity.Sniffer.class);
|
+ bukkitMap.put(net.minecraft.world.entity.animal.sniffer.Sniffer.class, org.bukkit.entity.Sniffer.class);
|
||||||
+ bukkitMap.put(Breeze.class, org.bukkit.entity.Breeze.class);
|
+ bukkitMap.put(Breeze.class, org.bukkit.entity.Breeze.class);
|
||||||
|
+ bukkitMap.put(net.minecraft.world.entity.animal.armadillo.Armadillo.class, org.bukkit.entity.Armadillo.class);
|
||||||
|
+ bukkitMap.put(net.minecraft.world.entity.monster.Bogged.class, org.bukkit.entity.Bogged.class);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ public static String getUsableName(Class<?> clazz) {
|
+ public static String getUsableName(Class<?> clazz) {
|
||||||
|
|
Loading…
Reference in a new issue