Skip to content

Commit 1049877

Browse files
committed
feature(version): Add support for 1.21.4
Took 39 minutes
1 parent fcd6fb0 commit 1049877

34 files changed

Lines changed: 2642 additions & 1 deletion

api/src/main/java/de/derfrzocker/feature/api/Setting.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
import org.jetbrains.annotations.NotNull;
44

55
public record Setting(@NotNull String name, @NotNull Class<?> valueType) {
6+
67
}

impl/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<module>v1_20_R4</module>
2323
<module>v1_21_R1</module>
2424
<module>v1_21_R2</module>
25+
<module>v1_21_R3</module>
2526
</modules>
2627

2728
<artifactId>ore-control-impl</artifactId>

impl/v1_21_R3/pom.xml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xmlns="http://maven.apache.org/POM/4.0.0"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<artifactId>ore-control-impl</artifactId>
9+
<groupId>de.derfrzocker</groupId>
10+
<version>${revision}</version>
11+
</parent>
12+
13+
<artifactId>ore-control-impl-v1_21_R3</artifactId>
14+
15+
<dependencies>
16+
<dependency>
17+
<groupId>de.derfrzocker</groupId>
18+
<artifactId>ore-control-api</artifactId>
19+
<version>${project.version}</version>
20+
<scope>provided</scope>
21+
</dependency>
22+
<dependency>
23+
<groupId>de.derfrzocker</groupId>
24+
<artifactId>ore-control-common</artifactId>
25+
<version>${project.version}</version>
26+
<scope>provided</scope>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.spigotmc</groupId>
30+
<artifactId>spigot</artifactId>
31+
<version>1.21.4-R0.1-SNAPSHOT</version>
32+
<classifier>remapped-mojang</classifier>
33+
<scope>provided</scope>
34+
<optional>true</optional>
35+
</dependency>
36+
</dependencies>
37+
38+
<build>
39+
<plugins>
40+
<plugin>
41+
<groupId>net.md-5</groupId>
42+
<artifactId>specialsource-maven-plugin</artifactId>
43+
<version>2.0.3</version>
44+
<executions>
45+
<execution>
46+
<phase>package</phase>
47+
<goals>
48+
<goal>remap</goal>
49+
</goals>
50+
<id>remap-obf</id>
51+
<configuration>
52+
<srgIn>org.spigotmc:minecraft-server:1.21.4-R0.1-SNAPSHOT:txt:maps-mojang</srgIn>
53+
<reverse>true</reverse>
54+
<remappedDependencies>org.spigotmc:spigot:1.21.4-R0.1-SNAPSHOT:jar:remapped-mojang
55+
</remappedDependencies>
56+
<remappedArtifactAttached>true</remappedArtifactAttached>
57+
<remappedClassifierName>remapped-obf</remappedClassifierName>
58+
</configuration>
59+
</execution>
60+
<execution>
61+
<phase>package</phase>
62+
<goals>
63+
<goal>remap</goal>
64+
</goals>
65+
<id>remap-spigot</id>
66+
<configuration>
67+
<inputFile>
68+
${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar
69+
</inputFile>
70+
<srgIn>org.spigotmc:minecraft-server:1.21.4-R0.1-SNAPSHOT:csrg:maps-spigot</srgIn>
71+
<remappedDependencies>org.spigotmc:spigot:1.21.4-R0.1-SNAPSHOT:jar:remapped-obf
72+
</remappedDependencies>
73+
</configuration>
74+
</execution>
75+
</executions>
76+
</plugin>
77+
</plugins>
78+
</build>
79+
80+
</project>
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package de.derfrzocker.feature.impl.v1_21_R3.extra;
2+
3+
import de.derfrzocker.feature.api.ExtraValues;
4+
import de.derfrzocker.ore.control.api.OreControlManager;
5+
import de.derfrzocker.ore.control.api.config.ConfigInfo;
6+
import de.derfrzocker.ore.control.api.config.ConfigManager;
7+
import de.derfrzocker.ore.control.impl.v1_21_R3.NMSReflectionNames;
8+
import java.lang.reflect.Field;
9+
import java.util.HashSet;
10+
import java.util.Optional;
11+
import java.util.Set;
12+
import net.minecraft.core.Holder;
13+
import net.minecraft.server.level.ChunkMap;
14+
import net.minecraft.world.level.chunk.status.WorldGenContext;
15+
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
16+
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
17+
import org.bukkit.World;
18+
import org.bukkit.craftbukkit.v1_21_R3.CraftWorld;
19+
import org.bukkit.event.EventHandler;
20+
import org.bukkit.event.EventPriority;
21+
import org.bukkit.event.Listener;
22+
import org.bukkit.event.world.WorldInitEvent;
23+
import org.bukkit.event.world.WorldUnloadEvent;
24+
25+
public class OreVeinHandler implements Listener {
26+
27+
private final static Field WORLD_GEN_CONTEXT_FIELD;
28+
private final static Field NOISE_GENERATOR_SETTINGS_FIELD;
29+
30+
static {
31+
try {
32+
WORLD_GEN_CONTEXT_FIELD = ChunkMap.class.getDeclaredField(NMSReflectionNames.CHUNK_MAP_WORLD_GEN_CONTEXT);
33+
WORLD_GEN_CONTEXT_FIELD.setAccessible(true);
34+
NOISE_GENERATOR_SETTINGS_FIELD = NoiseBasedChunkGenerator.class.getDeclaredField(NMSReflectionNames.NOISE_GENERATOR_SETTINGS);
35+
NOISE_GENERATOR_SETTINGS_FIELD.setAccessible(true);
36+
} catch (NoSuchFieldException e) {
37+
throw new RuntimeException(e);
38+
}
39+
}
40+
41+
private final Set<World> hookedWorlds = new HashSet<>();
42+
private final ConfigManager configManager;
43+
44+
public OreVeinHandler(OreControlManager oreControlManager) {
45+
this.configManager = oreControlManager.getConfigManager();
46+
oreControlManager.addValueChangeListener(this::update);
47+
}
48+
49+
@EventHandler(priority = EventPriority.LOW)
50+
public void onWorldInit(WorldInitEvent event) {
51+
if (!(((CraftWorld) event.getWorld()).getHandle().getChunkSource().getGenerator() instanceof NoiseBasedChunkGenerator noiseChunkGenerator)) {
52+
return;
53+
}
54+
55+
NoiseGeneratorSettings newSettings = getNewValue(event.getWorld(), noiseChunkGenerator.settings.value());
56+
NoiseBasedChunkGenerator newGenerator = new NoiseBasedChunkGenerator(noiseChunkGenerator.getBiomeSource(), Holder.direct(newSettings));
57+
58+
try {
59+
WorldGenContext worldGenContext = (WorldGenContext) WORLD_GEN_CONTEXT_FIELD.get(((CraftWorld) event.getWorld()).getHandle().getChunkSource().chunkMap);
60+
WORLD_GEN_CONTEXT_FIELD.set(((CraftWorld) event.getWorld()).getHandle().getChunkSource().chunkMap, new WorldGenContext(worldGenContext.level(), newGenerator, worldGenContext.structureManager(), worldGenContext.lightEngine(), worldGenContext.mainThreadExecutor(), worldGenContext.unsavedListener()));
61+
} catch (IllegalAccessException e) {
62+
throw new RuntimeException(e);
63+
}
64+
65+
hookedWorlds.add(event.getWorld());
66+
}
67+
68+
@EventHandler
69+
public void onWorldUnload(WorldUnloadEvent event) {
70+
// Cleanup
71+
hookedWorlds.remove(event.getWorld());
72+
}
73+
74+
private NoiseGeneratorSettings getNewValue(World world, NoiseGeneratorSettings old) {
75+
ConfigInfo configInfo = configManager.getOrCreateConfigInfo(world.getName());
76+
Optional<ExtraValues> optionalExtraValues = configManager.getGenerationExtraValues(configInfo);
77+
78+
boolean newValue = optionalExtraValues.flatMap(ExtraValues::shouldGeneratedBigOreVeins).orElse(old.oreVeinsEnabled());
79+
80+
return new NoiseGeneratorSettings(old.noiseSettings(), old.defaultBlock(), old.defaultFluid(),
81+
old.noiseRouter(), old.surfaceRule(), old.spawnTarget(), old.seaLevel(), old.disableMobGeneration(), old.aquifersEnabled(), newValue, old.useLegacyRandomSource());
82+
}
83+
84+
private void update() {
85+
for (World world : hookedWorlds) {
86+
if (!(((CraftWorld) world).getHandle().getChunkSource().getGenerator() instanceof NoiseBasedChunkGenerator noiseChunkGenerator)) {
87+
return;
88+
}
89+
90+
NoiseGeneratorSettings newSettings = getNewValue(world, noiseChunkGenerator.settings.value());
91+
92+
try {
93+
NOISE_GENERATOR_SETTINGS_FIELD.set(noiseChunkGenerator, Holder.direct(newSettings));
94+
} catch (IllegalAccessException e) {
95+
throw new RuntimeException(e);
96+
}
97+
}
98+
}
99+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package de.derfrzocker.feature.impl.v1_21_R3.feature.generator;
2+
3+
import com.google.gson.JsonElement;
4+
import com.google.gson.JsonObject;
5+
import de.derfrzocker.feature.api.Configuration;
6+
import de.derfrzocker.feature.api.Registries;
7+
import de.derfrzocker.feature.api.Setting;
8+
import de.derfrzocker.feature.api.util.Parser;
9+
import de.derfrzocker.feature.common.feature.generator.configuration.EmptyFeatureConfiguration;
10+
import java.util.Collections;
11+
import java.util.Random;
12+
import java.util.Set;
13+
import net.minecraft.world.level.levelgen.feature.Feature;
14+
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
15+
import org.bukkit.generator.LimitedRegion;
16+
import org.bukkit.generator.WorldInfo;
17+
import org.bukkit.util.BlockVector;
18+
import org.jetbrains.annotations.NotNull;
19+
20+
public class EmptyConfigurationGenerator extends MinecraftFeatureGenerator<NoneFeatureConfiguration, EmptyFeatureConfiguration> {
21+
22+
private EmptyConfigurationGenerator(Registries registries, Feature<NoneFeatureConfiguration> feature, String name) {
23+
super(registries, feature, name);
24+
}
25+
26+
public static EmptyConfigurationGenerator createGlowstoneBlob(Registries registries) {
27+
return new EmptyConfigurationGenerator(registries, Feature.GLOWSTONE_BLOB, "glowstone_blob");
28+
}
29+
30+
@Override
31+
public @NotNull Set<Setting> getSettings() {
32+
return Collections.emptySet();
33+
}
34+
35+
@Override
36+
public @NotNull Configuration createEmptyConfiguration() {
37+
return new EmptyFeatureConfiguration(this);
38+
}
39+
40+
@Override
41+
public EmptyFeatureConfiguration mergeConfig(EmptyFeatureConfiguration first, EmptyFeatureConfiguration second) {
42+
return first;
43+
}
44+
45+
@Override
46+
public Parser<EmptyFeatureConfiguration> createParser(Registries registries) {
47+
return new Parser<>() {
48+
@Override
49+
public JsonElement toJson(EmptyFeatureConfiguration value) {
50+
return new JsonObject();
51+
}
52+
53+
@Override
54+
public EmptyFeatureConfiguration fromJson(JsonElement jsonElement) {
55+
return new EmptyFeatureConfiguration(EmptyConfigurationGenerator.this);
56+
}
57+
};
58+
}
59+
60+
@Override
61+
public NoneFeatureConfiguration createConfiguration(@NotNull WorldInfo worldInfo, @NotNull Random random, @NotNull BlockVector position, @NotNull LimitedRegion limitedRegion, @NotNull EmptyFeatureConfiguration configuration) {
62+
return NoneFeatureConfiguration.INSTANCE;
63+
}
64+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package de.derfrzocker.feature.impl.v1_21_R3.feature.generator;
2+
3+
import de.derfrzocker.feature.api.FeatureGenerator;
4+
import de.derfrzocker.feature.api.FeatureGeneratorConfiguration;
5+
import de.derfrzocker.feature.api.Registries;
6+
import de.derfrzocker.feature.api.util.Parser;
7+
import java.util.Optional;
8+
import java.util.Random;
9+
import net.minecraft.core.BlockPos;
10+
import net.minecraft.world.level.WorldGenLevel;
11+
import net.minecraft.world.level.levelgen.feature.Feature;
12+
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
13+
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
14+
import org.bukkit.NamespacedKey;
15+
import org.bukkit.craftbukkit.v1_21_R3.generator.CraftLimitedRegion;
16+
import org.bukkit.craftbukkit.v1_21_R3.util.RandomSourceWrapper;
17+
import org.bukkit.generator.LimitedRegion;
18+
import org.bukkit.generator.WorldInfo;
19+
import org.bukkit.util.BlockVector;
20+
import org.jetbrains.annotations.NotNull;
21+
22+
public abstract class MinecraftFeatureGenerator<M extends FeatureConfiguration, C extends FeatureGeneratorConfiguration> implements FeatureGenerator<C> {
23+
24+
private final Parser<FeatureGeneratorConfiguration> parser;
25+
private final Feature<M> feature;
26+
private final NamespacedKey namespacedKey;
27+
28+
public MinecraftFeatureGenerator(Registries registries, Feature<M> feature, String name) {
29+
this.parser = (Parser<FeatureGeneratorConfiguration>) createParser(registries);
30+
this.feature = feature;
31+
this.namespacedKey = NamespacedKey.minecraft(name);
32+
}
33+
34+
public abstract C mergeConfig(C first, C second);
35+
36+
public abstract Parser<C> createParser(Registries registries);
37+
38+
public abstract M createConfiguration(@NotNull WorldInfo worldInfo, @NotNull Random random, @NotNull BlockVector position, @NotNull LimitedRegion limitedRegion, @NotNull C configuration);
39+
40+
@NotNull
41+
@Override
42+
public C merge(@NotNull FeatureGeneratorConfiguration first, @NotNull FeatureGeneratorConfiguration second) {
43+
return mergeConfig((C) first, (C) second);
44+
}
45+
46+
@Override
47+
public void place(@NotNull WorldInfo worldInfo, @NotNull Random random, @NotNull BlockVector position, @NotNull LimitedRegion limitedRegion, @NotNull C configuration) {
48+
WorldGenLevel level = ((CraftLimitedRegion) limitedRegion).getHandle();
49+
M config = createConfiguration(worldInfo, random, position, limitedRegion, configuration);
50+
feature.place(new FeaturePlaceContext<>(Optional.empty(), level, level.getMinecraftWorld().getChunkSource().getGenerator(), new RandomSourceWrapper(random), new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()), config));
51+
}
52+
53+
@NotNull
54+
@Override
55+
public Parser<FeatureGeneratorConfiguration> getParser() {
56+
return parser;
57+
}
58+
59+
@NotNull
60+
@Override
61+
public NamespacedKey getKey() {
62+
return namespacedKey;
63+
}
64+
}

0 commit comments

Comments
 (0)