31699ae9a8
* Updated Upstream (Bukkit/CraftBukkit) Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: a6a9d2a4 Remove some old ApiStatus.Experimental annotations be72314c SPIGOT-7300, PR-829: Add new DamageSource API providing enhanced information about entity damage b252cf05 SPIGOT-7576, PR-970: Add methods in MushroomCow to change stew effects b1c689bd PR-902: Add Server#isLoggingIPs to get log-ips configuration 08f86d1c PR-971: Add Player methods for client-side potion effects 2e3024a9 PR-963: Add API for in-world structures a23292a7 SPIGOT-7530, PR-948: Improve Resource Pack API with new 1.20.3 functionality 1851857b SPIGOT-3071, PR-969: Add entity spawn method with spawn reason cde4c52a SPIGOT-5553, PR-964: Add EntityKnockbackEvent CraftBukkit Changes: 38fd4bd50 Fix accidentally renamed internal damage method 80f0ce4be SPIGOT-7300, PR-1180: Add new DamageSource API providing enhanced information about entity damage 7e43f3b16 SPIGOT-7581: Fix typo in BlockMushroom ea14b7d90 SPIGOT-7576, PR-1347: Add methods in MushroomCow to change stew effects 4c687f243 PR-1259: Add Server#isLoggingIPs to get log-ips configuration 22a541a29 Improve support for per-world game rules cb7dccce2 PR-1348: Add Player methods for client-side potion effects b8d6109f0 PR-1335: Add API for in-world structures 4398a1b5b SPIGOT-7577: Make CraftWindCharge#explode discard the entity e74107678 Fix Crafter maximum stack size 0bb0f4f6a SPIGOT-7530, PR-1314: Improve Resource Pack API with new 1.20.3 functionality 4949f556d SPIGOT-3071, PR-1345: Add entity spawn method with spawn reason 20ac73ca2 PR-1353: Fix Structure#place not working as documented with 0 palette 3c1b77871 SPIGOT-6911, PR-1349: Change max book length in CraftMetaBook 333701839 SPIGOT-7572: Bee nests generated without bees f48f4174c SPIGOT-5553, PR-1336: Add EntityKnockbackEvent
220 Zeilen
12 KiB
Diff
220 Zeilen
12 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: dfsek <dfsek@protonmail.com>
|
|
Date: Wed, 16 Sep 2020 01:12:29 -0700
|
|
Subject: [PATCH] Add StructuresLocateEvent
|
|
|
|
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
|
|
|
diff --git a/src/main/java/io/papermc/paper/world/structure/PaperConfiguredStructure.java b/src/main/java/io/papermc/paper/world/structure/PaperConfiguredStructure.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..2667067fd13f61e0464ba88ae4e4a7078351d1a8
|
|
--- /dev/null
|
|
+++ b/src/main/java/io/papermc/paper/world/structure/PaperConfiguredStructure.java
|
|
@@ -0,0 +1,35 @@
|
|
+package io.papermc.paper.world.structure;
|
|
+
|
|
+import java.util.Objects;
|
|
+import net.minecraft.core.Registry;
|
|
+import net.minecraft.core.registries.BuiltInRegistries;
|
|
+import net.minecraft.resources.ResourceLocation;
|
|
+import net.minecraft.world.level.levelgen.structure.Structure;
|
|
+import org.bukkit.NamespacedKey;
|
|
+import org.bukkit.StructureType;
|
|
+import org.bukkit.craftbukkit.CraftRegistry;
|
|
+import org.checkerframework.checker.nullness.qual.NonNull;
|
|
+import org.checkerframework.checker.nullness.qual.Nullable;
|
|
+import org.checkerframework.framework.qual.DefaultQualifier;
|
|
+
|
|
+@DefaultQualifier(NonNull.class)
|
|
+@Deprecated(forRemoval = true)
|
|
+public final class PaperConfiguredStructure {
|
|
+
|
|
+ private PaperConfiguredStructure() {
|
|
+ }
|
|
+
|
|
+ @Deprecated(forRemoval = true)
|
|
+ public static final class LegacyRegistry extends CraftRegistry<ConfiguredStructure, Structure> {
|
|
+
|
|
+ public LegacyRegistry(final Registry<Structure> minecraftRegistry) {
|
|
+ super(ConfiguredStructure.class, minecraftRegistry, LegacyRegistry::minecraftToBukkit);
|
|
+ }
|
|
+
|
|
+ private static @Nullable ConfiguredStructure minecraftToBukkit(NamespacedKey key, Structure nms) {
|
|
+ final ResourceLocation structureTypeLoc = Objects.requireNonNull(BuiltInRegistries.STRUCTURE_TYPE.getKey(nms.type()), "unexpected structure type " + nms.type());
|
|
+ final @Nullable StructureType structureType = StructureType.getStructureTypes().get(structureTypeLoc.getPath());
|
|
+ return structureType == null ? null : new ConfiguredStructure(key, structureType);
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
|
index 3e57142dd9cb23d43857d5a4cb30962e4b696b74..a6d5b3fa7e3437e0aec54eec4079e9f3267c64b8 100644
|
|
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
|
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
|
@@ -121,6 +121,24 @@ public abstract class ChunkGenerator {
|
|
|
|
@Nullable
|
|
public Pair<BlockPos, Holder<Structure>> findNearestMapStructure(ServerLevel world, HolderSet<Structure> structures, BlockPos center, int radius, boolean skipReferencedStructures) {
|
|
+ // Paper start - StructuresLocateEvent
|
|
+ final org.bukkit.World bukkitWorld = world.getWorld();
|
|
+ final org.bukkit.Location origin = io.papermc.paper.util.MCUtil.toLocation(world, center);
|
|
+ final List<org.bukkit.generator.structure.Structure> apiStructures = structures.stream().map(Holder::value).map(nms -> org.bukkit.craftbukkit.generator.structure.CraftStructure.minecraftToBukkit(nms)).toList();
|
|
+ if (!apiStructures.isEmpty()) {
|
|
+ final io.papermc.paper.event.world.StructuresLocateEvent event = new io.papermc.paper.event.world.StructuresLocateEvent(bukkitWorld, origin, apiStructures, radius, skipReferencedStructures);
|
|
+ if (!event.callEvent()) {
|
|
+ return null;
|
|
+ }
|
|
+ if (event.getResult() != null) {
|
|
+ return Pair.of(io.papermc.paper.util.MCUtil.toBlockPos(event.getResult().pos()), world.registryAccess().registryOrThrow(Registries.STRUCTURE).wrapAsHolder(org.bukkit.craftbukkit.generator.structure.CraftStructure.bukkitToMinecraft(event.getResult().structure())));
|
|
+ }
|
|
+ center = io.papermc.paper.util.MCUtil.toBlockPosition(event.getOrigin());
|
|
+ radius = event.getRadius();
|
|
+ skipReferencedStructures = event.shouldFindUnexplored();
|
|
+ structures = HolderSet.direct(api -> world.registryAccess().registryOrThrow(Registries.STRUCTURE).wrapAsHolder(org.bukkit.craftbukkit.generator.structure.CraftStructure.bukkitToMinecraft(api)), event.getStructures());
|
|
+ }
|
|
+ // Paper end
|
|
ChunkGeneratorStructureState chunkgeneratorstructurestate = world.getChunkSource().getGeneratorState();
|
|
Map<StructurePlacement, Set<Holder<Structure>>> map = new Object2ObjectArrayMap();
|
|
Iterator iterator = structures.iterator();
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
|
|
index 110987de809339b4ce14eaf377782ebf3460164a..b12b99253543445475b73a1d3d7c6364856b49e8 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java
|
|
@@ -120,6 +120,11 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
|
|
return new CraftRegistry<>(DamageType.class, registryHolder.registryOrThrow(Registries.DAMAGE_TYPE), CraftDamageType::new);
|
|
}
|
|
// TODO registry modification API
|
|
+ // Paper start - remove this after a while along with all ConfiguredStructure stuff
|
|
+ if (bukkitClass == io.papermc.paper.world.structure.ConfiguredStructure.class) {
|
|
+ return new io.papermc.paper.world.structure.PaperConfiguredStructure.LegacyRegistry(registryHolder.registryOrThrow(Registries.STRUCTURE));
|
|
+ }
|
|
+ // Paper end
|
|
|
|
return null;
|
|
}
|
|
diff --git a/src/test/java/io/papermc/paper/world/structure/ConfiguredStructureTest.java b/src/test/java/io/papermc/paper/world/structure/ConfiguredStructureTest.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..9178fe0d01b998ca1442bf2511f8fc00db9388ba
|
|
--- /dev/null
|
|
+++ b/src/test/java/io/papermc/paper/world/structure/ConfiguredStructureTest.java
|
|
@@ -0,0 +1,96 @@
|
|
+package io.papermc.paper.world.structure;
|
|
+
|
|
+import io.papermc.paper.registry.Reference;
|
|
+import net.minecraft.core.Registry;
|
|
+import net.minecraft.core.registries.Registries;
|
|
+import net.minecraft.resources.ResourceKey;
|
|
+import net.minecraft.resources.ResourceLocation;
|
|
+import net.minecraft.server.Bootstrap;
|
|
+import net.minecraft.world.level.levelgen.structure.Structure;
|
|
+import net.minecraft.world.level.levelgen.structure.BuiltinStructures;
|
|
+import org.bukkit.NamespacedKey;
|
|
+import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
|
+import org.bukkit.support.AbstractTestingBase;
|
|
+import org.junit.jupiter.api.AfterAll;
|
|
+import org.junit.jupiter.api.BeforeAll;
|
|
+import org.junit.jupiter.api.Test;
|
|
+
|
|
+import java.io.PrintStream;
|
|
+import java.lang.reflect.Field;
|
|
+import java.lang.reflect.Modifier;
|
|
+import java.util.LinkedHashMap;
|
|
+import java.util.Map;
|
|
+import java.util.StringJoiner;
|
|
+
|
|
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
+import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|
+import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
+
|
|
+@Deprecated(forRemoval = true)
|
|
+public class ConfiguredStructureTest extends AbstractTestingBase {
|
|
+
|
|
+ private static final Map<ResourceLocation, String> BUILT_IN_STRUCTURES = new LinkedHashMap<>();
|
|
+ private static final Map<NamespacedKey, Reference<?>> DEFAULT_CONFIGURED_STRUCTURES = new LinkedHashMap<>();
|
|
+
|
|
+ private static PrintStream out;
|
|
+
|
|
+ @BeforeAll
|
|
+ public static void collectStructures() throws ReflectiveOperationException {
|
|
+ out = System.out;
|
|
+ System.setOut(Bootstrap.STDOUT);
|
|
+ for (Field field : BuiltinStructures.class.getDeclaredFields()) {
|
|
+ if (field.getType().equals(ResourceKey.class) && Modifier.isStatic(field.getModifiers())) {
|
|
+ BUILT_IN_STRUCTURES.put(((ResourceKey<?>) field.get(null)).location(), field.getName());
|
|
+ }
|
|
+ }
|
|
+ for (Field field : ConfiguredStructure.class.getDeclaredFields()) {
|
|
+ if (field.getType().equals(Reference.class) && Modifier.isStatic(field.getModifiers())) {
|
|
+ final Reference<?> ref = (Reference<?>) field.get(null);
|
|
+ DEFAULT_CONFIGURED_STRUCTURES.put(ref.getKey(), ref);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void testMinecraftToApi() {
|
|
+ Registry<Structure> structureRegistry = AbstractTestingBase.REGISTRY_CUSTOM.registryOrThrow(Registries.STRUCTURE);
|
|
+ assertEquals(BUILT_IN_STRUCTURES.size(), structureRegistry.size(), "configured structure maps should be the same size");
|
|
+
|
|
+ Map<ResourceLocation, Structure> missing = new LinkedHashMap<>();
|
|
+ for (Structure feature : structureRegistry) {
|
|
+ final ResourceLocation key = structureRegistry.getKey(feature);
|
|
+ assertNotNull(key, "Missing built-in registry key");
|
|
+ if (key.equals(BuiltinStructures.ANCIENT_CITY.location()) || key.equals(BuiltinStructures.TRAIL_RUINS.location()) || key.equals(BuiltinStructures.TRIAL_CHAMBERS.location())) {
|
|
+ continue; // TODO remove when upstream adds "jigsaw" StructureType
|
|
+ }
|
|
+ if (DEFAULT_CONFIGURED_STRUCTURES.get(CraftNamespacedKey.fromMinecraft(key)) == null) {
|
|
+ missing.put(key, feature);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ assertTrue(missing.isEmpty(), printMissing(missing));
|
|
+ }
|
|
+
|
|
+ @Test
|
|
+ public void testApiToMinecraft() {
|
|
+ Registry<Structure> structureRegistry = AbstractTestingBase.REGISTRY_CUSTOM.registryOrThrow(Registries.STRUCTURE);
|
|
+ for (NamespacedKey apiKey : DEFAULT_CONFIGURED_STRUCTURES.keySet()) {
|
|
+ assertTrue(structureRegistry.containsKey(CraftNamespacedKey.toMinecraft(apiKey)), apiKey + " does not have a minecraft counterpart");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static String printMissing(Map<ResourceLocation, Structure> missing) {
|
|
+ final StringJoiner joiner = new StringJoiner("\n", "Missing: \n", "");
|
|
+
|
|
+ missing.forEach((key, configuredFeature) -> {
|
|
+ joiner.add("public static final Reference<ConfiguredStructure> " + BUILT_IN_STRUCTURES.get(key) + " = create(\"" + key.getPath() + "\");");
|
|
+ });
|
|
+
|
|
+ return joiner.toString();
|
|
+ }
|
|
+
|
|
+ @AfterAll
|
|
+ public static void after() {
|
|
+ System.setOut(out);
|
|
+ }
|
|
+}
|
|
diff --git a/src/test/java/org/bukkit/registry/PerRegistryTest.java b/src/test/java/org/bukkit/registry/PerRegistryTest.java
|
|
index 4e4ea083063daf22f1bb785ef212958ea889c43b..1c4966520b6401e6571aa44d5934dfa280bc80e3 100644
|
|
--- a/src/test/java/org/bukkit/registry/PerRegistryTest.java
|
|
+++ b/src/test/java/org/bukkit/registry/PerRegistryTest.java
|
|
@@ -36,6 +36,7 @@ public class PerRegistryTest extends AbstractTestingBase {
|
|
if (!(object instanceof CraftRegistry<?, ?> registry)) {
|
|
continue;
|
|
}
|
|
+ if (object instanceof io.papermc.paper.world.structure.PaperConfiguredStructure.LegacyRegistry) continue; // Paper - skip
|
|
|
|
data.add(Arguments.of(registry));
|
|
} catch (ReflectiveOperationException e) {
|
|
diff --git a/src/test/java/org/bukkit/registry/RegistryArgumentAddedTest.java b/src/test/java/org/bukkit/registry/RegistryArgumentAddedTest.java
|
|
index 4adaafafb7140e983a4e90f0ff0deaaf0887a9a5..65cc33c45553e755371ec4313dd38bb61eb7d61c 100644
|
|
--- a/src/test/java/org/bukkit/registry/RegistryArgumentAddedTest.java
|
|
+++ b/src/test/java/org/bukkit/registry/RegistryArgumentAddedTest.java
|
|
@@ -23,6 +23,7 @@ public class RegistryArgumentAddedTest extends AbstractTestingBase {
|
|
|
|
Set<Class<?>> loadedRegistries = new HashSet<>(DummyServer.registers.keySet());
|
|
Set<Class<?>> notFound = new HashSet<>();
|
|
+ loadedRegistries.remove(io.papermc.paper.world.structure.ConfiguredStructure.class); // Paper - ignore
|
|
|
|
RegistriesArgumentProvider
|
|
.getData()
|